From 229f1e0ce08a67c456bc48883c4c1632262ff39b Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Thu, 14 Aug 2025 08:13:35 +0100 Subject: [PATCH 01/33] Fixed behaviour on database cache rebuild to update only for requested content types (#19905) Fixed behaviour on database cache rebuild to update only for requested content types. (cherry picked from commit b8b61cd326048380b762f4104c6178e4fcdde4f2) --- .../DatabaseCacheRebuilder.cs | 2 +- .../Persistence/DatabaseCacheRepository.cs | 42 ++++++++++++------- .../Services/MediaCacheService.cs | 2 +- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/Umbraco.PublishedCache.HybridCache/DatabaseCacheRebuilder.cs b/src/Umbraco.PublishedCache.HybridCache/DatabaseCacheRebuilder.cs index b61daf7f7c..5b1512ef50 100644 --- a/src/Umbraco.PublishedCache.HybridCache/DatabaseCacheRebuilder.cs +++ b/src/Umbraco.PublishedCache.HybridCache/DatabaseCacheRebuilder.cs @@ -120,7 +120,7 @@ internal sealed class DatabaseCacheRebuilder : IDatabaseCacheRebuilder private Task PerformRebuild() { using ICoreScope scope = _coreScopeProvider.CreateCoreScope(); - _databaseCacheRepository.Rebuild(); + _databaseCacheRepository.Rebuild([], [], []); // If the serializer type has changed, we also need to update it in the key value store. var currentSerializerValue = _keyValueService.GetValue(NuCacheSerializerKey); diff --git a/src/Umbraco.PublishedCache.HybridCache/Persistence/DatabaseCacheRepository.cs b/src/Umbraco.PublishedCache.HybridCache/Persistence/DatabaseCacheRepository.cs index b72af50a59..6e1df8b5d0 100644 --- a/src/Umbraco.PublishedCache.HybridCache/Persistence/DatabaseCacheRepository.cs +++ b/src/Umbraco.PublishedCache.HybridCache/Persistence/DatabaseCacheRepository.cs @@ -101,10 +101,11 @@ internal sealed class DatabaseCacheRepository : RepositoryBase, IDatabaseCacheRe | ContentCacheDataSerializerEntityType.Media | ContentCacheDataSerializerEntityType.Member); - // If contentTypeIds, mediaTypeIds and memberTypeIds are null, truncate table as all records will be deleted (as these 3 are the only types in the table). - if (contentTypeIds != null && !contentTypeIds.Any() - && mediaTypeIds != null && !mediaTypeIds.Any() - && memberTypeIds != null && !memberTypeIds.Any()) + // If contentTypeIds, mediaTypeIds and memberTypeIds are all non-null but empty, + // truncate the table as all records will be deleted (as these 3 are the only types in the table). + if (contentTypeIds is not null && contentTypeIds.Count == 0 && + mediaTypeIds is not null && mediaTypeIds.Count == 0 && + memberTypeIds is not null && memberTypeIds.Count == 0) { if (Database.DatabaseType == DatabaseType.SqlServer2012) { @@ -280,10 +281,15 @@ internal sealed class DatabaseCacheRepository : RepositoryBase, IDatabaseCacheRe // assumes content tree lock private void RebuildContentDbCache(IContentCacheDataSerializer serializer, int groupSize, IReadOnlyCollection? contentTypeIds) { + if (contentTypeIds is null) + { + return; + } + Guid contentObjectType = Constants.ObjectTypes.Document; // remove all - if anything fails the transaction will rollback - if (contentTypeIds == null || contentTypeIds.Count == 0) + if (contentTypeIds.Count == 0) { // must support SQL-CE Database.Execute( @@ -310,7 +316,7 @@ WHERE cmsContentNu.nodeId IN ( // insert back - if anything fails the transaction will rollback IQuery query = SqlContext.Query(); - if (contentTypeIds != null && contentTypeIds.Count > 0) + if (contentTypeIds.Count > 0) { query = query.WhereIn(x => x.ContentTypeId, contentTypeIds); // assume number of ctypes won't blow IN(...) } @@ -345,13 +351,17 @@ WHERE cmsContentNu.nodeId IN ( } // assumes media tree lock - private void RebuildMediaDbCache(IContentCacheDataSerializer serializer, int groupSize, - IReadOnlyCollection? contentTypeIds) + private void RebuildMediaDbCache(IContentCacheDataSerializer serializer, int groupSize, IReadOnlyCollection? contentTypeIds) { + if (contentTypeIds is null) + { + return; + } + Guid mediaObjectType = Constants.ObjectTypes.Media; // remove all - if anything fails the transaction will rollback - if (contentTypeIds is null || contentTypeIds.Count == 0) + if (contentTypeIds.Count == 0) { // must support SQL-CE Database.Execute( @@ -378,7 +388,7 @@ WHERE cmsContentNu.nodeId IN ( // insert back - if anything fails the transaction will rollback IQuery query = SqlContext.Query(); - if (contentTypeIds is not null && contentTypeIds.Count > 0) + if (contentTypeIds.Count > 0) { query = query.WhereIn(x => x.ContentTypeId, contentTypeIds); // assume number of ctypes won't blow IN(...) } @@ -398,13 +408,17 @@ WHERE cmsContentNu.nodeId IN ( } // assumes member tree lock - private void RebuildMemberDbCache(IContentCacheDataSerializer serializer, int groupSize, - IReadOnlyCollection? contentTypeIds) + private void RebuildMemberDbCache(IContentCacheDataSerializer serializer, int groupSize, IReadOnlyCollection? contentTypeIds) { + if (contentTypeIds is null) + { + return; + } + Guid memberObjectType = Constants.ObjectTypes.Member; // remove all - if anything fails the transaction will rollback - if (contentTypeIds == null || contentTypeIds.Count == 0) + if (contentTypeIds.Count == 0) { // must support SQL-CE Database.Execute( @@ -431,7 +445,7 @@ WHERE cmsContentNu.nodeId IN ( // insert back - if anything fails the transaction will rollback IQuery query = SqlContext.Query(); - if (contentTypeIds != null && contentTypeIds.Count > 0) + if (contentTypeIds.Count > 0) { query = query.WhereIn(x => x.ContentTypeId, contentTypeIds); // assume number of ctypes won't blow IN(...) } diff --git a/src/Umbraco.PublishedCache.HybridCache/Services/MediaCacheService.cs b/src/Umbraco.PublishedCache.HybridCache/Services/MediaCacheService.cs index 0a8283279a..29095b1d04 100644 --- a/src/Umbraco.PublishedCache.HybridCache/Services/MediaCacheService.cs +++ b/src/Umbraco.PublishedCache.HybridCache/Services/MediaCacheService.cs @@ -258,7 +258,7 @@ internal sealed class MediaCacheService : IMediaCacheService public void Rebuild(IReadOnlyCollection contentTypeIds) { using ICoreScope scope = _scopeProvider.CreateCoreScope(); - _databaseCacheRepository.Rebuild(contentTypeIds.ToList()); + _databaseCacheRepository.Rebuild(mediaTypeIds: contentTypeIds.ToList()); IEnumerable mediaTypeKeys = contentTypeIds.Select(x => _idKeyMap.GetKeyForId(x, UmbracoObjectTypes.MediaType)) .Where(x => x.Success) From c436c4288b5d4dbcfa308272176c03bdeb2bb2c7 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 Aug 2025 09:42:01 +0200 Subject: [PATCH 02/33] Fix TipTap word count extension state sharing between multiple editors (#19943) * Initial plan * Fix TipTap word count extension state sharing by using configure() Co-authored-by: iOvergaard <752371+iOvergaard@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: iOvergaard <752371+iOvergaard@users.noreply.github.com> --- .../packages/tiptap/extensions/core/word-count.tiptap-api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/core/word-count.tiptap-api.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/core/word-count.tiptap-api.ts index 6ff0bbcde8..1a2bb5cce5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/core/word-count.tiptap-api.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/core/word-count.tiptap-api.ts @@ -3,7 +3,7 @@ import { css } from '@umbraco-cms/backoffice/external/lit'; import { CharacterCount } from '@umbraco-cms/backoffice/external/tiptap'; export default class UmbTiptapWordCountExtensionApi extends UmbTiptapExtensionApiBase { - getTiptapExtensions = () => [CharacterCount]; + getTiptapExtensions = () => [CharacterCount.configure()]; override getStyles = () => css``; } From e60acfe437874cc6b768d78522167622f42276a1 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Thu, 21 Aug 2025 10:35:37 +0200 Subject: [PATCH 03/33] bump version to 16.2.0-rc2 --- src/Umbraco.Web.UI.Client/package-lock.json | 4 ++-- src/Umbraco.Web.UI.Client/package.json | 2 +- version.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 2886a3bcef..81227af986 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -1,12 +1,12 @@ { "name": "@umbraco-cms/backoffice", - "version": "16.2.0-rc", + "version": "16.2.0-rc2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@umbraco-cms/backoffice", - "version": "16.2.0-rc", + "version": "16.2.0-rc2", "license": "MIT", "workspaces": [ "./src/packages/*", diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 640d3feac8..7069cead81 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -1,7 +1,7 @@ { "name": "@umbraco-cms/backoffice", "license": "MIT", - "version": "16.2.0-rc", + "version": "16.2.0-rc2", "type": "module", "exports": { ".": null, diff --git a/version.json b/version.json index 8d380fda2b..f6a51c581a 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json", - "version": "16.2.0-rc", + "version": "16.2.0-rc2", "assemblyVersion": { "precision": "build" }, From 9cb5a12143dcdf2885a848aecd05fd1f19c712dc Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Mon, 25 Aug 2025 08:55:56 +0200 Subject: [PATCH 04/33] build(deps): bump @umbraco-ui/uui to 1.15.0 --- src/Umbraco.Web.UI.Client/package-lock.json | 966 +++++++++--------- .../src/external/uui/package.json | 4 +- 2 files changed, 485 insertions(+), 485 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 81227af986..0fe48a94d0 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -4004,909 +4004,909 @@ "link": true }, "node_modules/@umbraco-ui/uui": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.15.0-rc.0.tgz", - "integrity": "sha512-zO5uCoiXy8f6aGP6k5fCWchKT/6c/UnDlfquODG5tQioFF3pqIfInN/0JHUgMJsQQARdm5KFkSp0PWvVmXhX9A==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.15.0.tgz", + "integrity": "sha512-8yCzfKePv9zK+PMw1K3uwpnDDBZkbSCCOrt8dNDlZ1/6zf+yNLu+r/kVlMcauei6aNsCwXvcI4LhBGS1f5kJ/A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-action-bar": "1.15.0-rc.0", - "@umbraco-ui/uui-avatar": "1.15.0-rc.0", - "@umbraco-ui/uui-avatar-group": "1.15.0-rc.0", - "@umbraco-ui/uui-badge": "1.15.0-rc.0", - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-boolean-input": "1.15.0-rc.0", - "@umbraco-ui/uui-box": "1.15.0-rc.0", - "@umbraco-ui/uui-breadcrumbs": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0", - "@umbraco-ui/uui-button-copy-text": "1.15.0-rc.0", - "@umbraco-ui/uui-button-group": "1.15.0-rc.0", - "@umbraco-ui/uui-button-inline-create": "1.15.0-rc.0", - "@umbraco-ui/uui-card": "1.15.0-rc.0", - "@umbraco-ui/uui-card-block-type": "1.15.0-rc.0", - "@umbraco-ui/uui-card-content-node": "1.15.0-rc.0", - "@umbraco-ui/uui-card-media": "1.15.0-rc.0", - "@umbraco-ui/uui-card-user": "1.15.0-rc.0", - "@umbraco-ui/uui-caret": "1.15.0-rc.0", - "@umbraco-ui/uui-checkbox": "1.15.0-rc.0", - "@umbraco-ui/uui-color-area": "1.15.0-rc.0", - "@umbraco-ui/uui-color-picker": "1.15.0-rc.0", - "@umbraco-ui/uui-color-slider": "1.15.0-rc.0", - "@umbraco-ui/uui-color-swatch": "1.15.0-rc.0", - "@umbraco-ui/uui-color-swatches": "1.15.0-rc.0", - "@umbraco-ui/uui-combobox": "1.15.0-rc.0", - "@umbraco-ui/uui-combobox-list": "1.15.0-rc.0", - "@umbraco-ui/uui-css": "1.15.0-rc.0", - "@umbraco-ui/uui-dialog": "1.15.0-rc.0", - "@umbraco-ui/uui-dialog-layout": "1.15.0-rc.0", - "@umbraco-ui/uui-file-dropzone": "1.15.0-rc.0", - "@umbraco-ui/uui-file-preview": "1.15.0-rc.0", - "@umbraco-ui/uui-form": "1.15.0-rc.0", - "@umbraco-ui/uui-form-layout-item": "1.15.0-rc.0", - "@umbraco-ui/uui-form-validation-message": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0", - "@umbraco-ui/uui-input": "1.15.0-rc.0", - "@umbraco-ui/uui-input-file": "1.15.0-rc.0", - "@umbraco-ui/uui-input-lock": "1.15.0-rc.0", - "@umbraco-ui/uui-input-password": "1.15.0-rc.0", - "@umbraco-ui/uui-keyboard-shortcut": "1.15.0-rc.0", - "@umbraco-ui/uui-label": "1.15.0-rc.0", - "@umbraco-ui/uui-loader": "1.15.0-rc.0", - "@umbraco-ui/uui-loader-bar": "1.15.0-rc.0", - "@umbraco-ui/uui-loader-circle": "1.15.0-rc.0", - "@umbraco-ui/uui-menu-item": "1.15.0-rc.0", - "@umbraco-ui/uui-modal": "1.15.0-rc.0", - "@umbraco-ui/uui-pagination": "1.15.0-rc.0", - "@umbraco-ui/uui-popover": "1.15.0-rc.0", - "@umbraco-ui/uui-popover-container": "1.15.0-rc.0", - "@umbraco-ui/uui-progress-bar": "1.15.0-rc.0", - "@umbraco-ui/uui-radio": "1.15.0-rc.0", - "@umbraco-ui/uui-range-slider": "1.15.0-rc.0", - "@umbraco-ui/uui-ref": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-list": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node-data-type": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node-document-type": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node-form": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node-member": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node-package": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node-user": "1.15.0-rc.0", - "@umbraco-ui/uui-scroll-container": "1.15.0-rc.0", - "@umbraco-ui/uui-select": "1.15.0-rc.0", - "@umbraco-ui/uui-slider": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-expand": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-file": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-folder": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-lock": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-more": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-sort": "1.15.0-rc.0", - "@umbraco-ui/uui-table": "1.15.0-rc.0", - "@umbraco-ui/uui-tabs": "1.15.0-rc.0", - "@umbraco-ui/uui-tag": "1.15.0-rc.0", - "@umbraco-ui/uui-textarea": "1.15.0-rc.0", - "@umbraco-ui/uui-toast-notification": "1.15.0-rc.0", - "@umbraco-ui/uui-toast-notification-container": "1.15.0-rc.0", - "@umbraco-ui/uui-toast-notification-layout": "1.15.0-rc.0", - "@umbraco-ui/uui-toggle": "1.15.0-rc.0", - "@umbraco-ui/uui-visually-hidden": "1.15.0-rc.0" + "@umbraco-ui/uui-action-bar": "1.15.0", + "@umbraco-ui/uui-avatar": "1.15.0", + "@umbraco-ui/uui-avatar-group": "1.15.0", + "@umbraco-ui/uui-badge": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-boolean-input": "1.15.0", + "@umbraco-ui/uui-box": "1.15.0", + "@umbraco-ui/uui-breadcrumbs": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-button-copy-text": "1.15.0", + "@umbraco-ui/uui-button-group": "1.15.0", + "@umbraco-ui/uui-button-inline-create": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0", + "@umbraco-ui/uui-card-block-type": "1.15.0", + "@umbraco-ui/uui-card-content-node": "1.15.0", + "@umbraco-ui/uui-card-media": "1.15.0", + "@umbraco-ui/uui-card-user": "1.15.0", + "@umbraco-ui/uui-caret": "1.15.0", + "@umbraco-ui/uui-checkbox": "1.15.0", + "@umbraco-ui/uui-color-area": "1.15.0", + "@umbraco-ui/uui-color-picker": "1.15.0", + "@umbraco-ui/uui-color-slider": "1.15.0", + "@umbraco-ui/uui-color-swatch": "1.15.0", + "@umbraco-ui/uui-color-swatches": "1.15.0", + "@umbraco-ui/uui-combobox": "1.15.0", + "@umbraco-ui/uui-combobox-list": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0", + "@umbraco-ui/uui-dialog": "1.15.0", + "@umbraco-ui/uui-dialog-layout": "1.15.0", + "@umbraco-ui/uui-file-dropzone": "1.15.0", + "@umbraco-ui/uui-file-preview": "1.15.0", + "@umbraco-ui/uui-form": "1.15.0", + "@umbraco-ui/uui-form-layout-item": "1.15.0", + "@umbraco-ui/uui-form-validation-message": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-icon-registry": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0", + "@umbraco-ui/uui-input": "1.15.0", + "@umbraco-ui/uui-input-file": "1.15.0", + "@umbraco-ui/uui-input-lock": "1.15.0", + "@umbraco-ui/uui-input-password": "1.15.0", + "@umbraco-ui/uui-keyboard-shortcut": "1.15.0", + "@umbraco-ui/uui-label": "1.15.0", + "@umbraco-ui/uui-loader": "1.15.0", + "@umbraco-ui/uui-loader-bar": "1.15.0", + "@umbraco-ui/uui-loader-circle": "1.15.0", + "@umbraco-ui/uui-menu-item": "1.15.0", + "@umbraco-ui/uui-modal": "1.15.0", + "@umbraco-ui/uui-pagination": "1.15.0", + "@umbraco-ui/uui-popover": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", + "@umbraco-ui/uui-progress-bar": "1.15.0", + "@umbraco-ui/uui-radio": "1.15.0", + "@umbraco-ui/uui-range-slider": "1.15.0", + "@umbraco-ui/uui-ref": "1.15.0", + "@umbraco-ui/uui-ref-list": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0", + "@umbraco-ui/uui-ref-node-data-type": "1.15.0", + "@umbraco-ui/uui-ref-node-document-type": "1.15.0", + "@umbraco-ui/uui-ref-node-form": "1.15.0", + "@umbraco-ui/uui-ref-node-member": "1.15.0", + "@umbraco-ui/uui-ref-node-package": "1.15.0", + "@umbraco-ui/uui-ref-node-user": "1.15.0", + "@umbraco-ui/uui-scroll-container": "1.15.0", + "@umbraco-ui/uui-select": "1.15.0", + "@umbraco-ui/uui-slider": "1.15.0", + "@umbraco-ui/uui-symbol-expand": "1.15.0", + "@umbraco-ui/uui-symbol-file": "1.15.0", + "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0", + "@umbraco-ui/uui-symbol-folder": "1.15.0", + "@umbraco-ui/uui-symbol-lock": "1.15.0", + "@umbraco-ui/uui-symbol-more": "1.15.0", + "@umbraco-ui/uui-symbol-sort": "1.15.0", + "@umbraco-ui/uui-table": "1.15.0", + "@umbraco-ui/uui-tabs": "1.15.0", + "@umbraco-ui/uui-tag": "1.15.0", + "@umbraco-ui/uui-textarea": "1.15.0", + "@umbraco-ui/uui-toast-notification": "1.15.0", + "@umbraco-ui/uui-toast-notification-container": "1.15.0", + "@umbraco-ui/uui-toast-notification-layout": "1.15.0", + "@umbraco-ui/uui-toggle": "1.15.0", + "@umbraco-ui/uui-visually-hidden": "1.15.0" } }, "node_modules/@umbraco-ui/uui-action-bar": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.15.0-rc.0.tgz", - "integrity": "sha512-hrAIlv2MEg+BcgxLg0H1b0hsyfGjiLNRAiHXf9GUfDNb6RZs9wCEgnI88vU8pfnTIRkfVDqewm5WEBxYwucSQw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.15.0.tgz", + "integrity": "sha512-O0807+bWVWV/rsFihFVKSOkg9wBtLXKCszE5+eZk2KmONm93BFhIAE35rp7eD6X2SuJMHwYzInIxMIMjHzdpUQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button-group": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button-group": "1.15.0" } }, "node_modules/@umbraco-ui/uui-avatar": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.15.0-rc.0.tgz", - "integrity": "sha512-DbisxrMnN1Z2yV+kQduTHu3Jw6gCRQlQLt/H5GQySNek1zNqaI0M8yeU6CHZPis+DgZoP0MaFRXyRuTqOhe2iQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.15.0.tgz", + "integrity": "sha512-eEX83zwRN3tCiHScKcmkROWAfLu3TgFI9SntlbyxiuSSYfhJxWSZXOf6lVvQ/1CyvKq8XqSbBnN3VKXgcaKOpg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-avatar-group": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.15.0-rc.0.tgz", - "integrity": "sha512-tetsqYKGEv69RMRpeamAVzNQMP77Ty7NIYaRBNfhsyAoYCE2uL1DxQsqiUzv2Ve2dDmRM5GOrWD4zxhrFHhoiQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.15.0.tgz", + "integrity": "sha512-CGYAFAHgNoQK2UTupP7pO0mwP6t9/Ms6WZ0gIC40a+kPjrGtaDWU52hiPsuXrUcR6WjJwZ5WRrJHOboRpdmM0g==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-avatar": "1.15.0-rc.0", - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-avatar": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-badge": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.15.0-rc.0.tgz", - "integrity": "sha512-VFxMixI9AXu2FlHlY4djnzURNpIAYjCvgfgmZG81HRbfgtSsv/nCS/l2dC5Y0/oDku/yDkF73ZqeosQAOREyQA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.15.0.tgz", + "integrity": "sha512-9aGmhRvey98kcR7wfsnno0BNftIRwJ0r2lCH6cNK2lhe69enYm0MWjp+4uutnlEWWskTLEI344BOqmqOHH1NPA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-base": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.15.0-rc.0.tgz", - "integrity": "sha512-xj0NMdQ+dVdVvo4Y8FAFYYtVt84T/KkzVPi+jSsgt/n0pWdfFd3f13cYiUYehNcS1q+rZxXp0ECuxnoi9GTzQg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.15.0.tgz", + "integrity": "sha512-0vtKmjzUOn/tIUHNrsx7aZpy3eq9aRKqV9kkJTrhH92S4WcMy+cOB1iw9t3Fe3xlBPuL3JpszwuxMTIuIqJTgQ==", "license": "MIT", "peerDependencies": { "lit": ">=2.8.0" } }, "node_modules/@umbraco-ui/uui-boolean-input": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.15.0-rc.0.tgz", - "integrity": "sha512-BVQVhEdOz+YJQQ0iFFJqDpW8wvsa9423GcIa0x8QRj7KhDgiEcbwNM3eHblHYkmKXFYVd250/MIB7UurY5IycA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.15.0.tgz", + "integrity": "sha512-LkYX+p44mFVdvlZSliP5ClMcyHoOIVLWI3WVkaMLQdNi2LO9bbfaTneLzu4ruW6v0iF+kLsznr3bl73VHk7oEg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-box": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.15.0-rc.0.tgz", - "integrity": "sha512-u9RxTBDzbggQu6MHNFYSRU4siMLeMO4y/O6jbxRd/8mPViiT14yobY7I1d1wOYbgevoltJrtHqhDOjIWj+x0TQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.15.0.tgz", + "integrity": "sha512-MhSNcKsVNymD/yt3NFXujuaQmAqMqj5S+CBoDHEk88H7Id9NMw9RStZFJ37mI2CxHWkeHDotNVgOhSBiHJNJnw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-css": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0" } }, "node_modules/@umbraco-ui/uui-breadcrumbs": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.15.0-rc.0.tgz", - "integrity": "sha512-3hAq5GbnIbf2RfCbfW59T5uYm6nX0Zobp+VWtGb9388FhhkZuSQdn2nuN33VjmMwvVkTvGWcuqww4ii+XoSaTg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.15.0.tgz", + "integrity": "sha512-TaUY+hNB0VIwv9SBi9fDjIFRtrmmkcT7hlhLCJLUVfQ7jJlGLPISAAdypSplNeCPthYvP1cJQ9m28OzscXHZxQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.15.0-rc.0.tgz", - "integrity": "sha512-5YAmsYyQHzY8HBbfZpK7ekrLQKm90Zuq/TpcOuWGCe9h33T97CWJ+ekcNzpFWBhDXKPfcV22wSapnszzsPxI4g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.15.0.tgz", + "integrity": "sha512-3Oaqj6Yta/Q/Ndme20YA1XbHdBBL71iNhpqREfTHli2YV4TEcgIiNy0s2op2oPhKjIEQPEfitU2BrruYEEWa7Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button-copy-text": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-copy-text/-/uui-button-copy-text-1.15.0-rc.0.tgz", - "integrity": "sha512-HeV6yEZ6do7JkJfDLTZqD1Z4EHuev65KFx3JVNHSg+fDfFQgs1fcM4Hrm7wBUsOLcIknvislCs8UumypdGeIBQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-copy-text/-/uui-button-copy-text-1.15.0.tgz", + "integrity": "sha512-MAaJzpwVnlyGJNvLv6qIwrYsI5SaXXiVKgVi47I8+x//QmnArmetCN04766gGzmAb0m2uuC3ht0BXMDv05pxvw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button-group": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.15.0-rc.0.tgz", - "integrity": "sha512-C8goOUkPe6LzVJbkeIIMzEBpqt8rkqGwpLMxYnEnkFx5HW+pQK8JHEivpGiznzl3mGLglPZC/WxnTtKuNb9ZYg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.15.0.tgz", + "integrity": "sha512-YPEnubKNbKmw04eWRH24/3Uxu+zhtLPeJoaT6ykPCyjr/EKc82rSTvn8fwQuP41UokQrXOac2pKn7SncyoST1Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button-inline-create": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.15.0-rc.0.tgz", - "integrity": "sha512-4TOly3u5cWBJFBJZvtNkYNM0pnuiEz2u0kRQhrXOhutXH7jJ19yxSrAg+KntZDGalyd22a5nv7L3+P6kTiLibA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.15.0.tgz", + "integrity": "sha512-nLJZ6P5eK1rYgqjP5zCxbZp8g4WJ23RnUZQ49o7QpU/7zoPOK72/fuM3Ky00Iapixm/kAD6dYHO/P+GtNz8/CA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.15.0-rc.0.tgz", - "integrity": "sha512-A/sKTH8BxtjeEFFp1ou8v9TNBCw2jkMdXly3Ps+TmQZW/I0/bfZoRMOhHqLU+QyfF6/JH4v+IruVtcjqZJizMg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.15.0.tgz", + "integrity": "sha512-pNjpk2iIdSsmTtDdBsWaEr8JX0RcWbl8yKGaqLvo/S7d3bly5z+FjcsgGnX1i1GHo7dqmgVJfbdvN9V1jgn+FA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-checkbox": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-checkbox": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-block-type": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-block-type/-/uui-card-block-type-1.15.0-rc.0.tgz", - "integrity": "sha512-KZtZof1Tuierk9ztnoYcSqbtwFevBCYYnv4poTaoRTwoigxN1rK+aEdVZFejmHg9Jn6BxV6RIHjDI1P0+388tA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-block-type/-/uui-card-block-type-1.15.0.tgz", + "integrity": "sha512-cWag+D0XrogYZesAN8NMPQCCuU7L7uZ4Xz8dmirKQk1gjMrFDC4vYPZRQ/5O3ETTFupfDipVKimgRDsmarbLSQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-card": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-content-node": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.15.0-rc.0.tgz", - "integrity": "sha512-Bzw4gH+3f/gCVJZIV9+V7tzQrqIVUUy7Y44ZsMunwcSWUKldrKLfJvwkG2RmhrUmxlus8MYEJRHOEX2fQqJ4zQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.15.0.tgz", + "integrity": "sha512-DZ6JYNvGb5wVkhhLShENMm+Y6kTpz37YrApQTJVUUgPXhIABO2CDCnqgpH5tkQX73s9jjVB3Ca7SeivuYv8G9A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-card": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-media": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.15.0-rc.0.tgz", - "integrity": "sha512-SDrY63OyNvV3HjhAy+bNONX/cGTX+9Oe8ItlJvX/r7a8qN6j1QaoechUXCVDC4rlAwpaiyPILQ+hPs2eizevzw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.15.0.tgz", + "integrity": "sha512-EzYebWCzR0wHY902NmAcTRSVSscYac3QntCz+xwSulrhzfy4copeOd1qE+Lz7FjHs+ho0IBPZol8sF4W6rK8FQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-card": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-file": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-folder": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0", + "@umbraco-ui/uui-symbol-file": "1.15.0", + "@umbraco-ui/uui-symbol-folder": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-user": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.15.0-rc.0.tgz", - "integrity": "sha512-19a9edL1zmwK5ufyV15hYU6k5aWcLTf6YCOqjcZsnVZfZTpqu22pnDHH1eA5KYh4usGFIG6fTS5dQh1b/o7y6w==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.15.0.tgz", + "integrity": "sha512-oo7gCs3RGJ4ujFs+LpG9I1DS/XSNkz9gaqvp4BkaR0kBXzw5f2SLLGhA9S3M6M+OPlsXuuJNKlTV1tn2+LF6Ng==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-avatar": "1.15.0-rc.0", - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-card": "1.15.0-rc.0" + "@umbraco-ui/uui-avatar": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0" } }, "node_modules/@umbraco-ui/uui-caret": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.15.0-rc.0.tgz", - "integrity": "sha512-ym+6OpksGsJDL7TkRtnvnGu+1kq6VOyxKlvYR+1pqATQfU61t8DBPTuZXYdyiXLKkh5iOSxmxnoq7jIYi89VSA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.15.0.tgz", + "integrity": "sha512-cnKP5GeaI028hGabVCki1kPqAVSekFeP7QEwu7lncA+dcX8uvg+ffV6kW9FV0emOhI5Tmxvh8o+UDKlLs28q3A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-checkbox": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.15.0-rc.0.tgz", - "integrity": "sha512-vCXJi1x3HGr25l1BubJcJJU6XN+Mw7Wlq1sCThS5MBBDi/SaZojV0Xpo5EwREnf8kNn2ozKG5qhKCfHLptO0QQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.15.0.tgz", + "integrity": "sha512-vPkgrFAPDMvJdJTADIWNj48D8gJWD3dBotucUghg/wHhvJv8h/2MvnwMUNnnSB1REHbanl7hJBVvKcNkoil0gA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-boolean-input": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-boolean-input": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-color-area": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.15.0-rc.0.tgz", - "integrity": "sha512-MB0iM4pCVEs3JCBHMUa4Zu9AQJt+89JkZuTHzOMJKaZG31rWx4Jm5BzLazstnxRTkrBsY3IRq/PSnU7bT5jXUA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.15.0.tgz", + "integrity": "sha512-k6u//b+s6UYmzKYMizIf2MRGD4kFy1qWdSk1GnIeDdiQxABJuBZEtkACIe66j+lxnonFvZ/assbLbhRiu15ZCw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-base": "1.15.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-picker": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.15.0-rc.0.tgz", - "integrity": "sha512-Qxd0jRZtCkpoKkWaNLs9zGqqynXLA57XDDz3BpC/KdyUDL9Ab8HDUdtZJdTNla7+Paf2kZ0jqINClas/0AiWaA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.15.0.tgz", + "integrity": "sha512-I4KGyzZZazjeifcavHp7qnMbP0Jh0dM+gzZhV+YtdPR2JT0o7y6stkbY0f+dOln0K6Bu6BQLV0HLHl/1f/1NDg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-popover-container": "1.15.0-rc.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-slider": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.15.0-rc.0.tgz", - "integrity": "sha512-gRKjEEB93OBLxkkq8rnix8Ve5hIIHkjgsO0EoolEHUNx0R3E9nlzc0fkG1xdht3Ifd20CFQS7PsQ3ciJjUvQwg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.15.0.tgz", + "integrity": "sha512-lpT9kapypGkTelG9COSk169VKs0MSiKweX8menDDn0p6I4RfKQBy0N27HecCcf1RqPsCnTbP3lPr5DJy00KdzA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-color-swatch": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.15.0-rc.0.tgz", - "integrity": "sha512-LuyExHAC9nv2gK1sd4QolUreAAvqfNzQR1iDggfRqx9RG+X7yXaxssDRZ0L8uL7ga1sefYSQlYO0L28e2hpLCw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.15.0.tgz", + "integrity": "sha512-1AI0QMr046fKc8xZ4aBO7FDwvggsS9plIpY0W4AGrqQxqGUR2u/mTU49+8xMtboaFOen5RQpJ65DN9hAgeNZ+w==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-swatches": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.15.0-rc.0.tgz", - "integrity": "sha512-OPT9M21/5dHxEMXdxMH6Vum5XDPhSqCgJ81OKvXk/KfYCMXdh8mfkOu+EqchKL2bgDsAbc5eaqk5aLqTwVF+hA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.15.0.tgz", + "integrity": "sha512-UzlgWdsVHyCM/znFThrfA4A/S/K/R9Nc2KyRYiyy2xgBoP7x2vJ5Rn4mnR02W4bhI3gNgCJ2fqhmyiW4dxyk0Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-color-swatch": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-color-swatch": "1.15.0" } }, "node_modules/@umbraco-ui/uui-combobox": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.15.0-rc.0.tgz", - "integrity": "sha512-vkJZT4bno93Xyamky2vM1dVh8vClX2nm7P3Vyd/drBCihcBDcijv7tRCn+97HzEXyUO5aEs4lV43niyOzsRIoQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.15.0.tgz", + "integrity": "sha512-CKslvVRCKCReMr/ZZh4wc3TKJNvFjKVm/hSIvFqCIoJuSKfC4XuLU9SK9FL1s42NUAUmccSD3hATZJZ9VXqY+Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0", - "@umbraco-ui/uui-combobox-list": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0", - "@umbraco-ui/uui-popover-container": "1.15.0-rc.0", - "@umbraco-ui/uui-scroll-container": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-expand": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-combobox-list": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", + "@umbraco-ui/uui-scroll-container": "1.15.0", + "@umbraco-ui/uui-symbol-expand": "1.15.0" } }, "node_modules/@umbraco-ui/uui-combobox-list": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.15.0-rc.0.tgz", - "integrity": "sha512-7kCNzHY51hBY3YTXzCTWfsmyMMbyxPb6ClXyeUBA2DAihP/YNm73lT3zSpR9eXowppEbnTFM8NpMa3PSqu67cw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.15.0.tgz", + "integrity": "sha512-e8IhqU9AC5pOqXuzPzI+BDsW97Ac0u1GU/5MIJqRcBZ+ZttPcH4fsm4u8siCHbK1khCG0Vzo7HiKPZ0IuuOslg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-css": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.15.0-rc.0.tgz", - "integrity": "sha512-S+fIODQMdBjfA/WNg950AvRnKfXOP5j2IZgXRb2zk5KhDLx7Hr/Zw8KICM/7CeOTnbedCm/BvZoVrZ8bCtMCRw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.15.0.tgz", + "integrity": "sha512-0FPJ/NHE8MSJ7vvdFp4cSWT5L73KS00bUHPyA6oiF/XnE0AfS9TzkSWObdSrU6kyPr/fybVwsycDZNBfPiyrCA==", "license": "MIT", "peerDependencies": { "lit": ">=2.8.0" } }, "node_modules/@umbraco-ui/uui-dialog": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.15.0-rc.0.tgz", - "integrity": "sha512-j81llRkeb+cL9DIPpfI0TDxi63xdiZchNpLg59a7wI9UBgoTAdsjhml6vuNgf7x2ivmy7OF8XswP98MQSoQnxw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.15.0.tgz", + "integrity": "sha512-iVsrVVnvBrCCT9uJhyBE7b1kXwWUUKDmimhs/TyF1SFjxWP/U0Z99QqqI1pawdad+BuK3oVCmxYOdaReWDQXkQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-css": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0" } }, "node_modules/@umbraco-ui/uui-dialog-layout": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.15.0-rc.0.tgz", - "integrity": "sha512-0UxrGcCThIBk15lsahGGnDzJXR0QD40JfqZGkc7jMddCF/uljBn/R2Ccke1VEic6x9SiB2csPLpA9L/sIui1hA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.15.0.tgz", + "integrity": "sha512-JdDRIzSGGDnvVqXSIhc+5rDXMdYMO+Hd7s2hqLp+iRSn8IHISN/qT1nfFVO9LMbLdcApanl3JJ4Rru9LN4Q3HA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-file-dropzone": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.15.0-rc.0.tgz", - "integrity": "sha512-37flID+ISdYZA9i1p7sVqjf6qwvrHtYFUYIh7xSuQCQPT+ftrg/db3S0lUaWJnslOGe6ChhLp4qSXo8p3ZLDVQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.15.0.tgz", + "integrity": "sha512-MhJRkVdDQWKEBvemNRD4bZCuIS0JUll1nNoPK7scA+e6vDmbv25vqPHNXGE/sIpVkChY/L+v+twokzlHn57XMw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0" } }, "node_modules/@umbraco-ui/uui-file-preview": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.15.0-rc.0.tgz", - "integrity": "sha512-sFBAUDSGV2fiLV4xdcou7t1GZKCtYTETUZW/zJf0QTAoexjlYyp9hcRw7f3IhOBbARlQvFeuoIiA5e1ZZA+3aw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.15.0.tgz", + "integrity": "sha512-AHKIdYLC0ga4Wgr68xtW/gG3NDqn+QhD2aus0l2n4lBoq6OAQ5aZiPwD9i1fCD7dgyjKQ6Ov9PJSaqRYQkOlNA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-file": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-folder": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-symbol-file": "1.15.0", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0", + "@umbraco-ui/uui-symbol-folder": "1.15.0" } }, "node_modules/@umbraco-ui/uui-form": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.15.0-rc.0.tgz", - "integrity": "sha512-+drFTajJ4i+Kzv0DD8mSMb8eRHMM5l8E4ucAXVpXjQ6oo8LxRemmjFoU+wq4y/xLZeYEvRXz6m33esRHjgFhug==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.15.0.tgz", + "integrity": "sha512-4u9ZryfVBunpb0IL0+TevytrISA6S1+AajiK/PUk0JMJfqMuQMjmpnNPdtYRNVgFFIcQFQKipjT/mrHbDVawxw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-form-layout-item": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.15.0-rc.0.tgz", - "integrity": "sha512-IU9WiRWC7/O+YeMRPhnJ+VCx7i+gwRIdjeCmpB8LbRBspK40PBYpHn14G4parwaKHGVfOnis+BbUjWP4TTOrMg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.15.0.tgz", + "integrity": "sha512-fiWGeQpREnl6k+6VNHz9ixNdEmOoFNm7qsgdIYJ1jCDXBGME1mjxJOr2Eq7UWJuzQM8BeyQEcXq5SVIOv21PRw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-form-validation-message": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-form-validation-message": "1.15.0" } }, "node_modules/@umbraco-ui/uui-form-validation-message": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.15.0-rc.0.tgz", - "integrity": "sha512-B8l/jlOtAWimDC2m7/pZjnZS/rVNayYVivwsHKnQn/KN0XQ2nyYq8cpYUA1XZ+ZqDbS/0BP/UUZIC3Fx4n4Eng==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.15.0.tgz", + "integrity": "sha512-RYfwmjPkY0KumjaalLW8gkasW25Mj87YFAzJn7mAYiZigURape9RqGpvrBfwcMmGj3W2/uVuHxpAHrvweQOt4A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-icon": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.15.0-rc.0.tgz", - "integrity": "sha512-x+HjEO92m4D31Xajzet7XwmAWDNim0XMn0IDB/qxHVza3N3ciisaMiqQ1kx/196RTcKFFWVOT6d2UMwPxwS5eQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.15.0.tgz", + "integrity": "sha512-e8/W6gu6kwrodH0f0U70LR5rHQhiZGq3NqLqikAQ1rvmwitXUqtkVXIhkGxSf7M6yPhpmoi2qEEZDQH9cvCE5A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-icon-registry": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.15.0-rc.0.tgz", - "integrity": "sha512-/iNgSrVtXUQzwYRLjAI3XcIcr0EnN00trdOFCGd/2TnEhR1QOxNHIw/0FvSqjDder1y5gYFwLregle0pOvzkow==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.15.0.tgz", + "integrity": "sha512-nIdzCqoABeRVG6jW045ok649MiAhm5zPdfuMKc1a+TNw9xkKj+vnA1YcjaBN502+AekMhhwnqgj9mLL+mC2VPQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0" } }, "node_modules/@umbraco-ui/uui-icon-registry-essential": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.15.0-rc.0.tgz", - "integrity": "sha512-sj7R4u1DYXOHpjeYnlJPA3qjdp4SZSen1/XUdbQxouANcI5a8ZCVfg1+7WIvYWIDBJ2c4VMabGkZYkAvpgLanw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.15.0.tgz", + "integrity": "sha512-llHFVMlV3Uyg2fHiNt1qfDgRhLthD37uQD2FzlQb0GEYjp+4dE8Jyc/eZW2mqABPweUJACVwbrwBUVrCeQJ1OQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.15.0-rc.0.tgz", - "integrity": "sha512-UeoW+WzqfR01kDqgDDsRX+N7ELujghXqDoOx364kJjlwfiemh+58490bujbOT7a+AG1LDNsV27px0OJBpNsErA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.15.0.tgz", + "integrity": "sha512-vPc4I/kkQM9RWfHI0F/OQhoTu+KefplbQp0JEQ4gfr6MwxIm6bBTEuw8T5K9t1DQs8EZ7yeLEsSh65FDPepRtg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input-file": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.15.0-rc.0.tgz", - "integrity": "sha512-NNbOzLtRPeWnzJoRqLP9BKyCrZODsuOeJuFKQUUPo6NuT2bg1SIu51PHdRcO8a709UDH/lB3wBSuwt3Be71TEw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.15.0.tgz", + "integrity": "sha512-VVn2FMsflvEWd6fOX0HQ3JaUh7haznqSqCLTSTOduh/H3jE+dVYCW6YC5uTsxArmOwsSBYSfBQNetW23eJim3Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-action-bar": "1.15.0-rc.0", - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0", - "@umbraco-ui/uui-file-dropzone": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0" + "@umbraco-ui/uui-action-bar": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-file-dropzone": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input-lock": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.15.0-rc.0.tgz", - "integrity": "sha512-CJKssXf7E8szjGRXghkyHRMo8seyXq9jxrumWyxxhJCHGOXsGecIREc1oAd/a2C+BfZzdyykGiOiJLZoJRURGw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.15.0.tgz", + "integrity": "sha512-AFyVYNeExHXe10b3/5/BLZOmMKyMxzftsO0HKbaQQuxrxL2SCHsQJRUpxSY+/0vAl2JbNdmrk0HTsP1O4Y9zig==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0", - "@umbraco-ui/uui-input": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-input": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input-password": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.15.0-rc.0.tgz", - "integrity": "sha512-H0G6xtLeWE1z8hi0cgMA4DnE6ay84Z4y2vtb5R9hvS5oocMbpybjOwaKuiV3H4qam/CUAhGtRnTqP0cEWqLahQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.15.0.tgz", + "integrity": "sha512-Pe8lNdHz/6IfbQyWEi0o+pKJ6/zunQ2b8HARCU0a9HFXRDk+XsAuBsn79zQXZl5MvseAUQrnouLwPHpdtMbeMg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0", - "@umbraco-ui/uui-input": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0", + "@umbraco-ui/uui-input": "1.15.0" } }, "node_modules/@umbraco-ui/uui-keyboard-shortcut": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.15.0-rc.0.tgz", - "integrity": "sha512-mR5SWcf+U01aJfNxtgTZxYJQ240MtxnfKNo7C/7soxLnTd1w0Pp7KRHkB6GgKlqTx0X4Umcdu8kn35cCOkoDtA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.15.0.tgz", + "integrity": "sha512-8Q/G5Lg6949BbMHQ1BhZ9UpoJjOQ19w1tl2y0d/rP3w/mKnTQaBSf+MQmA/6kQ/Unb2wHXJANr4pAGpUklOg6A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-label": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.15.0-rc.0.tgz", - "integrity": "sha512-P/wuJift88Sd7fq/BASMTb9JmqpA069GttPxiIoCwMb7zt+fX+xsjjzPHiD1FLihVPUFdw9lIq6d65ahbrDnMg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.15.0.tgz", + "integrity": "sha512-fnmRl+RGUROERvt+Jw0WiW3Btlddg0Xka6F+gR95gy5gr/v8s34uf1/bbPD3hWUXZPukLmxeMjbzyuqMrO8rpQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-loader": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.15.0-rc.0.tgz", - "integrity": "sha512-XD8DsEIQhVVnXtAFNVHwH9v6ysTyKbSpHeq9pHFWmupCpqvF1i0fBRYLnE+nTyzq5331WyoQieWrsmYz2C8dTw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.15.0.tgz", + "integrity": "sha512-HQ2zCp2kz45GWQ3wV153ytuYD2KcdeAA5RRUVrN0Zn3GQB3wfG7xMkQQNRAOWMUdnfqmdQHeK+COO7NaET3VBA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-loader-bar": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.15.0-rc.0.tgz", - "integrity": "sha512-rXH8dEagrmiWZHgdHfb7Er3FsA93ZBrvF/KF4tC4Jw+2xZC+tw+n/7yAKcWM8JpCphGaIl2e4BqoalNIazmd8g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.15.0.tgz", + "integrity": "sha512-4eMeerunFc5yZsJIwpHADn8oGcu0Nn36oyKbSd0qC0mNmmN2i8UOF9w4O+lndd2L0Mhv23FGvBRo7mb5EAvWlg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-loader-circle": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.15.0-rc.0.tgz", - "integrity": "sha512-JfjucJUjGMD9yKgOscYXPOY0KN9ABbmMTwOQTzWzWAPvY6P8/OgGUKrGAQAnZzQ2Qqcl4/MMGuN4L5HX5YC3gw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.15.0.tgz", + "integrity": "sha512-4rG8UHvyS2qvsjQYEmYjKX01SRwfk60oH8SSSx8r3z2BM62dCOa+4SBhLxqiBciC/u8FtN8X20MIGE0+eMdtoA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-menu-item": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.15.0-rc.0.tgz", - "integrity": "sha512-rGe/GsgWWyPZiRw0vjW7T1i00x3IKt502ESADdfK/ViF8rE9JgVIDvwCGvYHvbDPfVQci8YsQYS8I4VX29z77w==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.15.0.tgz", + "integrity": "sha512-BOebCMB/p4TaK4kJYrYgimC6SSGBHN4y1MytK3tyvObbuj3gVqkbwHW5CZrhK4jMaywRgGq96OsuaGfc52HFog==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-loader-bar": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-expand": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-loader-bar": "1.15.0", + "@umbraco-ui/uui-symbol-expand": "1.15.0" } }, "node_modules/@umbraco-ui/uui-modal": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.15.0-rc.0.tgz", - "integrity": "sha512-cKO6BE5tWDIfiGAMM/8/6GmOTrEzVqpSfe4yVFX4AvChOlCfx0+NS2gffICzFq7n5BZ7lOKo5dx8ByuRDkIhrw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.15.0.tgz", + "integrity": "sha512-EDz1Qx+mTXNvOu565IculPCyuuFHwBon2wYnfWDBMoHJ5+P54jBHzg2U/8fUVse7xKPvU21hF4JneAvycNIiGQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-pagination": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.15.0-rc.0.tgz", - "integrity": "sha512-NaxkYnfUSQNfXVpyQyqtFefpvA4ElBaXf+BdhwxEIYvki7qLsracZxPtLahgfxm08xP+kP5smIVSNbLsOUh1Kg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.15.0.tgz", + "integrity": "sha512-sPVs1bApKupNd2JcSMwFS1060Y++Fti1ybJrafcLh1+h4IjmLDIRTHTTL8C+kei5G2Oi3+Z7vGpLu7lrTAmRlw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0", - "@umbraco-ui/uui-button-group": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-button-group": "1.15.0" } }, "node_modules/@umbraco-ui/uui-popover": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.15.0-rc.0.tgz", - "integrity": "sha512-jkrJVREYar6tNG+DS01Wnqg656d6Cen2sUTYl/grKVsgLqdZPP42hzpClctlT8HdDYSj650e5JOCqSOFZiv2Zw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.15.0.tgz", + "integrity": "sha512-VCHVvO0fd5eL5UvB/RPL/K68UhOgsIpuyr+aXLblaYT/6at2LNosUxR4eRW2r0WOQzOiyE+Nu69pExBKyfT8bw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-popover-container": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover-container/-/uui-popover-container-1.15.0-rc.0.tgz", - "integrity": "sha512-s/j+dlKjtVhAXvs7FKwjL54xlrqfWnjqjycxIABHXasrJbLJwX8oxs2iL8pk4mb4ZbdIpdA5xkRjF4eTyfT1Jw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover-container/-/uui-popover-container-1.15.0.tgz", + "integrity": "sha512-54M4G0ru8j5ltPAdDGIxogdmos33hxeQeusI/uMFxo2yqHHyMHRi95vvCdcwFmGlEdFd2rsnxZKfNMUKM99GKQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-progress-bar": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.15.0-rc.0.tgz", - "integrity": "sha512-oYGogiagAay/ZqmDgTtB1FCjXZuaN/5Lj0TiOFwdVtIO2l+xmHwyUyX7byyt2kaZ6kGcuROTlPYn1gDvK5yRUg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.15.0.tgz", + "integrity": "sha512-vtGUwHaG4EDLQERkwym51OasoWLj30LQLhcCCYXDJtTL1dG2nIKScEtlSUiVh5qRsI+V+kaBYPGD4TFD5o43tQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-radio": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.15.0-rc.0.tgz", - "integrity": "sha512-l/+QPKyN+9CiDhKxOfmDnbpXLO7rkLM0F8AL+fy/Jjp33NC32blQYAkYV+Ayv0H898nkZBrcpA+tvVGkoiHKeQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.15.0.tgz", + "integrity": "sha512-5TUF/iWUzbVXvBs9Z273q6s9yLbns8itTiFHCITw5w5fZzDn8R6O5hrOW7tV79kCxAnBSOAVP8v1JhGTwXw19Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-range-slider": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.15.0-rc.0.tgz", - "integrity": "sha512-P8+e+JFlEhsZHntt3XVwKQkNvluIVqnlLM3VYFlOeqU+3pgsDIat4Tm2YiH23Cd8dCI0G5eLlmqVLPvwQjhhDA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.15.0.tgz", + "integrity": "sha512-HMHVdBoB1O39rojofezee2aXGv6CMn7dUFvNefdF9HxmNrIcpFBYXSL8aBt5QJeziFQMwbCtqyY21aUag0nzfw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.15.0-rc.0.tgz", - "integrity": "sha512-ZQ9U8x2ypxWqFFFDu3vjXPahUbr7TmGKUSBwDai4HPdLXOQqoAR5Fc0NOYxx4fc9yq5NQ2hczK1hd71V9ST28g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.15.0.tgz", + "integrity": "sha512-w7FZIe5mtsgvsf6hOH5mHKDBzg9Rd/+viyk/xNVs1NeZBn1nWEIHZs0R7YMpv+QxulklhAOpBcbGoUTB8xE+vA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-list": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.15.0-rc.0.tgz", - "integrity": "sha512-th86PCdgzsaIwtjLr8AccyvHYhpoRKWVDjDEcFkfpUvbogSI8u/0fSmkaNwUjtCehoRT/HCDj9we3Yn4A10xUQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.15.0.tgz", + "integrity": "sha512-UT65bpUmRlEgVuvn2RlTZ5l2WDF82jH1t8g+6HV6OJctpqTKlOfPkQmd6AluESPhHFEwwTydS/M7x+X3Adkdtw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.15.0-rc.0.tgz", - "integrity": "sha512-kw56OWmUdd2sFWeYBjcKaE4mDuLFjKv7JImwIfn8LYtZ/uTcwsdiGOQf6gQtNbMVtW5FMjJQXBFCagT+HwW0RQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.15.0.tgz", + "integrity": "sha512-ybDqIt1cXd7AiZLZsDrSHCMp2zM8I+0lmN599b3NROjm59SZXIvpbY1TS1gJ45htgsc18x2y+S4laInYu2dGUg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0", - "@umbraco-ui/uui-ref": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-ref": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-data-type": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.15.0-rc.0.tgz", - "integrity": "sha512-ZYNoUVBPmuxYM3obWfuiQNJCAEv7csDMpiQJ0Eaf3W3hxm6i1HxTC6V4NajO38zFVBsJjCaXzqgESLPtN1DS+g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.15.0.tgz", + "integrity": "sha512-59s16558ySCX7b9IT/Sorq0fdFeCRENSTa7DIkQUrvVPaFWqKFz9jCYFEqDnH11jZHGsNiYh5YCmWlF/VNbwJQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-document-type": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.15.0-rc.0.tgz", - "integrity": "sha512-ZEtyl+n/IkSflZxLwhKBGTMJYndJPHBGAqijqAajDWpBYrum/bxu8bYjE+oVkRRMHqQgCm/q6B4qTrX0qsPWfQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.15.0.tgz", + "integrity": "sha512-AWPZPkFGcAkRx4j6JnOi2r3EJxnvZUXfhOWNyWB2/dFRckatPH56+lVkqV+fRC+81emKBSQWkx2NphFzLEMr0A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-form": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.15.0-rc.0.tgz", - "integrity": "sha512-cQER0tdwAGSzyO76RDDj/aoIDC3rLv3EobpL0BeSldYfgFQKfyS+96JthQkDytJP1RC8kJdQ8J5/QM2Z+QTDnA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.15.0.tgz", + "integrity": "sha512-knIIbbfoWtepOvyC54dCo3xF0Vuap6i5uMQPd+wITCmg56a+yiJFuke+dyzatOIeXzgspLgFUngwQZEj5mJnWA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-member": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.15.0-rc.0.tgz", - "integrity": "sha512-oOqA0Dl6Zc312Li8mLlTvIJ4MDiaMEGD5ip1plmSiNF7YxRIh+6srrPugAZQwsrU+q6JVEEul5HjgOd8Eu46pQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.15.0.tgz", + "integrity": "sha512-pXvL523m2JR3P8OO+E1AE4YAaYhJLc519CtjNXSuctNIk1yWvwxBu8VozLIQV+xrOXGz+SiXwDkoaRPwjTQKtg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-package": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.15.0-rc.0.tgz", - "integrity": "sha512-oXh030/wLZiU/9TBEfHvoGHXCRDcI43oJ0x/Den4S2U1Fc+5U4Y9F0LvA3611IL2EqUa3ZA0tQJLzAt6kPbpkw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.15.0.tgz", + "integrity": "sha512-bQWfZPKJyAf2O/YvOD6fVSSpKaYZMBsrEGT+ydLPv3BNJroYHS8+NEbulZxExWztNApTcs6Vo5T19AUz+vsnLQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-user": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.15.0-rc.0.tgz", - "integrity": "sha512-KqFQAaXGdf3N+RLj3tuU0TFeedNANT2fr6dRuVysEL8hKIpjkCKdNp4PCGePY1BR97/NVLNnXXuG3+Ccued3tQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.15.0.tgz", + "integrity": "sha512-4GpRzhGedMwjqW1Wk7AvgakNCc6S1edYpHWeO6cfmryIm0hvnCfkU132lzLmB+Ag2QIOI8p4Ak0OQHYWd+XZHw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-scroll-container": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.15.0-rc.0.tgz", - "integrity": "sha512-KfBdFU2zY5IfeNUMreCwHfWw0HoEPx9+2pbmc7UCPgg7SjYMkBNa8sce+bpc/OoUUpo9zbbvNjqF6eyXqeVwGw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.15.0.tgz", + "integrity": "sha512-L4qM6GPDqu0/9B2OVb3EljZT3zYxbwp6uOz1nfVYpGAWBxd6INOtNbn8WYdZLq6qqa8NR6qK+su2554nInvQGA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-select": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.15.0-rc.0.tgz", - "integrity": "sha512-IORtMOqTy/1+S6a7QRqg8LKgqRX4jLsQkz1J2PK2DtuKceX/tO5HmE+Ec9cTVSFBlDFE95uek6VEsGyGj5oGMw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.15.0.tgz", + "integrity": "sha512-yRx+TlXBB05jM8ShThRooFgCS5nSN7eAAnpttZgBWqY3sccIVy2Knbkz3kXLJE6ld+bO5nUXhsZBZ34MEHkiog==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-slider": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.15.0-rc.0.tgz", - "integrity": "sha512-CifB669wtpHvTzG9d9jKj1eVB9ePeJSO8L4DjNSCaDyvrsYxDpZYzOBQuaIpPRXwdGyznFSyOAb7d8renrlpBw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.15.0.tgz", + "integrity": "sha512-+OAzOutyUB2WCI+e5aFRoUNsFFuc/hUXnpIjx4P1moOYiggc/NxjaTHz5mxbmkC11yyS+0vpl8lVSZglkLCH5w==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-expand": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.15.0-rc.0.tgz", - "integrity": "sha512-GQ9SMmMVJ6b/vAMa22QVJOTRn6uFdu9IELRtwrBNDgywA5L+TG7MyJ4ZgKXc1DwAKwVXwlS0qTAWBis3z1CZRQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.15.0.tgz", + "integrity": "sha512-6y9rpFfhtuWMnaAamlzrB5Q12dsZ8dprmQaGtKr+g97PTNRPC3/dc5sdROam8VMDAhL9MkfBAZBoS6yAoJsPcQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-file": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.15.0-rc.0.tgz", - "integrity": "sha512-8FrKoBzm1YKM2L4dpNG9DjqrQZ/qnUfnx1oLzohxWZXKn13dxS7XdDFkn9B7PPgcxkxPK5DFR2Y8H0YQCTPEIw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.15.0.tgz", + "integrity": "sha512-F0BueWxu6J5P7xyzkp1c/eFZJjStsw65hB3bNEmWBOqkm/jbBKg9+Xs99tov+VwCHYOt8T+DuEDkkKmdxVAxyQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-file-dropzone": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.15.0-rc.0.tgz", - "integrity": "sha512-89og/JhpHbcQj2NuKnbJJBKKCvUWnixMw+yEDU6K4rQ7gOEWMUiYgEI87rfpp4tIRp4pKLL8jTDrvu6I1rS6jA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.15.0.tgz", + "integrity": "sha512-D5DottbukIFxL+YTVEMujHPdqB8Hhw02TKpegfDQb8UGSPC5pCQw4O212TSuyTalKb598niNmCzcjEG5TWNqww==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-file-thumbnail": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.15.0-rc.0.tgz", - "integrity": "sha512-LxNSR/v8NnAs7iyhDBy+ylf8C1OxxIelm3Q7/6ko474wsaBfQqwfJUbmzqCmcQhoptDZia0VxjWB80Sh5OtkAg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.15.0.tgz", + "integrity": "sha512-JLcEVnJqv2LL8VtscPCtPKda9ywWzV4vd0XODHLE3iI1cgHeNwMBhxqgkah0ULuw5w2Hrq8gwQ7/DuPHMSIFxw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-folder": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.15.0-rc.0.tgz", - "integrity": "sha512-OqMe0IKp1qIhyQJ3Yw0CMcEt1ciuO/EnoUPtdeGUGLZBfZiTEkXoxBc2Yh/6kBLgySDydD+Ddaa1gIYuMpM3RQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.15.0.tgz", + "integrity": "sha512-CPsr1K5IkdxBgID+xoIcgbumm/z0q+Z/1NPxTO40EL7kx3KOLQ8vwLdOTSW1cTj90JFA9+XuRtOpmMEY0XjICg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-lock": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.15.0-rc.0.tgz", - "integrity": "sha512-U0hU0MAZGA6eYz5lMxKajwsEQnUGFGaDgeE6cnJBBManrlT24RmDSFmr7MlW2V0yTYOrWJOCv/P/RPFvZBNuXA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.15.0.tgz", + "integrity": "sha512-5QyDNFjiBeuPgalT9zwPMP220zJUHPpbPvCohWCFLn/2JJsa6IjSMtsAcqxI154ZJ9vYX7vYiYUn8tJTY8CHpA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-more": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.15.0-rc.0.tgz", - "integrity": "sha512-BJ264C8xpe92a9Rx2sDirpS1jqn/en3oVGUV4wDH/BJw+jQAgTt12LzHEjQbNNEbuQBYuZuzLnoW9UVQwyV5hg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.15.0.tgz", + "integrity": "sha512-BQq7BwZ7nCcgKE5tMhG6OVYTrrMEIXpx8kQKec/ULgVfs0/Ws6qeH9u4rGVK/yHU8gecd6DSeUczjjq2iS4djA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-sort": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.15.0-rc.0.tgz", - "integrity": "sha512-xj464OIL8Casqxk2S+SdmwBGn95k5SBh3Y93fZEUykZ4vFG2zmwk32chrJ8kX0uaQ7M3cg+lO5RZRk7QHBaPQA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.15.0.tgz", + "integrity": "sha512-5Akw8T0SV2OrwvPk1JSeFr1clvHE4N0DwceSU9bn9f6gLIGGRxvniJAclQDRI/Woe3hm8waMy6cC2fXfSdc6lg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-table": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.15.0-rc.0.tgz", - "integrity": "sha512-usidTyVmBgE+YYt1ITg0JQxurSAyfg6bz8Fh5FLQVS9hdUWKsRvRhJP7M+u9tSIjzv07mhIlZWBvt6GJUMjFlw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.15.0.tgz", + "integrity": "sha512-AnPp0QJeI70ucX8ludr3qaFmlxjKZUarX10DI8ieIB8VJiQZo0TjoPcPdSGmZupaPBLiszlpb3rKzGkZhXEIHg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-tabs": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.15.0-rc.0.tgz", - "integrity": "sha512-a5o7FXRpj3bAXTkyLlV7G7gn6nHlNn6uYEaSfwuk8sAAfcF84hp75OWLJuNrbIaH6IOblgn4FNBL01GgdAB0mg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.15.0.tgz", + "integrity": "sha512-oS0eA5Z8+s+5o2ks3WCED5VGP8AunRLyuB2y7kVdRUfhCfck7B9v83zNfxPVoGoVsTDLtAQM1S4P8SHwNRmk7g==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0", - "@umbraco-ui/uui-popover-container": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-more": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", + "@umbraco-ui/uui-symbol-more": "1.15.0" } }, "node_modules/@umbraco-ui/uui-tag": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.15.0-rc.0.tgz", - "integrity": "sha512-cnOEKEGM5BlpDEx4/Fz2o0D2n4o7si87A9UHMPbiDKFNFcJ0gfitwn7eJGn0EZs8C2GLti9wvxv24oUDJ5Hd4Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.15.0.tgz", + "integrity": "sha512-PgyZvAiOZmXmiRW4UhfD6Tybx3ft755aKAVqT8ELpskLSvVr1oz4uTI6+QxoeQ1AkrHovenvIdBX+Iwi91SheQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-textarea": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.15.0-rc.0.tgz", - "integrity": "sha512-J7+CFi16wJWMYpQ+c4VLQdA/bpDAIt6USCzoT+Rs+UYFcJKOHI4eEBxQknA61SZMbhcn9hXHI2FrIeR+2/S6GQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.15.0.tgz", + "integrity": "sha512-tk/RVzCxs+KPSJ+qH2Xlr9RYxcdrSNulDKk5sBCQR0A9nwOffa15SGreSMKWgq+gYOVYChHBg/WxLWLq3d7Rlg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toast-notification": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.15.0-rc.0.tgz", - "integrity": "sha512-dEu934tASMh4vbuzy11V7WIKrx5iMQ92j/1lw0ZHaDLHNdkpmkZtbSUKYlO66Wq0EMu3s9O5CAWRNFZJlV15EQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.15.0.tgz", + "integrity": "sha512-nz+snpjPFE+ftH5R/ekgZYy9ofGAf51yQYjWCtBwkrQ6D1dIBYA6kynZFdqIefrRwJJ5zHpe25BcS/AyRPc/9Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0", - "@umbraco-ui/uui-css": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toast-notification-container": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.15.0-rc.0.tgz", - "integrity": "sha512-8fSSsBwAoflq7w9qwcKSmrnq6f5JADgzquEQWrK4RXvfvBeFXXlII14WbfYqIe3+FX4310VuPooHse1vd0UiCw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.15.0.tgz", + "integrity": "sha512-fd5d0DU/x2+u15rP0wrjw29M0oqsDFmnAfbPEdgQoPV+hvq9/SLhxJtzx10ZSNXoyuO9sTK50Q7nYsqOvGCzqg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-toast-notification": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-toast-notification": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toast-notification-layout": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.15.0-rc.0.tgz", - "integrity": "sha512-IX4w00PwV8BMbLeqs37Yn0CGGHtGlabMxwODtICze5TkPdD64Xc9W4oPbQ/Fr5CgJdiJhb6OyeVd92cr8n2lAg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.15.0.tgz", + "integrity": "sha512-uf/e/dVN6kqX76vcawiQM3w1nMHa8A+ZTtNwxtmAZi8bNPwjXLNaqKfeSp2thTByCIzFz7imnft56QtYLbksOA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-css": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toggle": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.15.0-rc.0.tgz", - "integrity": "sha512-ReMVDGO303IIM34HPArTIcVSCfACW8+4gY+fJr46vdy+XPjeZupoBDbxVrn+zMacxxF92sv7gqdabMYhBH6k4g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.15.0.tgz", + "integrity": "sha512-WLooENcxuAobbXxN1W2uKGh/cN9k0f3cRmDDtCZdgjeheGlBYWatkc5HQte7zchXHUi0xTrsvBCBa9CsLKN/3Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-boolean-input": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-boolean-input": "1.15.0" } }, "node_modules/@umbraco-ui/uui-visually-hidden": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-visually-hidden/-/uui-visually-hidden-1.15.0-rc.0.tgz", - "integrity": "sha512-1em6yB9KuZbe14ZQrwmL20YCuEeGKNHiJ4veZ5K/Dm/x9wvsd5skw5M7vMVK+gF77dJBDuGpPLtCtp/FqgFG8A==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-visually-hidden/-/uui-visually-hidden-1.15.0.tgz", + "integrity": "sha512-vn3dbpYGekAqG944Vkwd0ILQRtTaZtL1BVdsge2UsU8sOsEKwv5YzQal4b+o8yu8nb4vZbWHZ2zRmnpnPgPmjg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@vitest/expect": { @@ -17298,8 +17298,8 @@ "src/external/uui": { "name": "@umbraco-backoffice/uui", "dependencies": { - "@umbraco-ui/uui": "^1.15.0-rc.0", - "@umbraco-ui/uui-css": "^1.15.0-rc.0" + "@umbraco-ui/uui": "^1.15.0", + "@umbraco-ui/uui-css": "^1.15.0" } }, "src/packages/block": { diff --git a/src/Umbraco.Web.UI.Client/src/external/uui/package.json b/src/Umbraco.Web.UI.Client/src/external/uui/package.json index 072fb13ef4..c18990b32d 100644 --- a/src/Umbraco.Web.UI.Client/src/external/uui/package.json +++ b/src/Umbraco.Web.UI.Client/src/external/uui/package.json @@ -6,7 +6,7 @@ "build": "vite build" }, "dependencies": { - "@umbraco-ui/uui": "^1.15.0-rc.0", - "@umbraco-ui/uui-css": "^1.15.0-rc.0" + "@umbraco-ui/uui": "^1.15.0", + "@umbraco-ui/uui-css": "^1.15.0" } } From 5a22e5012082c22fb3d6692bd3785037dbf9c5b0 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Mon, 25 Aug 2025 08:57:29 +0200 Subject: [PATCH 05/33] Revert "build(deps): bump @umbraco-ui/uui to 1.15.0" This reverts commit 9cb5a12143dcdf2885a848aecd05fd1f19c712dc. --- src/Umbraco.Web.UI.Client/package-lock.json | 966 +++++++++--------- .../src/external/uui/package.json | 4 +- 2 files changed, 485 insertions(+), 485 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 0fe48a94d0..81227af986 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -4004,909 +4004,909 @@ "link": true }, "node_modules/@umbraco-ui/uui": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.15.0.tgz", - "integrity": "sha512-8yCzfKePv9zK+PMw1K3uwpnDDBZkbSCCOrt8dNDlZ1/6zf+yNLu+r/kVlMcauei6aNsCwXvcI4LhBGS1f5kJ/A==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.15.0-rc.0.tgz", + "integrity": "sha512-zO5uCoiXy8f6aGP6k5fCWchKT/6c/UnDlfquODG5tQioFF3pqIfInN/0JHUgMJsQQARdm5KFkSp0PWvVmXhX9A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-action-bar": "1.15.0", - "@umbraco-ui/uui-avatar": "1.15.0", - "@umbraco-ui/uui-avatar-group": "1.15.0", - "@umbraco-ui/uui-badge": "1.15.0", - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-boolean-input": "1.15.0", - "@umbraco-ui/uui-box": "1.15.0", - "@umbraco-ui/uui-breadcrumbs": "1.15.0", - "@umbraco-ui/uui-button": "1.15.0", - "@umbraco-ui/uui-button-copy-text": "1.15.0", - "@umbraco-ui/uui-button-group": "1.15.0", - "@umbraco-ui/uui-button-inline-create": "1.15.0", - "@umbraco-ui/uui-card": "1.15.0", - "@umbraco-ui/uui-card-block-type": "1.15.0", - "@umbraco-ui/uui-card-content-node": "1.15.0", - "@umbraco-ui/uui-card-media": "1.15.0", - "@umbraco-ui/uui-card-user": "1.15.0", - "@umbraco-ui/uui-caret": "1.15.0", - "@umbraco-ui/uui-checkbox": "1.15.0", - "@umbraco-ui/uui-color-area": "1.15.0", - "@umbraco-ui/uui-color-picker": "1.15.0", - "@umbraco-ui/uui-color-slider": "1.15.0", - "@umbraco-ui/uui-color-swatch": "1.15.0", - "@umbraco-ui/uui-color-swatches": "1.15.0", - "@umbraco-ui/uui-combobox": "1.15.0", - "@umbraco-ui/uui-combobox-list": "1.15.0", - "@umbraco-ui/uui-css": "1.15.0", - "@umbraco-ui/uui-dialog": "1.15.0", - "@umbraco-ui/uui-dialog-layout": "1.15.0", - "@umbraco-ui/uui-file-dropzone": "1.15.0", - "@umbraco-ui/uui-file-preview": "1.15.0", - "@umbraco-ui/uui-form": "1.15.0", - "@umbraco-ui/uui-form-layout-item": "1.15.0", - "@umbraco-ui/uui-form-validation-message": "1.15.0", - "@umbraco-ui/uui-icon": "1.15.0", - "@umbraco-ui/uui-icon-registry": "1.15.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0", - "@umbraco-ui/uui-input": "1.15.0", - "@umbraco-ui/uui-input-file": "1.15.0", - "@umbraco-ui/uui-input-lock": "1.15.0", - "@umbraco-ui/uui-input-password": "1.15.0", - "@umbraco-ui/uui-keyboard-shortcut": "1.15.0", - "@umbraco-ui/uui-label": "1.15.0", - "@umbraco-ui/uui-loader": "1.15.0", - "@umbraco-ui/uui-loader-bar": "1.15.0", - "@umbraco-ui/uui-loader-circle": "1.15.0", - "@umbraco-ui/uui-menu-item": "1.15.0", - "@umbraco-ui/uui-modal": "1.15.0", - "@umbraco-ui/uui-pagination": "1.15.0", - "@umbraco-ui/uui-popover": "1.15.0", - "@umbraco-ui/uui-popover-container": "1.15.0", - "@umbraco-ui/uui-progress-bar": "1.15.0", - "@umbraco-ui/uui-radio": "1.15.0", - "@umbraco-ui/uui-range-slider": "1.15.0", - "@umbraco-ui/uui-ref": "1.15.0", - "@umbraco-ui/uui-ref-list": "1.15.0", - "@umbraco-ui/uui-ref-node": "1.15.0", - "@umbraco-ui/uui-ref-node-data-type": "1.15.0", - "@umbraco-ui/uui-ref-node-document-type": "1.15.0", - "@umbraco-ui/uui-ref-node-form": "1.15.0", - "@umbraco-ui/uui-ref-node-member": "1.15.0", - "@umbraco-ui/uui-ref-node-package": "1.15.0", - "@umbraco-ui/uui-ref-node-user": "1.15.0", - "@umbraco-ui/uui-scroll-container": "1.15.0", - "@umbraco-ui/uui-select": "1.15.0", - "@umbraco-ui/uui-slider": "1.15.0", - "@umbraco-ui/uui-symbol-expand": "1.15.0", - "@umbraco-ui/uui-symbol-file": "1.15.0", - "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0", - "@umbraco-ui/uui-symbol-folder": "1.15.0", - "@umbraco-ui/uui-symbol-lock": "1.15.0", - "@umbraco-ui/uui-symbol-more": "1.15.0", - "@umbraco-ui/uui-symbol-sort": "1.15.0", - "@umbraco-ui/uui-table": "1.15.0", - "@umbraco-ui/uui-tabs": "1.15.0", - "@umbraco-ui/uui-tag": "1.15.0", - "@umbraco-ui/uui-textarea": "1.15.0", - "@umbraco-ui/uui-toast-notification": "1.15.0", - "@umbraco-ui/uui-toast-notification-container": "1.15.0", - "@umbraco-ui/uui-toast-notification-layout": "1.15.0", - "@umbraco-ui/uui-toggle": "1.15.0", - "@umbraco-ui/uui-visually-hidden": "1.15.0" + "@umbraco-ui/uui-action-bar": "1.15.0-rc.0", + "@umbraco-ui/uui-avatar": "1.15.0-rc.0", + "@umbraco-ui/uui-avatar-group": "1.15.0-rc.0", + "@umbraco-ui/uui-badge": "1.15.0-rc.0", + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-boolean-input": "1.15.0-rc.0", + "@umbraco-ui/uui-box": "1.15.0-rc.0", + "@umbraco-ui/uui-breadcrumbs": "1.15.0-rc.0", + "@umbraco-ui/uui-button": "1.15.0-rc.0", + "@umbraco-ui/uui-button-copy-text": "1.15.0-rc.0", + "@umbraco-ui/uui-button-group": "1.15.0-rc.0", + "@umbraco-ui/uui-button-inline-create": "1.15.0-rc.0", + "@umbraco-ui/uui-card": "1.15.0-rc.0", + "@umbraco-ui/uui-card-block-type": "1.15.0-rc.0", + "@umbraco-ui/uui-card-content-node": "1.15.0-rc.0", + "@umbraco-ui/uui-card-media": "1.15.0-rc.0", + "@umbraco-ui/uui-card-user": "1.15.0-rc.0", + "@umbraco-ui/uui-caret": "1.15.0-rc.0", + "@umbraco-ui/uui-checkbox": "1.15.0-rc.0", + "@umbraco-ui/uui-color-area": "1.15.0-rc.0", + "@umbraco-ui/uui-color-picker": "1.15.0-rc.0", + "@umbraco-ui/uui-color-slider": "1.15.0-rc.0", + "@umbraco-ui/uui-color-swatch": "1.15.0-rc.0", + "@umbraco-ui/uui-color-swatches": "1.15.0-rc.0", + "@umbraco-ui/uui-combobox": "1.15.0-rc.0", + "@umbraco-ui/uui-combobox-list": "1.15.0-rc.0", + "@umbraco-ui/uui-css": "1.15.0-rc.0", + "@umbraco-ui/uui-dialog": "1.15.0-rc.0", + "@umbraco-ui/uui-dialog-layout": "1.15.0-rc.0", + "@umbraco-ui/uui-file-dropzone": "1.15.0-rc.0", + "@umbraco-ui/uui-file-preview": "1.15.0-rc.0", + "@umbraco-ui/uui-form": "1.15.0-rc.0", + "@umbraco-ui/uui-form-layout-item": "1.15.0-rc.0", + "@umbraco-ui/uui-form-validation-message": "1.15.0-rc.0", + "@umbraco-ui/uui-icon": "1.15.0-rc.0", + "@umbraco-ui/uui-icon-registry": "1.15.0-rc.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0", + "@umbraco-ui/uui-input": "1.15.0-rc.0", + "@umbraco-ui/uui-input-file": "1.15.0-rc.0", + "@umbraco-ui/uui-input-lock": "1.15.0-rc.0", + "@umbraco-ui/uui-input-password": "1.15.0-rc.0", + "@umbraco-ui/uui-keyboard-shortcut": "1.15.0-rc.0", + "@umbraco-ui/uui-label": "1.15.0-rc.0", + "@umbraco-ui/uui-loader": "1.15.0-rc.0", + "@umbraco-ui/uui-loader-bar": "1.15.0-rc.0", + "@umbraco-ui/uui-loader-circle": "1.15.0-rc.0", + "@umbraco-ui/uui-menu-item": "1.15.0-rc.0", + "@umbraco-ui/uui-modal": "1.15.0-rc.0", + "@umbraco-ui/uui-pagination": "1.15.0-rc.0", + "@umbraco-ui/uui-popover": "1.15.0-rc.0", + "@umbraco-ui/uui-popover-container": "1.15.0-rc.0", + "@umbraco-ui/uui-progress-bar": "1.15.0-rc.0", + "@umbraco-ui/uui-radio": "1.15.0-rc.0", + "@umbraco-ui/uui-range-slider": "1.15.0-rc.0", + "@umbraco-ui/uui-ref": "1.15.0-rc.0", + "@umbraco-ui/uui-ref-list": "1.15.0-rc.0", + "@umbraco-ui/uui-ref-node": "1.15.0-rc.0", + "@umbraco-ui/uui-ref-node-data-type": "1.15.0-rc.0", + "@umbraco-ui/uui-ref-node-document-type": "1.15.0-rc.0", + "@umbraco-ui/uui-ref-node-form": "1.15.0-rc.0", + "@umbraco-ui/uui-ref-node-member": "1.15.0-rc.0", + "@umbraco-ui/uui-ref-node-package": "1.15.0-rc.0", + "@umbraco-ui/uui-ref-node-user": "1.15.0-rc.0", + "@umbraco-ui/uui-scroll-container": "1.15.0-rc.0", + "@umbraco-ui/uui-select": "1.15.0-rc.0", + "@umbraco-ui/uui-slider": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-expand": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-file": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-folder": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-lock": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-more": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-sort": "1.15.0-rc.0", + "@umbraco-ui/uui-table": "1.15.0-rc.0", + "@umbraco-ui/uui-tabs": "1.15.0-rc.0", + "@umbraco-ui/uui-tag": "1.15.0-rc.0", + "@umbraco-ui/uui-textarea": "1.15.0-rc.0", + "@umbraco-ui/uui-toast-notification": "1.15.0-rc.0", + "@umbraco-ui/uui-toast-notification-container": "1.15.0-rc.0", + "@umbraco-ui/uui-toast-notification-layout": "1.15.0-rc.0", + "@umbraco-ui/uui-toggle": "1.15.0-rc.0", + "@umbraco-ui/uui-visually-hidden": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-action-bar": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.15.0.tgz", - "integrity": "sha512-O0807+bWVWV/rsFihFVKSOkg9wBtLXKCszE5+eZk2KmONm93BFhIAE35rp7eD6X2SuJMHwYzInIxMIMjHzdpUQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.15.0-rc.0.tgz", + "integrity": "sha512-hrAIlv2MEg+BcgxLg0H1b0hsyfGjiLNRAiHXf9GUfDNb6RZs9wCEgnI88vU8pfnTIRkfVDqewm5WEBxYwucSQw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-button-group": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-button-group": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-avatar": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.15.0.tgz", - "integrity": "sha512-eEX83zwRN3tCiHScKcmkROWAfLu3TgFI9SntlbyxiuSSYfhJxWSZXOf6lVvQ/1CyvKq8XqSbBnN3VKXgcaKOpg==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.15.0-rc.0.tgz", + "integrity": "sha512-DbisxrMnN1Z2yV+kQduTHu3Jw6gCRQlQLt/H5GQySNek1zNqaI0M8yeU6CHZPis+DgZoP0MaFRXyRuTqOhe2iQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-avatar-group": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.15.0.tgz", - "integrity": "sha512-CGYAFAHgNoQK2UTupP7pO0mwP6t9/Ms6WZ0gIC40a+kPjrGtaDWU52hiPsuXrUcR6WjJwZ5WRrJHOboRpdmM0g==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.15.0-rc.0.tgz", + "integrity": "sha512-tetsqYKGEv69RMRpeamAVzNQMP77Ty7NIYaRBNfhsyAoYCE2uL1DxQsqiUzv2Ve2dDmRM5GOrWD4zxhrFHhoiQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-avatar": "1.15.0", - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-avatar": "1.15.0-rc.0", + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-badge": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.15.0.tgz", - "integrity": "sha512-9aGmhRvey98kcR7wfsnno0BNftIRwJ0r2lCH6cNK2lhe69enYm0MWjp+4uutnlEWWskTLEI344BOqmqOHH1NPA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.15.0-rc.0.tgz", + "integrity": "sha512-VFxMixI9AXu2FlHlY4djnzURNpIAYjCvgfgmZG81HRbfgtSsv/nCS/l2dC5Y0/oDku/yDkF73ZqeosQAOREyQA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-base": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.15.0.tgz", - "integrity": "sha512-0vtKmjzUOn/tIUHNrsx7aZpy3eq9aRKqV9kkJTrhH92S4WcMy+cOB1iw9t3Fe3xlBPuL3JpszwuxMTIuIqJTgQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.15.0-rc.0.tgz", + "integrity": "sha512-xj0NMdQ+dVdVvo4Y8FAFYYtVt84T/KkzVPi+jSsgt/n0pWdfFd3f13cYiUYehNcS1q+rZxXp0ECuxnoi9GTzQg==", "license": "MIT", "peerDependencies": { "lit": ">=2.8.0" } }, "node_modules/@umbraco-ui/uui-boolean-input": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.15.0.tgz", - "integrity": "sha512-LkYX+p44mFVdvlZSliP5ClMcyHoOIVLWI3WVkaMLQdNi2LO9bbfaTneLzu4ruW6v0iF+kLsznr3bl73VHk7oEg==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.15.0-rc.0.tgz", + "integrity": "sha512-BVQVhEdOz+YJQQ0iFFJqDpW8wvsa9423GcIa0x8QRj7KhDgiEcbwNM3eHblHYkmKXFYVd250/MIB7UurY5IycA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-box": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.15.0.tgz", - "integrity": "sha512-MhSNcKsVNymD/yt3NFXujuaQmAqMqj5S+CBoDHEk88H7Id9NMw9RStZFJ37mI2CxHWkeHDotNVgOhSBiHJNJnw==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.15.0-rc.0.tgz", + "integrity": "sha512-u9RxTBDzbggQu6MHNFYSRU4siMLeMO4y/O6jbxRd/8mPViiT14yobY7I1d1wOYbgevoltJrtHqhDOjIWj+x0TQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-css": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-css": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-breadcrumbs": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.15.0.tgz", - "integrity": "sha512-TaUY+hNB0VIwv9SBi9fDjIFRtrmmkcT7hlhLCJLUVfQ7jJlGLPISAAdypSplNeCPthYvP1cJQ9m28OzscXHZxQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.15.0-rc.0.tgz", + "integrity": "sha512-3hAq5GbnIbf2RfCbfW59T5uYm6nX0Zobp+VWtGb9388FhhkZuSQdn2nuN33VjmMwvVkTvGWcuqww4ii+XoSaTg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-button": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.15.0.tgz", - "integrity": "sha512-3Oaqj6Yta/Q/Ndme20YA1XbHdBBL71iNhpqREfTHli2YV4TEcgIiNy0s2op2oPhKjIEQPEfitU2BrruYEEWa7Q==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.15.0-rc.0.tgz", + "integrity": "sha512-5YAmsYyQHzY8HBbfZpK7ekrLQKm90Zuq/TpcOuWGCe9h33T97CWJ+ekcNzpFWBhDXKPfcV22wSapnszzsPxI4g==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-button-copy-text": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-copy-text/-/uui-button-copy-text-1.15.0.tgz", - "integrity": "sha512-MAaJzpwVnlyGJNvLv6qIwrYsI5SaXXiVKgVi47I8+x//QmnArmetCN04766gGzmAb0m2uuC3ht0BXMDv05pxvw==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-copy-text/-/uui-button-copy-text-1.15.0-rc.0.tgz", + "integrity": "sha512-HeV6yEZ6do7JkJfDLTZqD1Z4EHuev65KFx3JVNHSg+fDfFQgs1fcM4Hrm7wBUsOLcIknvislCs8UumypdGeIBQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-button": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-button": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-button-group": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.15.0.tgz", - "integrity": "sha512-YPEnubKNbKmw04eWRH24/3Uxu+zhtLPeJoaT6ykPCyjr/EKc82rSTvn8fwQuP41UokQrXOac2pKn7SncyoST1Q==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.15.0-rc.0.tgz", + "integrity": "sha512-C8goOUkPe6LzVJbkeIIMzEBpqt8rkqGwpLMxYnEnkFx5HW+pQK8JHEivpGiznzl3mGLglPZC/WxnTtKuNb9ZYg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-button-inline-create": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.15.0.tgz", - "integrity": "sha512-nLJZ6P5eK1rYgqjP5zCxbZp8g4WJ23RnUZQ49o7QpU/7zoPOK72/fuM3Ky00Iapixm/kAD6dYHO/P+GtNz8/CA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.15.0-rc.0.tgz", + "integrity": "sha512-4TOly3u5cWBJFBJZvtNkYNM0pnuiEz2u0kRQhrXOhutXH7jJ19yxSrAg+KntZDGalyd22a5nv7L3+P6kTiLibA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-card": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.15.0.tgz", - "integrity": "sha512-pNjpk2iIdSsmTtDdBsWaEr8JX0RcWbl8yKGaqLvo/S7d3bly5z+FjcsgGnX1i1GHo7dqmgVJfbdvN9V1jgn+FA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.15.0-rc.0.tgz", + "integrity": "sha512-A/sKTH8BxtjeEFFp1ou8v9TNBCw2jkMdXly3Ps+TmQZW/I0/bfZoRMOhHqLU+QyfF6/JH4v+IruVtcjqZJizMg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-checkbox": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-checkbox": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-card-block-type": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-block-type/-/uui-card-block-type-1.15.0.tgz", - "integrity": "sha512-cWag+D0XrogYZesAN8NMPQCCuU7L7uZ4Xz8dmirKQk1gjMrFDC4vYPZRQ/5O3ETTFupfDipVKimgRDsmarbLSQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-block-type/-/uui-card-block-type-1.15.0-rc.0.tgz", + "integrity": "sha512-KZtZof1Tuierk9ztnoYcSqbtwFevBCYYnv4poTaoRTwoigxN1rK+aEdVZFejmHg9Jn6BxV6RIHjDI1P0+388tA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-card": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-card": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-card-content-node": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.15.0.tgz", - "integrity": "sha512-DZ6JYNvGb5wVkhhLShENMm+Y6kTpz37YrApQTJVUUgPXhIABO2CDCnqgpH5tkQX73s9jjVB3Ca7SeivuYv8G9A==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.15.0-rc.0.tgz", + "integrity": "sha512-Bzw4gH+3f/gCVJZIV9+V7tzQrqIVUUy7Y44ZsMunwcSWUKldrKLfJvwkG2RmhrUmxlus8MYEJRHOEX2fQqJ4zQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-card": "1.15.0", - "@umbraco-ui/uui-icon": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-card": "1.15.0-rc.0", + "@umbraco-ui/uui-icon": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-card-media": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.15.0.tgz", - "integrity": "sha512-EzYebWCzR0wHY902NmAcTRSVSscYac3QntCz+xwSulrhzfy4copeOd1qE+Lz7FjHs+ho0IBPZol8sF4W6rK8FQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.15.0-rc.0.tgz", + "integrity": "sha512-SDrY63OyNvV3HjhAy+bNONX/cGTX+9Oe8ItlJvX/r7a8qN6j1QaoechUXCVDC4rlAwpaiyPILQ+hPs2eizevzw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-card": "1.15.0", - "@umbraco-ui/uui-symbol-file": "1.15.0", - "@umbraco-ui/uui-symbol-folder": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-card": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-file": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-folder": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-card-user": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.15.0.tgz", - "integrity": "sha512-oo7gCs3RGJ4ujFs+LpG9I1DS/XSNkz9gaqvp4BkaR0kBXzw5f2SLLGhA9S3M6M+OPlsXuuJNKlTV1tn2+LF6Ng==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.15.0-rc.0.tgz", + "integrity": "sha512-19a9edL1zmwK5ufyV15hYU6k5aWcLTf6YCOqjcZsnVZfZTpqu22pnDHH1eA5KYh4usGFIG6fTS5dQh1b/o7y6w==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-avatar": "1.15.0", - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-card": "1.15.0" + "@umbraco-ui/uui-avatar": "1.15.0-rc.0", + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-card": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-caret": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.15.0.tgz", - "integrity": "sha512-cnKP5GeaI028hGabVCki1kPqAVSekFeP7QEwu7lncA+dcX8uvg+ffV6kW9FV0emOhI5Tmxvh8o+UDKlLs28q3A==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.15.0-rc.0.tgz", + "integrity": "sha512-ym+6OpksGsJDL7TkRtnvnGu+1kq6VOyxKlvYR+1pqATQfU61t8DBPTuZXYdyiXLKkh5iOSxmxnoq7jIYi89VSA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-checkbox": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.15.0.tgz", - "integrity": "sha512-vPkgrFAPDMvJdJTADIWNj48D8gJWD3dBotucUghg/wHhvJv8h/2MvnwMUNnnSB1REHbanl7hJBVvKcNkoil0gA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.15.0-rc.0.tgz", + "integrity": "sha512-vCXJi1x3HGr25l1BubJcJJU6XN+Mw7Wlq1sCThS5MBBDi/SaZojV0Xpo5EwREnf8kNn2ozKG5qhKCfHLptO0QQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-boolean-input": "1.15.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-boolean-input": "1.15.0-rc.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-color-area": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.15.0.tgz", - "integrity": "sha512-k6u//b+s6UYmzKYMizIf2MRGD4kFy1qWdSk1GnIeDdiQxABJuBZEtkACIe66j+lxnonFvZ/assbLbhRiu15ZCw==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.15.0-rc.0.tgz", + "integrity": "sha512-MB0iM4pCVEs3JCBHMUa4Zu9AQJt+89JkZuTHzOMJKaZG31rWx4Jm5BzLazstnxRTkrBsY3IRq/PSnU7bT5jXUA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0-rc.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-picker": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.15.0.tgz", - "integrity": "sha512-I4KGyzZZazjeifcavHp7qnMbP0Jh0dM+gzZhV+YtdPR2JT0o7y6stkbY0f+dOln0K6Bu6BQLV0HLHl/1f/1NDg==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.15.0-rc.0.tgz", + "integrity": "sha512-Qxd0jRZtCkpoKkWaNLs9zGqqynXLA57XDDz3BpC/KdyUDL9Ab8HDUdtZJdTNla7+Paf2kZ0jqINClas/0AiWaA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-popover-container": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-popover-container": "1.15.0-rc.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-slider": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.15.0.tgz", - "integrity": "sha512-lpT9kapypGkTelG9COSk169VKs0MSiKweX8menDDn0p6I4RfKQBy0N27HecCcf1RqPsCnTbP3lPr5DJy00KdzA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.15.0-rc.0.tgz", + "integrity": "sha512-gRKjEEB93OBLxkkq8rnix8Ve5hIIHkjgsO0EoolEHUNx0R3E9nlzc0fkG1xdht3Ifd20CFQS7PsQ3ciJjUvQwg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-color-swatch": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.15.0.tgz", - "integrity": "sha512-1AI0QMr046fKc8xZ4aBO7FDwvggsS9plIpY0W4AGrqQxqGUR2u/mTU49+8xMtboaFOen5RQpJ65DN9hAgeNZ+w==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.15.0-rc.0.tgz", + "integrity": "sha512-LuyExHAC9nv2gK1sd4QolUreAAvqfNzQR1iDggfRqx9RG+X7yXaxssDRZ0L8uL7ga1sefYSQlYO0L28e2hpLCw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-swatches": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.15.0.tgz", - "integrity": "sha512-UzlgWdsVHyCM/znFThrfA4A/S/K/R9Nc2KyRYiyy2xgBoP7x2vJ5Rn4mnR02W4bhI3gNgCJ2fqhmyiW4dxyk0Q==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.15.0-rc.0.tgz", + "integrity": "sha512-OPT9M21/5dHxEMXdxMH6Vum5XDPhSqCgJ81OKvXk/KfYCMXdh8mfkOu+EqchKL2bgDsAbc5eaqk5aLqTwVF+hA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-color-swatch": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-color-swatch": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-combobox": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.15.0.tgz", - "integrity": "sha512-CKslvVRCKCReMr/ZZh4wc3TKJNvFjKVm/hSIvFqCIoJuSKfC4XuLU9SK9FL1s42NUAUmccSD3hATZJZ9VXqY+Q==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.15.0-rc.0.tgz", + "integrity": "sha512-vkJZT4bno93Xyamky2vM1dVh8vClX2nm7P3Vyd/drBCihcBDcijv7tRCn+97HzEXyUO5aEs4lV43niyOzsRIoQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-button": "1.15.0", - "@umbraco-ui/uui-combobox-list": "1.15.0", - "@umbraco-ui/uui-icon": "1.15.0", - "@umbraco-ui/uui-popover-container": "1.15.0", - "@umbraco-ui/uui-scroll-container": "1.15.0", - "@umbraco-ui/uui-symbol-expand": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-button": "1.15.0-rc.0", + "@umbraco-ui/uui-combobox-list": "1.15.0-rc.0", + "@umbraco-ui/uui-icon": "1.15.0-rc.0", + "@umbraco-ui/uui-popover-container": "1.15.0-rc.0", + "@umbraco-ui/uui-scroll-container": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-expand": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-combobox-list": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.15.0.tgz", - "integrity": "sha512-e8IhqU9AC5pOqXuzPzI+BDsW97Ac0u1GU/5MIJqRcBZ+ZttPcH4fsm4u8siCHbK1khCG0Vzo7HiKPZ0IuuOslg==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.15.0-rc.0.tgz", + "integrity": "sha512-7kCNzHY51hBY3YTXzCTWfsmyMMbyxPb6ClXyeUBA2DAihP/YNm73lT3zSpR9eXowppEbnTFM8NpMa3PSqu67cw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-css": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.15.0.tgz", - "integrity": "sha512-0FPJ/NHE8MSJ7vvdFp4cSWT5L73KS00bUHPyA6oiF/XnE0AfS9TzkSWObdSrU6kyPr/fybVwsycDZNBfPiyrCA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.15.0-rc.0.tgz", + "integrity": "sha512-S+fIODQMdBjfA/WNg950AvRnKfXOP5j2IZgXRb2zk5KhDLx7Hr/Zw8KICM/7CeOTnbedCm/BvZoVrZ8bCtMCRw==", "license": "MIT", "peerDependencies": { "lit": ">=2.8.0" } }, "node_modules/@umbraco-ui/uui-dialog": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.15.0.tgz", - "integrity": "sha512-iVsrVVnvBrCCT9uJhyBE7b1kXwWUUKDmimhs/TyF1SFjxWP/U0Z99QqqI1pawdad+BuK3oVCmxYOdaReWDQXkQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.15.0-rc.0.tgz", + "integrity": "sha512-j81llRkeb+cL9DIPpfI0TDxi63xdiZchNpLg59a7wI9UBgoTAdsjhml6vuNgf7x2ivmy7OF8XswP98MQSoQnxw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-css": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-css": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-dialog-layout": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.15.0.tgz", - "integrity": "sha512-JdDRIzSGGDnvVqXSIhc+5rDXMdYMO+Hd7s2hqLp+iRSn8IHISN/qT1nfFVO9LMbLdcApanl3JJ4Rru9LN4Q3HA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.15.0-rc.0.tgz", + "integrity": "sha512-0UxrGcCThIBk15lsahGGnDzJXR0QD40JfqZGkc7jMddCF/uljBn/R2Ccke1VEic6x9SiB2csPLpA9L/sIui1hA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-file-dropzone": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.15.0.tgz", - "integrity": "sha512-MhJRkVdDQWKEBvemNRD4bZCuIS0JUll1nNoPK7scA+e6vDmbv25vqPHNXGE/sIpVkChY/L+v+twokzlHn57XMw==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.15.0-rc.0.tgz", + "integrity": "sha512-37flID+ISdYZA9i1p7sVqjf6qwvrHtYFUYIh7xSuQCQPT+ftrg/db3S0lUaWJnslOGe6ChhLp4qSXo8p3ZLDVQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-file-preview": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.15.0.tgz", - "integrity": "sha512-AHKIdYLC0ga4Wgr68xtW/gG3NDqn+QhD2aus0l2n4lBoq6OAQ5aZiPwD9i1fCD7dgyjKQ6Ov9PJSaqRYQkOlNA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.15.0-rc.0.tgz", + "integrity": "sha512-sFBAUDSGV2fiLV4xdcou7t1GZKCtYTETUZW/zJf0QTAoexjlYyp9hcRw7f3IhOBbARlQvFeuoIiA5e1ZZA+3aw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-symbol-file": "1.15.0", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0", - "@umbraco-ui/uui-symbol-folder": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-file": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-folder": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-form": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.15.0.tgz", - "integrity": "sha512-4u9ZryfVBunpb0IL0+TevytrISA6S1+AajiK/PUk0JMJfqMuQMjmpnNPdtYRNVgFFIcQFQKipjT/mrHbDVawxw==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.15.0-rc.0.tgz", + "integrity": "sha512-+drFTajJ4i+Kzv0DD8mSMb8eRHMM5l8E4ucAXVpXjQ6oo8LxRemmjFoU+wq4y/xLZeYEvRXz6m33esRHjgFhug==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-form-layout-item": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.15.0.tgz", - "integrity": "sha512-fiWGeQpREnl6k+6VNHz9ixNdEmOoFNm7qsgdIYJ1jCDXBGME1mjxJOr2Eq7UWJuzQM8BeyQEcXq5SVIOv21PRw==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.15.0-rc.0.tgz", + "integrity": "sha512-IU9WiRWC7/O+YeMRPhnJ+VCx7i+gwRIdjeCmpB8LbRBspK40PBYpHn14G4parwaKHGVfOnis+BbUjWP4TTOrMg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-form-validation-message": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-form-validation-message": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-form-validation-message": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.15.0.tgz", - "integrity": "sha512-RYfwmjPkY0KumjaalLW8gkasW25Mj87YFAzJn7mAYiZigURape9RqGpvrBfwcMmGj3W2/uVuHxpAHrvweQOt4A==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.15.0-rc.0.tgz", + "integrity": "sha512-B8l/jlOtAWimDC2m7/pZjnZS/rVNayYVivwsHKnQn/KN0XQ2nyYq8cpYUA1XZ+ZqDbS/0BP/UUZIC3Fx4n4Eng==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-icon": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.15.0.tgz", - "integrity": "sha512-e8/W6gu6kwrodH0f0U70LR5rHQhiZGq3NqLqikAQ1rvmwitXUqtkVXIhkGxSf7M6yPhpmoi2qEEZDQH9cvCE5A==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.15.0-rc.0.tgz", + "integrity": "sha512-x+HjEO92m4D31Xajzet7XwmAWDNim0XMn0IDB/qxHVza3N3ciisaMiqQ1kx/196RTcKFFWVOT6d2UMwPxwS5eQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-icon-registry": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.15.0.tgz", - "integrity": "sha512-nIdzCqoABeRVG6jW045ok649MiAhm5zPdfuMKc1a+TNw9xkKj+vnA1YcjaBN502+AekMhhwnqgj9mLL+mC2VPQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.15.0-rc.0.tgz", + "integrity": "sha512-/iNgSrVtXUQzwYRLjAI3XcIcr0EnN00trdOFCGd/2TnEhR1QOxNHIw/0FvSqjDder1y5gYFwLregle0pOvzkow==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-icon": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-icon": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-icon-registry-essential": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.15.0.tgz", - "integrity": "sha512-llHFVMlV3Uyg2fHiNt1qfDgRhLthD37uQD2FzlQb0GEYjp+4dE8Jyc/eZW2mqABPweUJACVwbrwBUVrCeQJ1OQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.15.0-rc.0.tgz", + "integrity": "sha512-sj7R4u1DYXOHpjeYnlJPA3qjdp4SZSen1/XUdbQxouANcI5a8ZCVfg1+7WIvYWIDBJ2c4VMabGkZYkAvpgLanw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-icon-registry": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-icon-registry": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-input": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.15.0.tgz", - "integrity": "sha512-vPc4I/kkQM9RWfHI0F/OQhoTu+KefplbQp0JEQ4gfr6MwxIm6bBTEuw8T5K9t1DQs8EZ7yeLEsSh65FDPepRtg==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.15.0-rc.0.tgz", + "integrity": "sha512-UeoW+WzqfR01kDqgDDsRX+N7ELujghXqDoOx364kJjlwfiemh+58490bujbOT7a+AG1LDNsV27px0OJBpNsErA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-input-file": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.15.0.tgz", - "integrity": "sha512-VVn2FMsflvEWd6fOX0HQ3JaUh7haznqSqCLTSTOduh/H3jE+dVYCW6YC5uTsxArmOwsSBYSfBQNetW23eJim3Q==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.15.0-rc.0.tgz", + "integrity": "sha512-NNbOzLtRPeWnzJoRqLP9BKyCrZODsuOeJuFKQUUPo6NuT2bg1SIu51PHdRcO8a709UDH/lB3wBSuwt3Be71TEw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-action-bar": "1.15.0", - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-button": "1.15.0", - "@umbraco-ui/uui-file-dropzone": "1.15.0", - "@umbraco-ui/uui-icon": "1.15.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0" + "@umbraco-ui/uui-action-bar": "1.15.0-rc.0", + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-button": "1.15.0-rc.0", + "@umbraco-ui/uui-file-dropzone": "1.15.0-rc.0", + "@umbraco-ui/uui-icon": "1.15.0-rc.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-input-lock": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.15.0.tgz", - "integrity": "sha512-AFyVYNeExHXe10b3/5/BLZOmMKyMxzftsO0HKbaQQuxrxL2SCHsQJRUpxSY+/0vAl2JbNdmrk0HTsP1O4Y9zig==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.15.0-rc.0.tgz", + "integrity": "sha512-CJKssXf7E8szjGRXghkyHRMo8seyXq9jxrumWyxxhJCHGOXsGecIREc1oAd/a2C+BfZzdyykGiOiJLZoJRURGw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-button": "1.15.0", - "@umbraco-ui/uui-icon": "1.15.0", - "@umbraco-ui/uui-input": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-button": "1.15.0-rc.0", + "@umbraco-ui/uui-icon": "1.15.0-rc.0", + "@umbraco-ui/uui-input": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-input-password": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.15.0.tgz", - "integrity": "sha512-Pe8lNdHz/6IfbQyWEi0o+pKJ6/zunQ2b8HARCU0a9HFXRDk+XsAuBsn79zQXZl5MvseAUQrnouLwPHpdtMbeMg==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.15.0-rc.0.tgz", + "integrity": "sha512-H0G6xtLeWE1z8hi0cgMA4DnE6ay84Z4y2vtb5R9hvS5oocMbpybjOwaKuiV3H4qam/CUAhGtRnTqP0cEWqLahQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0", - "@umbraco-ui/uui-input": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0", + "@umbraco-ui/uui-input": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-keyboard-shortcut": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.15.0.tgz", - "integrity": "sha512-8Q/G5Lg6949BbMHQ1BhZ9UpoJjOQ19w1tl2y0d/rP3w/mKnTQaBSf+MQmA/6kQ/Unb2wHXJANr4pAGpUklOg6A==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.15.0-rc.0.tgz", + "integrity": "sha512-mR5SWcf+U01aJfNxtgTZxYJQ240MtxnfKNo7C/7soxLnTd1w0Pp7KRHkB6GgKlqTx0X4Umcdu8kn35cCOkoDtA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-label": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.15.0.tgz", - "integrity": "sha512-fnmRl+RGUROERvt+Jw0WiW3Btlddg0Xka6F+gR95gy5gr/v8s34uf1/bbPD3hWUXZPukLmxeMjbzyuqMrO8rpQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.15.0-rc.0.tgz", + "integrity": "sha512-P/wuJift88Sd7fq/BASMTb9JmqpA069GttPxiIoCwMb7zt+fX+xsjjzPHiD1FLihVPUFdw9lIq6d65ahbrDnMg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-loader": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.15.0.tgz", - "integrity": "sha512-HQ2zCp2kz45GWQ3wV153ytuYD2KcdeAA5RRUVrN0Zn3GQB3wfG7xMkQQNRAOWMUdnfqmdQHeK+COO7NaET3VBA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.15.0-rc.0.tgz", + "integrity": "sha512-XD8DsEIQhVVnXtAFNVHwH9v6ysTyKbSpHeq9pHFWmupCpqvF1i0fBRYLnE+nTyzq5331WyoQieWrsmYz2C8dTw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-loader-bar": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.15.0.tgz", - "integrity": "sha512-4eMeerunFc5yZsJIwpHADn8oGcu0Nn36oyKbSd0qC0mNmmN2i8UOF9w4O+lndd2L0Mhv23FGvBRo7mb5EAvWlg==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.15.0-rc.0.tgz", + "integrity": "sha512-rXH8dEagrmiWZHgdHfb7Er3FsA93ZBrvF/KF4tC4Jw+2xZC+tw+n/7yAKcWM8JpCphGaIl2e4BqoalNIazmd8g==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-loader-circle": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.15.0.tgz", - "integrity": "sha512-4rG8UHvyS2qvsjQYEmYjKX01SRwfk60oH8SSSx8r3z2BM62dCOa+4SBhLxqiBciC/u8FtN8X20MIGE0+eMdtoA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.15.0-rc.0.tgz", + "integrity": "sha512-JfjucJUjGMD9yKgOscYXPOY0KN9ABbmMTwOQTzWzWAPvY6P8/OgGUKrGAQAnZzQ2Qqcl4/MMGuN4L5HX5YC3gw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-menu-item": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.15.0.tgz", - "integrity": "sha512-BOebCMB/p4TaK4kJYrYgimC6SSGBHN4y1MytK3tyvObbuj3gVqkbwHW5CZrhK4jMaywRgGq96OsuaGfc52HFog==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.15.0-rc.0.tgz", + "integrity": "sha512-rGe/GsgWWyPZiRw0vjW7T1i00x3IKt502ESADdfK/ViF8rE9JgVIDvwCGvYHvbDPfVQci8YsQYS8I4VX29z77w==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-loader-bar": "1.15.0", - "@umbraco-ui/uui-symbol-expand": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-loader-bar": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-expand": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-modal": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.15.0.tgz", - "integrity": "sha512-EDz1Qx+mTXNvOu565IculPCyuuFHwBon2wYnfWDBMoHJ5+P54jBHzg2U/8fUVse7xKPvU21hF4JneAvycNIiGQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.15.0-rc.0.tgz", + "integrity": "sha512-cKO6BE5tWDIfiGAMM/8/6GmOTrEzVqpSfe4yVFX4AvChOlCfx0+NS2gffICzFq7n5BZ7lOKo5dx8ByuRDkIhrw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-pagination": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.15.0.tgz", - "integrity": "sha512-sPVs1bApKupNd2JcSMwFS1060Y++Fti1ybJrafcLh1+h4IjmLDIRTHTTL8C+kei5G2Oi3+Z7vGpLu7lrTAmRlw==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.15.0-rc.0.tgz", + "integrity": "sha512-NaxkYnfUSQNfXVpyQyqtFefpvA4ElBaXf+BdhwxEIYvki7qLsracZxPtLahgfxm08xP+kP5smIVSNbLsOUh1Kg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-button": "1.15.0", - "@umbraco-ui/uui-button-group": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-button": "1.15.0-rc.0", + "@umbraco-ui/uui-button-group": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-popover": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.15.0.tgz", - "integrity": "sha512-VCHVvO0fd5eL5UvB/RPL/K68UhOgsIpuyr+aXLblaYT/6at2LNosUxR4eRW2r0WOQzOiyE+Nu69pExBKyfT8bw==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.15.0-rc.0.tgz", + "integrity": "sha512-jkrJVREYar6tNG+DS01Wnqg656d6Cen2sUTYl/grKVsgLqdZPP42hzpClctlT8HdDYSj650e5JOCqSOFZiv2Zw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-popover-container": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover-container/-/uui-popover-container-1.15.0.tgz", - "integrity": "sha512-54M4G0ru8j5ltPAdDGIxogdmos33hxeQeusI/uMFxo2yqHHyMHRi95vvCdcwFmGlEdFd2rsnxZKfNMUKM99GKQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover-container/-/uui-popover-container-1.15.0-rc.0.tgz", + "integrity": "sha512-s/j+dlKjtVhAXvs7FKwjL54xlrqfWnjqjycxIABHXasrJbLJwX8oxs2iL8pk4mb4ZbdIpdA5xkRjF4eTyfT1Jw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-progress-bar": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.15.0.tgz", - "integrity": "sha512-vtGUwHaG4EDLQERkwym51OasoWLj30LQLhcCCYXDJtTL1dG2nIKScEtlSUiVh5qRsI+V+kaBYPGD4TFD5o43tQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.15.0-rc.0.tgz", + "integrity": "sha512-oYGogiagAay/ZqmDgTtB1FCjXZuaN/5Lj0TiOFwdVtIO2l+xmHwyUyX7byyt2kaZ6kGcuROTlPYn1gDvK5yRUg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-radio": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.15.0.tgz", - "integrity": "sha512-5TUF/iWUzbVXvBs9Z273q6s9yLbns8itTiFHCITw5w5fZzDn8R6O5hrOW7tV79kCxAnBSOAVP8v1JhGTwXw19Q==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.15.0-rc.0.tgz", + "integrity": "sha512-l/+QPKyN+9CiDhKxOfmDnbpXLO7rkLM0F8AL+fy/Jjp33NC32blQYAkYV+Ayv0H898nkZBrcpA+tvVGkoiHKeQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-range-slider": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.15.0.tgz", - "integrity": "sha512-HMHVdBoB1O39rojofezee2aXGv6CMn7dUFvNefdF9HxmNrIcpFBYXSL8aBt5QJeziFQMwbCtqyY21aUag0nzfw==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.15.0-rc.0.tgz", + "integrity": "sha512-P8+e+JFlEhsZHntt3XVwKQkNvluIVqnlLM3VYFlOeqU+3pgsDIat4Tm2YiH23Cd8dCI0G5eLlmqVLPvwQjhhDA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-ref": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.15.0.tgz", - "integrity": "sha512-w7FZIe5mtsgvsf6hOH5mHKDBzg9Rd/+viyk/xNVs1NeZBn1nWEIHZs0R7YMpv+QxulklhAOpBcbGoUTB8xE+vA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.15.0-rc.0.tgz", + "integrity": "sha512-ZQ9U8x2ypxWqFFFDu3vjXPahUbr7TmGKUSBwDai4HPdLXOQqoAR5Fc0NOYxx4fc9yq5NQ2hczK1hd71V9ST28g==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-ref-list": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.15.0.tgz", - "integrity": "sha512-UT65bpUmRlEgVuvn2RlTZ5l2WDF82jH1t8g+6HV6OJctpqTKlOfPkQmd6AluESPhHFEwwTydS/M7x+X3Adkdtw==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.15.0-rc.0.tgz", + "integrity": "sha512-th86PCdgzsaIwtjLr8AccyvHYhpoRKWVDjDEcFkfpUvbogSI8u/0fSmkaNwUjtCehoRT/HCDj9we3Yn4A10xUQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-ref-node": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.15.0.tgz", - "integrity": "sha512-ybDqIt1cXd7AiZLZsDrSHCMp2zM8I+0lmN599b3NROjm59SZXIvpbY1TS1gJ45htgsc18x2y+S4laInYu2dGUg==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.15.0-rc.0.tgz", + "integrity": "sha512-kw56OWmUdd2sFWeYBjcKaE4mDuLFjKv7JImwIfn8LYtZ/uTcwsdiGOQf6gQtNbMVtW5FMjJQXBFCagT+HwW0RQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-icon": "1.15.0", - "@umbraco-ui/uui-ref": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-icon": "1.15.0-rc.0", + "@umbraco-ui/uui-ref": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-ref-node-data-type": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.15.0.tgz", - "integrity": "sha512-59s16558ySCX7b9IT/Sorq0fdFeCRENSTa7DIkQUrvVPaFWqKFz9jCYFEqDnH11jZHGsNiYh5YCmWlF/VNbwJQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.15.0-rc.0.tgz", + "integrity": "sha512-ZYNoUVBPmuxYM3obWfuiQNJCAEv7csDMpiQJ0Eaf3W3hxm6i1HxTC6V4NajO38zFVBsJjCaXzqgESLPtN1DS+g==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-ref-node": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-ref-node-document-type": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.15.0.tgz", - "integrity": "sha512-AWPZPkFGcAkRx4j6JnOi2r3EJxnvZUXfhOWNyWB2/dFRckatPH56+lVkqV+fRC+81emKBSQWkx2NphFzLEMr0A==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.15.0-rc.0.tgz", + "integrity": "sha512-ZEtyl+n/IkSflZxLwhKBGTMJYndJPHBGAqijqAajDWpBYrum/bxu8bYjE+oVkRRMHqQgCm/q6B4qTrX0qsPWfQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-ref-node": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-ref-node-form": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.15.0.tgz", - "integrity": "sha512-knIIbbfoWtepOvyC54dCo3xF0Vuap6i5uMQPd+wITCmg56a+yiJFuke+dyzatOIeXzgspLgFUngwQZEj5mJnWA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.15.0-rc.0.tgz", + "integrity": "sha512-cQER0tdwAGSzyO76RDDj/aoIDC3rLv3EobpL0BeSldYfgFQKfyS+96JthQkDytJP1RC8kJdQ8J5/QM2Z+QTDnA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-ref-node": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-ref-node-member": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.15.0.tgz", - "integrity": "sha512-pXvL523m2JR3P8OO+E1AE4YAaYhJLc519CtjNXSuctNIk1yWvwxBu8VozLIQV+xrOXGz+SiXwDkoaRPwjTQKtg==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.15.0-rc.0.tgz", + "integrity": "sha512-oOqA0Dl6Zc312Li8mLlTvIJ4MDiaMEGD5ip1plmSiNF7YxRIh+6srrPugAZQwsrU+q6JVEEul5HjgOd8Eu46pQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-ref-node": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-ref-node-package": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.15.0.tgz", - "integrity": "sha512-bQWfZPKJyAf2O/YvOD6fVSSpKaYZMBsrEGT+ydLPv3BNJroYHS8+NEbulZxExWztNApTcs6Vo5T19AUz+vsnLQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.15.0-rc.0.tgz", + "integrity": "sha512-oXh030/wLZiU/9TBEfHvoGHXCRDcI43oJ0x/Den4S2U1Fc+5U4Y9F0LvA3611IL2EqUa3ZA0tQJLzAt6kPbpkw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-ref-node": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-ref-node-user": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.15.0.tgz", - "integrity": "sha512-4GpRzhGedMwjqW1Wk7AvgakNCc6S1edYpHWeO6cfmryIm0hvnCfkU132lzLmB+Ag2QIOI8p4Ak0OQHYWd+XZHw==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.15.0-rc.0.tgz", + "integrity": "sha512-KqFQAaXGdf3N+RLj3tuU0TFeedNANT2fr6dRuVysEL8hKIpjkCKdNp4PCGePY1BR97/NVLNnXXuG3+Ccued3tQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-ref-node": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-scroll-container": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.15.0.tgz", - "integrity": "sha512-L4qM6GPDqu0/9B2OVb3EljZT3zYxbwp6uOz1nfVYpGAWBxd6INOtNbn8WYdZLq6qqa8NR6qK+su2554nInvQGA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.15.0-rc.0.tgz", + "integrity": "sha512-KfBdFU2zY5IfeNUMreCwHfWw0HoEPx9+2pbmc7UCPgg7SjYMkBNa8sce+bpc/OoUUpo9zbbvNjqF6eyXqeVwGw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-select": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.15.0.tgz", - "integrity": "sha512-yRx+TlXBB05jM8ShThRooFgCS5nSN7eAAnpttZgBWqY3sccIVy2Knbkz3kXLJE6ld+bO5nUXhsZBZ34MEHkiog==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.15.0-rc.0.tgz", + "integrity": "sha512-IORtMOqTy/1+S6a7QRqg8LKgqRX4jLsQkz1J2PK2DtuKceX/tO5HmE+Ec9cTVSFBlDFE95uek6VEsGyGj5oGMw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-slider": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.15.0.tgz", - "integrity": "sha512-+OAzOutyUB2WCI+e5aFRoUNsFFuc/hUXnpIjx4P1moOYiggc/NxjaTHz5mxbmkC11yyS+0vpl8lVSZglkLCH5w==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.15.0-rc.0.tgz", + "integrity": "sha512-CifB669wtpHvTzG9d9jKj1eVB9ePeJSO8L4DjNSCaDyvrsYxDpZYzOBQuaIpPRXwdGyznFSyOAb7d8renrlpBw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-symbol-expand": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.15.0.tgz", - "integrity": "sha512-6y9rpFfhtuWMnaAamlzrB5Q12dsZ8dprmQaGtKr+g97PTNRPC3/dc5sdROam8VMDAhL9MkfBAZBoS6yAoJsPcQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.15.0-rc.0.tgz", + "integrity": "sha512-GQ9SMmMVJ6b/vAMa22QVJOTRn6uFdu9IELRtwrBNDgywA5L+TG7MyJ4ZgKXc1DwAKwVXwlS0qTAWBis3z1CZRQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-symbol-file": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.15.0.tgz", - "integrity": "sha512-F0BueWxu6J5P7xyzkp1c/eFZJjStsw65hB3bNEmWBOqkm/jbBKg9+Xs99tov+VwCHYOt8T+DuEDkkKmdxVAxyQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.15.0-rc.0.tgz", + "integrity": "sha512-8FrKoBzm1YKM2L4dpNG9DjqrQZ/qnUfnx1oLzohxWZXKn13dxS7XdDFkn9B7PPgcxkxPK5DFR2Y8H0YQCTPEIw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-symbol-file-dropzone": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.15.0.tgz", - "integrity": "sha512-D5DottbukIFxL+YTVEMujHPdqB8Hhw02TKpegfDQb8UGSPC5pCQw4O212TSuyTalKb598niNmCzcjEG5TWNqww==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.15.0-rc.0.tgz", + "integrity": "sha512-89og/JhpHbcQj2NuKnbJJBKKCvUWnixMw+yEDU6K4rQ7gOEWMUiYgEI87rfpp4tIRp4pKLL8jTDrvu6I1rS6jA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-symbol-file-thumbnail": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.15.0.tgz", - "integrity": "sha512-JLcEVnJqv2LL8VtscPCtPKda9ywWzV4vd0XODHLE3iI1cgHeNwMBhxqgkah0ULuw5w2Hrq8gwQ7/DuPHMSIFxw==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.15.0-rc.0.tgz", + "integrity": "sha512-LxNSR/v8NnAs7iyhDBy+ylf8C1OxxIelm3Q7/6ko474wsaBfQqwfJUbmzqCmcQhoptDZia0VxjWB80Sh5OtkAg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-symbol-folder": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.15.0.tgz", - "integrity": "sha512-CPsr1K5IkdxBgID+xoIcgbumm/z0q+Z/1NPxTO40EL7kx3KOLQ8vwLdOTSW1cTj90JFA9+XuRtOpmMEY0XjICg==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.15.0-rc.0.tgz", + "integrity": "sha512-OqMe0IKp1qIhyQJ3Yw0CMcEt1ciuO/EnoUPtdeGUGLZBfZiTEkXoxBc2Yh/6kBLgySDydD+Ddaa1gIYuMpM3RQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-symbol-lock": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.15.0.tgz", - "integrity": "sha512-5QyDNFjiBeuPgalT9zwPMP220zJUHPpbPvCohWCFLn/2JJsa6IjSMtsAcqxI154ZJ9vYX7vYiYUn8tJTY8CHpA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.15.0-rc.0.tgz", + "integrity": "sha512-U0hU0MAZGA6eYz5lMxKajwsEQnUGFGaDgeE6cnJBBManrlT24RmDSFmr7MlW2V0yTYOrWJOCv/P/RPFvZBNuXA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-symbol-more": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.15.0.tgz", - "integrity": "sha512-BQq7BwZ7nCcgKE5tMhG6OVYTrrMEIXpx8kQKec/ULgVfs0/Ws6qeH9u4rGVK/yHU8gecd6DSeUczjjq2iS4djA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.15.0-rc.0.tgz", + "integrity": "sha512-BJ264C8xpe92a9Rx2sDirpS1jqn/en3oVGUV4wDH/BJw+jQAgTt12LzHEjQbNNEbuQBYuZuzLnoW9UVQwyV5hg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-symbol-sort": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.15.0.tgz", - "integrity": "sha512-5Akw8T0SV2OrwvPk1JSeFr1clvHE4N0DwceSU9bn9f6gLIGGRxvniJAclQDRI/Woe3hm8waMy6cC2fXfSdc6lg==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.15.0-rc.0.tgz", + "integrity": "sha512-xj464OIL8Casqxk2S+SdmwBGn95k5SBh3Y93fZEUykZ4vFG2zmwk32chrJ8kX0uaQ7M3cg+lO5RZRk7QHBaPQA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-table": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.15.0.tgz", - "integrity": "sha512-AnPp0QJeI70ucX8ludr3qaFmlxjKZUarX10DI8ieIB8VJiQZo0TjoPcPdSGmZupaPBLiszlpb3rKzGkZhXEIHg==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.15.0-rc.0.tgz", + "integrity": "sha512-usidTyVmBgE+YYt1ITg0JQxurSAyfg6bz8Fh5FLQVS9hdUWKsRvRhJP7M+u9tSIjzv07mhIlZWBvt6GJUMjFlw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-tabs": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.15.0.tgz", - "integrity": "sha512-oS0eA5Z8+s+5o2ks3WCED5VGP8AunRLyuB2y7kVdRUfhCfck7B9v83zNfxPVoGoVsTDLtAQM1S4P8SHwNRmk7g==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.15.0-rc.0.tgz", + "integrity": "sha512-a5o7FXRpj3bAXTkyLlV7G7gn6nHlNn6uYEaSfwuk8sAAfcF84hp75OWLJuNrbIaH6IOblgn4FNBL01GgdAB0mg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-button": "1.15.0", - "@umbraco-ui/uui-popover-container": "1.15.0", - "@umbraco-ui/uui-symbol-more": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-button": "1.15.0-rc.0", + "@umbraco-ui/uui-popover-container": "1.15.0-rc.0", + "@umbraco-ui/uui-symbol-more": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-tag": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.15.0.tgz", - "integrity": "sha512-PgyZvAiOZmXmiRW4UhfD6Tybx3ft755aKAVqT8ELpskLSvVr1oz4uTI6+QxoeQ1AkrHovenvIdBX+Iwi91SheQ==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.15.0-rc.0.tgz", + "integrity": "sha512-cnOEKEGM5BlpDEx4/Fz2o0D2n4o7si87A9UHMPbiDKFNFcJ0gfitwn7eJGn0EZs8C2GLti9wvxv24oUDJ5Hd4Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-textarea": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.15.0.tgz", - "integrity": "sha512-tk/RVzCxs+KPSJ+qH2Xlr9RYxcdrSNulDKk5sBCQR0A9nwOffa15SGreSMKWgq+gYOVYChHBg/WxLWLq3d7Rlg==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.15.0-rc.0.tgz", + "integrity": "sha512-J7+CFi16wJWMYpQ+c4VLQdA/bpDAIt6USCzoT+Rs+UYFcJKOHI4eEBxQknA61SZMbhcn9hXHI2FrIeR+2/S6GQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-toast-notification": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.15.0.tgz", - "integrity": "sha512-nz+snpjPFE+ftH5R/ekgZYy9ofGAf51yQYjWCtBwkrQ6D1dIBYA6kynZFdqIefrRwJJ5zHpe25BcS/AyRPc/9Q==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.15.0-rc.0.tgz", + "integrity": "sha512-dEu934tASMh4vbuzy11V7WIKrx5iMQ92j/1lw0ZHaDLHNdkpmkZtbSUKYlO66Wq0EMu3s9O5CAWRNFZJlV15EQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-button": "1.15.0", - "@umbraco-ui/uui-css": "1.15.0", - "@umbraco-ui/uui-icon": "1.15.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-button": "1.15.0-rc.0", + "@umbraco-ui/uui-css": "1.15.0-rc.0", + "@umbraco-ui/uui-icon": "1.15.0-rc.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-toast-notification-container": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.15.0.tgz", - "integrity": "sha512-fd5d0DU/x2+u15rP0wrjw29M0oqsDFmnAfbPEdgQoPV+hvq9/SLhxJtzx10ZSNXoyuO9sTK50Q7nYsqOvGCzqg==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.15.0-rc.0.tgz", + "integrity": "sha512-8fSSsBwAoflq7w9qwcKSmrnq6f5JADgzquEQWrK4RXvfvBeFXXlII14WbfYqIe3+FX4310VuPooHse1vd0UiCw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-toast-notification": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-toast-notification": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-toast-notification-layout": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.15.0.tgz", - "integrity": "sha512-uf/e/dVN6kqX76vcawiQM3w1nMHa8A+ZTtNwxtmAZi8bNPwjXLNaqKfeSp2thTByCIzFz7imnft56QtYLbksOA==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.15.0-rc.0.tgz", + "integrity": "sha512-IX4w00PwV8BMbLeqs37Yn0CGGHtGlabMxwODtICze5TkPdD64Xc9W4oPbQ/Fr5CgJdiJhb6OyeVd92cr8n2lAg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-css": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-css": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-toggle": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.15.0.tgz", - "integrity": "sha512-WLooENcxuAobbXxN1W2uKGh/cN9k0f3cRmDDtCZdgjeheGlBYWatkc5HQte7zchXHUi0xTrsvBCBa9CsLKN/3Q==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.15.0-rc.0.tgz", + "integrity": "sha512-ReMVDGO303IIM34HPArTIcVSCfACW8+4gY+fJr46vdy+XPjeZupoBDbxVrn+zMacxxF92sv7gqdabMYhBH6k4g==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0", - "@umbraco-ui/uui-boolean-input": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-boolean-input": "1.15.0-rc.0" } }, "node_modules/@umbraco-ui/uui-visually-hidden": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-visually-hidden/-/uui-visually-hidden-1.15.0.tgz", - "integrity": "sha512-vn3dbpYGekAqG944Vkwd0ILQRtTaZtL1BVdsge2UsU8sOsEKwv5YzQal4b+o8yu8nb4vZbWHZ2zRmnpnPgPmjg==", + "version": "1.15.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-visually-hidden/-/uui-visually-hidden-1.15.0-rc.0.tgz", + "integrity": "sha512-1em6yB9KuZbe14ZQrwmL20YCuEeGKNHiJ4veZ5K/Dm/x9wvsd5skw5M7vMVK+gF77dJBDuGpPLtCtp/FqgFG8A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0" + "@umbraco-ui/uui-base": "1.15.0-rc.0" } }, "node_modules/@vitest/expect": { @@ -17298,8 +17298,8 @@ "src/external/uui": { "name": "@umbraco-backoffice/uui", "dependencies": { - "@umbraco-ui/uui": "^1.15.0", - "@umbraco-ui/uui-css": "^1.15.0" + "@umbraco-ui/uui": "^1.15.0-rc.0", + "@umbraco-ui/uui-css": "^1.15.0-rc.0" } }, "src/packages/block": { diff --git a/src/Umbraco.Web.UI.Client/src/external/uui/package.json b/src/Umbraco.Web.UI.Client/src/external/uui/package.json index c18990b32d..072fb13ef4 100644 --- a/src/Umbraco.Web.UI.Client/src/external/uui/package.json +++ b/src/Umbraco.Web.UI.Client/src/external/uui/package.json @@ -6,7 +6,7 @@ "build": "vite build" }, "dependencies": { - "@umbraco-ui/uui": "^1.15.0", - "@umbraco-ui/uui-css": "^1.15.0" + "@umbraco-ui/uui": "^1.15.0-rc.0", + "@umbraco-ui/uui-css": "^1.15.0-rc.0" } } From 9f887846bcccc7edb46c7e23925bacaf39d01b55 Mon Sep 17 00:00:00 2001 From: Engiber Lozada <89547469+engijlr@users.noreply.github.com> Date: Mon, 25 Aug 2025 11:16:32 +0200 Subject: [PATCH 06/33] Allow open split view using the keyboard (#19927) * Allow open split view using the keyboard * Add localize method to the label * Add a method to localize terms with a language parameter * adjust localization wording * support segments in label * localize texts --------- Co-authored-by: Mads Rasmussen --- src/Umbraco.Web.UI.Client/src/assets/lang/da.ts | 4 ++++ src/Umbraco.Web.UI.Client/src/assets/lang/en.ts | 4 ++++ src/Umbraco.Web.UI.Client/src/assets/lang/es.ts | 1 + .../workspace-split-view-variant-selector.element.ts | 12 ++++++++---- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/da.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/da.ts index 230a936d86..999d49a324 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/da.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/da.ts @@ -176,6 +176,9 @@ export default { confirmActionConfirm: 'Bekræft', morePublishingOptions: 'Flere publiseringsmuligheder', submitChanges: 'Indsæt', + openInSplitView: 'Åbn i sidestillet visning', + openVersionSelector: 'Åbn udgavevælger', + closeVersionSelector: 'Luk udgavevælger', }, auditTrailsMedia: { delete: 'Medie slettet', @@ -352,6 +355,7 @@ export default { selectAllVariants: 'Vælg alle varianter', scheduledPendingChanges: 'Denne tidsplan har ændringer, der træder i kraft, når du klikker på "%0%".', noVariantsToProcess: 'Der er ingen tilgængelige varianter', + openSplitViewForVariant: (variant: string) => `Åbn ${variant} i sidestillet visning`, }, blueprints: { createBlueprintFrom: "Opret en ny indholdsskabelon fra '%0%'", diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts index 409190e954..d4806a5f1b 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts @@ -177,6 +177,9 @@ export default { morePublishingOptions: 'More publishing options', submitChanges: 'Submit', viewSystemDetails: 'View Umbraco CMS system information and version number', + openInSplitView: 'Open in split view', + openVersionSelector: 'Open version selector', + closeVersionSelector: 'Close version selector', }, auditTrailsMedia: { delete: 'Media deleted', @@ -353,6 +356,7 @@ export default { saveModalTitle: 'Save', saveAndPublishModalTitle: 'Save and publish', publishModalTitle: 'Publish', + openSplitViewForVariant: (variant: string) => `Open ${variant} in split view`, }, blueprints: { createBlueprintFrom: "Create a new Document Blueprint from '%0%'", diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/es.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/es.ts index bc6f603820..deee492da0 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/es.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/es.ts @@ -204,6 +204,7 @@ export default { removeTextBox: 'Eliminar caja de texto', contentRoot: 'Raíz de contenido', saveModalTitle: 'Guardar', + openSplitViewForVariant: (variant: string) => `Abrir vista dividida para '${variant}'`, }, blueprints: { createBlueprintFrom: 'Crear nueva Plantilla de Contenido desde %0%', diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts index cc06cf5222..3e2ff19967 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts @@ -324,7 +324,9 @@ export class UmbWorkspaceSplitViewVariantSelectorElement< slot="append" popovertarget="popover" title=${this.#getVariantSpecInfo(this._activeVariant)} - label="Select a variant"> + label=${this._variantSelectorOpen + ? this.localize.term('buttons_closeVersionSelector') + : this.localize.term('buttons_openVersionSelector')}> ${this.#getVariantSpecInfo(this._activeVariant)} ${this.#renderReadOnlyTag(this._activeVariant?.culture)} @@ -488,9 +490,9 @@ export class UmbWorkspaceSplitViewVariantSelectorElement< : html` this.#openSplitView(variant)}> - Open in Split view + ${this.localize.term('buttons_openInSplitView')} `} `; @@ -561,7 +563,9 @@ export class UmbWorkspaceSplitViewVariantSelectorElement< background: none; } - .variant:hover > .split-view { + .variant:hover > .split-view, + .variant:focus > .split-view, + .variant:focus-within > .split-view { display: flex; } From 2537411fc66a8e29440e211a438a294a1cee2aa5 Mon Sep 17 00:00:00 2001 From: NguyenThuyLan <116753400+NguyenThuyLan@users.noreply.github.com> Date: Mon, 25 Aug 2025 17:59:02 +0700 Subject: [PATCH 07/33] Fix issue console error when navigating to document type template tab (#19913) Co-authored-by: Lan Nguyen Thuy --- .../global-components/input-template/input-template.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/global-components/input-template/input-template.element.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/global-components/input-template/input-template.element.ts index e1ba049486..03a1dba441 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/global-components/input-template/input-template.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/global-components/input-template/input-template.element.ts @@ -101,7 +101,7 @@ export class UmbInputTemplateElement extends UUIFormControlMixin(UmbLitElement, } protected override getFormElement() { - return this; + return undefined; } #appendTemplates(unique: string[]) { From d063f344bcd37cb67803c9af75f30e5571ef0315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 25 Aug 2025 13:26:53 +0200 Subject: [PATCH 08/33] Block workspace view validation badges (#19987) block workspace view validation badges --- .../block/workspace/block-element-manager.ts | 23 +++++++++++++++++-- .../workspace/block-workspace.context.ts | 6 ++--- .../block/block/workspace/constants.ts | 4 ++++ .../packages/block/block/workspace/index.ts | 3 +-- .../block/block/workspace/manifests.ts | 10 +++++--- .../content-validation-to-hints.manager.ts | 7 +++--- .../content/content/workspace/index.ts | 1 + .../core/hint/context/hints.context.ts | 6 ++--- .../core/hint/context/hints.controller.ts | 7 +++++- 9 files changed, 50 insertions(+), 17 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/constants.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-element-manager.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-element-manager.ts index 5c401f6c37..6ac9729c10 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-element-manager.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-element-manager.ts @@ -14,11 +14,16 @@ import { type UmbClassInterface, UmbControllerBase } from '@umbraco-cms/backoffi import { UmbDocumentTypeDetailRepository } from '@umbraco-cms/backoffice/document-type'; import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import { UmbValidationController } from '@umbraco-cms/backoffice/validation'; -import { UmbElementWorkspaceDataManager, type UmbElementPropertyDataOwner } from '@umbraco-cms/backoffice/content'; +import { + UmbContentValidationToHintsManager, + UmbElementWorkspaceDataManager, + type UmbElementPropertyDataOwner, +} from '@umbraco-cms/backoffice/content'; import { UmbReadOnlyVariantGuardManager } from '@umbraco-cms/backoffice/utils'; import { UmbDataTypeItemRepositoryManager } from '@umbraco-cms/backoffice/data-type'; import { UmbVariantPropertyGuardManager } from '@umbraco-cms/backoffice/property'; +import { UmbHintContext, type UmbVariantHint } from '@umbraco-cms/backoffice/hint'; export class UmbBlockElementManager extends UmbControllerBase @@ -62,9 +67,21 @@ export class UmbBlockElementManager, dataPathPropertyName: string) { + readonly hints; + + constructor( + host: UmbBlockWorkspaceContext, + dataPathPropertyName: string, + workspaceViewAlias: string, + ) { super(host); + this.hints = new UmbHintContext(this, { viewAlias: workspaceViewAlias }); + this.hints.inherit(); + new UmbContentValidationToHintsManager(this, this.structure, this.validation, this.hints, [ + workspaceViewAlias, + ]); + // Ugly, but we just inherit these from the workspace context: [NL] this.name = host.name; this.getName = host.getName; @@ -241,6 +258,8 @@ export class UmbBlockElementManager @@ -58,9 +59,8 @@ export class UmbBlockWorkspaceContext x?.contentKey); readonly contentKey = this.#layout.asObservablePart((x) => x?.contentKey); - readonly content = new UmbBlockElementManager(this, 'contentData'); - - readonly settings = new UmbBlockElementManager(this, 'settingsData'); + readonly content = new UmbBlockElementManager(this, 'contentData', UMB_BLOCK_WORKSPACE_VIEW_CONTENT); + readonly settings = new UmbBlockElementManager(this, 'settingsData', UMB_BLOCK_WORKSPACE_VIEW_SETTINGS); #name = new UmbStringState(undefined); readonly name = this.#name.asObservable(); diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/constants.ts new file mode 100644 index 0000000000..f0ecc00046 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/constants.ts @@ -0,0 +1,4 @@ +export const UMB_BLOCK_WORKSPACE_ALIAS = 'Umb.Workspace.Block'; + +export const UMB_BLOCK_WORKSPACE_VIEW_CONTENT = 'Umb.WorkspaceView.Block.Content'; +export const UMB_BLOCK_WORKSPACE_VIEW_SETTINGS = 'Umb.WorkspaceView.Block.Settings'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/index.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/index.ts index 533b373c45..4fd2a462aa 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/index.ts @@ -1,5 +1,4 @@ export * from './block-element-property-dataset.context-token.js'; export * from './block-workspace.context-token.js'; export * from './block-workspace.modal-token.js'; - -export const UMB_BLOCK_WORKSPACE_ALIAS = 'Umb.Workspace.Block'; +export * from './constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/manifests.ts index 949a4312c6..d3ac0faf73 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/manifests.ts @@ -1,4 +1,8 @@ -import { UMB_BLOCK_WORKSPACE_ALIAS } from './index.js'; +import { + UMB_BLOCK_WORKSPACE_ALIAS, + UMB_BLOCK_WORKSPACE_VIEW_CONTENT, + UMB_BLOCK_WORKSPACE_VIEW_SETTINGS, +} from './constants.js'; import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ @@ -57,7 +61,7 @@ export const manifests: Array = [ }, { type: 'workspaceView', - alias: 'Umb.WorkspaceView.Block.Content', + alias: UMB_BLOCK_WORKSPACE_VIEW_CONTENT, name: 'Block Workspace Content View', element: () => import('./views/edit/block-workspace-view-edit.element.js'), weight: 1000, @@ -83,7 +87,7 @@ export const manifests: Array = [ // TODO: Fix manifest types so it support additional properties. { type: 'workspaceView', - alias: 'Umb.WorkspaceView.Block.Settings', + alias: UMB_BLOCK_WORKSPACE_VIEW_SETTINGS, name: 'Block Workspace Settings View', element: () => import('./views/edit/block-workspace-view-edit.element.js'), weight: 900, diff --git a/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-validation-to-hints.manager.ts b/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-validation-to-hints.manager.ts index 8dcd90539b..2811bebfa7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-validation-to-hints.manager.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-validation-to-hints.manager.ts @@ -6,7 +6,7 @@ import type { } from '@umbraco-cms/backoffice/content-type'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbHintController, UmbVariantHint } from '@umbraco-cms/backoffice/hint'; -import { extractJsonQueryProps, type UmbValidationContext } from '@umbraco-cms/backoffice/validation'; +import { extractJsonQueryProps, type UmbValidationController } from '@umbraco-cms/backoffice/validation'; import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; /* @@ -39,8 +39,9 @@ export class UmbContentValidationToHintsManager< constructor( host: UmbControllerHost, structure: UmbContentTypeStructureManager, - validation: UmbValidationContext, + validation: UmbValidationController, hints: UmbHintController, + hintsPathPrefix: Array = ['Umb.WorkspaceView.Document.Edit'], ) { super(host); @@ -77,7 +78,7 @@ export class UmbContentValidationToHintsManager< hints.addOne({ unique: message.key, - path: ['Umb.WorkspaceView.Document.Edit', ...path], + path: [...hintsPathPrefix, ...path], text: '!', /*label: message.body,*/ color: 'invalid', diff --git a/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/index.ts b/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/index.ts index 40d5ffc230..8428753305 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/index.ts @@ -1,2 +1,3 @@ export * from './content-detail-workspace-base.js'; +export * from './content-validation-to-hints.manager.js'; export type * from './content-workspace-context.interface.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/hint/context/hints.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/hint/context/hints.context.ts index 87025e2717..3a9875d47c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/hint/context/hints.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/hint/context/hints.context.ts @@ -1,6 +1,6 @@ import type { UmbHint, UmbIncomingHintBase } from '../types.js'; import { UMB_HINT_CONTEXT } from './hint.context-token.js'; -import { UmbHintController } from './hints.controller.js'; +import { UmbHintController, type UmbHintControllerArgs } from './hints.controller.js'; import type { UmbPartialSome } from '@umbraco-cms/backoffice/utils'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; @@ -8,8 +8,8 @@ export class UmbHintContext< HintType extends UmbHint = UmbHint, IncomingHintType extends UmbIncomingHintBase = UmbPartialSome, > extends UmbHintController { - constructor(host: UmbControllerHost) { - super(host); + constructor(host: UmbControllerHost, args?: UmbHintControllerArgs) { + super(host, args); this.provideContext(UMB_HINT_CONTEXT, this as unknown as UmbHintContext); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/hint/context/hints.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/hint/context/hints.controller.ts index d655c10ae3..6b9f3ba1e6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/hint/context/hints.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/hint/context/hints.controller.ts @@ -6,6 +6,11 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbArrayState, UmbObjectState, type Observable } from '@umbraco-cms/backoffice/observable-api'; import type { UmbContextProviderController } from '@umbraco-cms/backoffice/context-api'; +export interface UmbHintControllerArgs { + viewAlias?: string; + scaffold?: Partial; +} + export class UmbHintController< HintType extends UmbHint = UmbHint, IncomingHintType extends UmbIncomingHintBase = UmbPartialSome, @@ -35,7 +40,7 @@ export class UmbHintController< return this.#scaffold.getValue(); } - constructor(host: UmbControllerHost, args?: { viewAlias?: string; scaffold?: Partial }) { + constructor(host: UmbControllerHost, args?: UmbHintControllerArgs) { super(host); this.#viewAlias = args?.viewAlias; From d895032e225ce57f06792d52b4c920f38cd37669 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 26 Aug 2025 10:11:07 +0200 Subject: [PATCH 09/33] build(deps): bump @umbraco-ui/uui to 1.15.0 (#19981) --- src/Umbraco.Web.UI.Client/package-lock.json | 966 +++++++++--------- .../src/external/uui/package.json | 6 +- 2 files changed, 486 insertions(+), 486 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 81227af986..0fe48a94d0 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -4004,909 +4004,909 @@ "link": true }, "node_modules/@umbraco-ui/uui": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.15.0-rc.0.tgz", - "integrity": "sha512-zO5uCoiXy8f6aGP6k5fCWchKT/6c/UnDlfquODG5tQioFF3pqIfInN/0JHUgMJsQQARdm5KFkSp0PWvVmXhX9A==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.15.0.tgz", + "integrity": "sha512-8yCzfKePv9zK+PMw1K3uwpnDDBZkbSCCOrt8dNDlZ1/6zf+yNLu+r/kVlMcauei6aNsCwXvcI4LhBGS1f5kJ/A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-action-bar": "1.15.0-rc.0", - "@umbraco-ui/uui-avatar": "1.15.0-rc.0", - "@umbraco-ui/uui-avatar-group": "1.15.0-rc.0", - "@umbraco-ui/uui-badge": "1.15.0-rc.0", - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-boolean-input": "1.15.0-rc.0", - "@umbraco-ui/uui-box": "1.15.0-rc.0", - "@umbraco-ui/uui-breadcrumbs": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0", - "@umbraco-ui/uui-button-copy-text": "1.15.0-rc.0", - "@umbraco-ui/uui-button-group": "1.15.0-rc.0", - "@umbraco-ui/uui-button-inline-create": "1.15.0-rc.0", - "@umbraco-ui/uui-card": "1.15.0-rc.0", - "@umbraco-ui/uui-card-block-type": "1.15.0-rc.0", - "@umbraco-ui/uui-card-content-node": "1.15.0-rc.0", - "@umbraco-ui/uui-card-media": "1.15.0-rc.0", - "@umbraco-ui/uui-card-user": "1.15.0-rc.0", - "@umbraco-ui/uui-caret": "1.15.0-rc.0", - "@umbraco-ui/uui-checkbox": "1.15.0-rc.0", - "@umbraco-ui/uui-color-area": "1.15.0-rc.0", - "@umbraco-ui/uui-color-picker": "1.15.0-rc.0", - "@umbraco-ui/uui-color-slider": "1.15.0-rc.0", - "@umbraco-ui/uui-color-swatch": "1.15.0-rc.0", - "@umbraco-ui/uui-color-swatches": "1.15.0-rc.0", - "@umbraco-ui/uui-combobox": "1.15.0-rc.0", - "@umbraco-ui/uui-combobox-list": "1.15.0-rc.0", - "@umbraco-ui/uui-css": "1.15.0-rc.0", - "@umbraco-ui/uui-dialog": "1.15.0-rc.0", - "@umbraco-ui/uui-dialog-layout": "1.15.0-rc.0", - "@umbraco-ui/uui-file-dropzone": "1.15.0-rc.0", - "@umbraco-ui/uui-file-preview": "1.15.0-rc.0", - "@umbraco-ui/uui-form": "1.15.0-rc.0", - "@umbraco-ui/uui-form-layout-item": "1.15.0-rc.0", - "@umbraco-ui/uui-form-validation-message": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0", - "@umbraco-ui/uui-input": "1.15.0-rc.0", - "@umbraco-ui/uui-input-file": "1.15.0-rc.0", - "@umbraco-ui/uui-input-lock": "1.15.0-rc.0", - "@umbraco-ui/uui-input-password": "1.15.0-rc.0", - "@umbraco-ui/uui-keyboard-shortcut": "1.15.0-rc.0", - "@umbraco-ui/uui-label": "1.15.0-rc.0", - "@umbraco-ui/uui-loader": "1.15.0-rc.0", - "@umbraco-ui/uui-loader-bar": "1.15.0-rc.0", - "@umbraco-ui/uui-loader-circle": "1.15.0-rc.0", - "@umbraco-ui/uui-menu-item": "1.15.0-rc.0", - "@umbraco-ui/uui-modal": "1.15.0-rc.0", - "@umbraco-ui/uui-pagination": "1.15.0-rc.0", - "@umbraco-ui/uui-popover": "1.15.0-rc.0", - "@umbraco-ui/uui-popover-container": "1.15.0-rc.0", - "@umbraco-ui/uui-progress-bar": "1.15.0-rc.0", - "@umbraco-ui/uui-radio": "1.15.0-rc.0", - "@umbraco-ui/uui-range-slider": "1.15.0-rc.0", - "@umbraco-ui/uui-ref": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-list": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node-data-type": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node-document-type": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node-form": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node-member": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node-package": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node-user": "1.15.0-rc.0", - "@umbraco-ui/uui-scroll-container": "1.15.0-rc.0", - "@umbraco-ui/uui-select": "1.15.0-rc.0", - "@umbraco-ui/uui-slider": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-expand": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-file": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-folder": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-lock": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-more": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-sort": "1.15.0-rc.0", - "@umbraco-ui/uui-table": "1.15.0-rc.0", - "@umbraco-ui/uui-tabs": "1.15.0-rc.0", - "@umbraco-ui/uui-tag": "1.15.0-rc.0", - "@umbraco-ui/uui-textarea": "1.15.0-rc.0", - "@umbraco-ui/uui-toast-notification": "1.15.0-rc.0", - "@umbraco-ui/uui-toast-notification-container": "1.15.0-rc.0", - "@umbraco-ui/uui-toast-notification-layout": "1.15.0-rc.0", - "@umbraco-ui/uui-toggle": "1.15.0-rc.0", - "@umbraco-ui/uui-visually-hidden": "1.15.0-rc.0" + "@umbraco-ui/uui-action-bar": "1.15.0", + "@umbraco-ui/uui-avatar": "1.15.0", + "@umbraco-ui/uui-avatar-group": "1.15.0", + "@umbraco-ui/uui-badge": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-boolean-input": "1.15.0", + "@umbraco-ui/uui-box": "1.15.0", + "@umbraco-ui/uui-breadcrumbs": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-button-copy-text": "1.15.0", + "@umbraco-ui/uui-button-group": "1.15.0", + "@umbraco-ui/uui-button-inline-create": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0", + "@umbraco-ui/uui-card-block-type": "1.15.0", + "@umbraco-ui/uui-card-content-node": "1.15.0", + "@umbraco-ui/uui-card-media": "1.15.0", + "@umbraco-ui/uui-card-user": "1.15.0", + "@umbraco-ui/uui-caret": "1.15.0", + "@umbraco-ui/uui-checkbox": "1.15.0", + "@umbraco-ui/uui-color-area": "1.15.0", + "@umbraco-ui/uui-color-picker": "1.15.0", + "@umbraco-ui/uui-color-slider": "1.15.0", + "@umbraco-ui/uui-color-swatch": "1.15.0", + "@umbraco-ui/uui-color-swatches": "1.15.0", + "@umbraco-ui/uui-combobox": "1.15.0", + "@umbraco-ui/uui-combobox-list": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0", + "@umbraco-ui/uui-dialog": "1.15.0", + "@umbraco-ui/uui-dialog-layout": "1.15.0", + "@umbraco-ui/uui-file-dropzone": "1.15.0", + "@umbraco-ui/uui-file-preview": "1.15.0", + "@umbraco-ui/uui-form": "1.15.0", + "@umbraco-ui/uui-form-layout-item": "1.15.0", + "@umbraco-ui/uui-form-validation-message": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-icon-registry": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0", + "@umbraco-ui/uui-input": "1.15.0", + "@umbraco-ui/uui-input-file": "1.15.0", + "@umbraco-ui/uui-input-lock": "1.15.0", + "@umbraco-ui/uui-input-password": "1.15.0", + "@umbraco-ui/uui-keyboard-shortcut": "1.15.0", + "@umbraco-ui/uui-label": "1.15.0", + "@umbraco-ui/uui-loader": "1.15.0", + "@umbraco-ui/uui-loader-bar": "1.15.0", + "@umbraco-ui/uui-loader-circle": "1.15.0", + "@umbraco-ui/uui-menu-item": "1.15.0", + "@umbraco-ui/uui-modal": "1.15.0", + "@umbraco-ui/uui-pagination": "1.15.0", + "@umbraco-ui/uui-popover": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", + "@umbraco-ui/uui-progress-bar": "1.15.0", + "@umbraco-ui/uui-radio": "1.15.0", + "@umbraco-ui/uui-range-slider": "1.15.0", + "@umbraco-ui/uui-ref": "1.15.0", + "@umbraco-ui/uui-ref-list": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0", + "@umbraco-ui/uui-ref-node-data-type": "1.15.0", + "@umbraco-ui/uui-ref-node-document-type": "1.15.0", + "@umbraco-ui/uui-ref-node-form": "1.15.0", + "@umbraco-ui/uui-ref-node-member": "1.15.0", + "@umbraco-ui/uui-ref-node-package": "1.15.0", + "@umbraco-ui/uui-ref-node-user": "1.15.0", + "@umbraco-ui/uui-scroll-container": "1.15.0", + "@umbraco-ui/uui-select": "1.15.0", + "@umbraco-ui/uui-slider": "1.15.0", + "@umbraco-ui/uui-symbol-expand": "1.15.0", + "@umbraco-ui/uui-symbol-file": "1.15.0", + "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0", + "@umbraco-ui/uui-symbol-folder": "1.15.0", + "@umbraco-ui/uui-symbol-lock": "1.15.0", + "@umbraco-ui/uui-symbol-more": "1.15.0", + "@umbraco-ui/uui-symbol-sort": "1.15.0", + "@umbraco-ui/uui-table": "1.15.0", + "@umbraco-ui/uui-tabs": "1.15.0", + "@umbraco-ui/uui-tag": "1.15.0", + "@umbraco-ui/uui-textarea": "1.15.0", + "@umbraco-ui/uui-toast-notification": "1.15.0", + "@umbraco-ui/uui-toast-notification-container": "1.15.0", + "@umbraco-ui/uui-toast-notification-layout": "1.15.0", + "@umbraco-ui/uui-toggle": "1.15.0", + "@umbraco-ui/uui-visually-hidden": "1.15.0" } }, "node_modules/@umbraco-ui/uui-action-bar": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.15.0-rc.0.tgz", - "integrity": "sha512-hrAIlv2MEg+BcgxLg0H1b0hsyfGjiLNRAiHXf9GUfDNb6RZs9wCEgnI88vU8pfnTIRkfVDqewm5WEBxYwucSQw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.15.0.tgz", + "integrity": "sha512-O0807+bWVWV/rsFihFVKSOkg9wBtLXKCszE5+eZk2KmONm93BFhIAE35rp7eD6X2SuJMHwYzInIxMIMjHzdpUQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button-group": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button-group": "1.15.0" } }, "node_modules/@umbraco-ui/uui-avatar": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.15.0-rc.0.tgz", - "integrity": "sha512-DbisxrMnN1Z2yV+kQduTHu3Jw6gCRQlQLt/H5GQySNek1zNqaI0M8yeU6CHZPis+DgZoP0MaFRXyRuTqOhe2iQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.15.0.tgz", + "integrity": "sha512-eEX83zwRN3tCiHScKcmkROWAfLu3TgFI9SntlbyxiuSSYfhJxWSZXOf6lVvQ/1CyvKq8XqSbBnN3VKXgcaKOpg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-avatar-group": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.15.0-rc.0.tgz", - "integrity": "sha512-tetsqYKGEv69RMRpeamAVzNQMP77Ty7NIYaRBNfhsyAoYCE2uL1DxQsqiUzv2Ve2dDmRM5GOrWD4zxhrFHhoiQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.15.0.tgz", + "integrity": "sha512-CGYAFAHgNoQK2UTupP7pO0mwP6t9/Ms6WZ0gIC40a+kPjrGtaDWU52hiPsuXrUcR6WjJwZ5WRrJHOboRpdmM0g==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-avatar": "1.15.0-rc.0", - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-avatar": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-badge": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.15.0-rc.0.tgz", - "integrity": "sha512-VFxMixI9AXu2FlHlY4djnzURNpIAYjCvgfgmZG81HRbfgtSsv/nCS/l2dC5Y0/oDku/yDkF73ZqeosQAOREyQA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.15.0.tgz", + "integrity": "sha512-9aGmhRvey98kcR7wfsnno0BNftIRwJ0r2lCH6cNK2lhe69enYm0MWjp+4uutnlEWWskTLEI344BOqmqOHH1NPA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-base": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.15.0-rc.0.tgz", - "integrity": "sha512-xj0NMdQ+dVdVvo4Y8FAFYYtVt84T/KkzVPi+jSsgt/n0pWdfFd3f13cYiUYehNcS1q+rZxXp0ECuxnoi9GTzQg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.15.0.tgz", + "integrity": "sha512-0vtKmjzUOn/tIUHNrsx7aZpy3eq9aRKqV9kkJTrhH92S4WcMy+cOB1iw9t3Fe3xlBPuL3JpszwuxMTIuIqJTgQ==", "license": "MIT", "peerDependencies": { "lit": ">=2.8.0" } }, "node_modules/@umbraco-ui/uui-boolean-input": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.15.0-rc.0.tgz", - "integrity": "sha512-BVQVhEdOz+YJQQ0iFFJqDpW8wvsa9423GcIa0x8QRj7KhDgiEcbwNM3eHblHYkmKXFYVd250/MIB7UurY5IycA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.15.0.tgz", + "integrity": "sha512-LkYX+p44mFVdvlZSliP5ClMcyHoOIVLWI3WVkaMLQdNi2LO9bbfaTneLzu4ruW6v0iF+kLsznr3bl73VHk7oEg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-box": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.15.0-rc.0.tgz", - "integrity": "sha512-u9RxTBDzbggQu6MHNFYSRU4siMLeMO4y/O6jbxRd/8mPViiT14yobY7I1d1wOYbgevoltJrtHqhDOjIWj+x0TQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.15.0.tgz", + "integrity": "sha512-MhSNcKsVNymD/yt3NFXujuaQmAqMqj5S+CBoDHEk88H7Id9NMw9RStZFJ37mI2CxHWkeHDotNVgOhSBiHJNJnw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-css": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0" } }, "node_modules/@umbraco-ui/uui-breadcrumbs": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.15.0-rc.0.tgz", - "integrity": "sha512-3hAq5GbnIbf2RfCbfW59T5uYm6nX0Zobp+VWtGb9388FhhkZuSQdn2nuN33VjmMwvVkTvGWcuqww4ii+XoSaTg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.15.0.tgz", + "integrity": "sha512-TaUY+hNB0VIwv9SBi9fDjIFRtrmmkcT7hlhLCJLUVfQ7jJlGLPISAAdypSplNeCPthYvP1cJQ9m28OzscXHZxQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.15.0-rc.0.tgz", - "integrity": "sha512-5YAmsYyQHzY8HBbfZpK7ekrLQKm90Zuq/TpcOuWGCe9h33T97CWJ+ekcNzpFWBhDXKPfcV22wSapnszzsPxI4g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.15.0.tgz", + "integrity": "sha512-3Oaqj6Yta/Q/Ndme20YA1XbHdBBL71iNhpqREfTHli2YV4TEcgIiNy0s2op2oPhKjIEQPEfitU2BrruYEEWa7Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button-copy-text": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-copy-text/-/uui-button-copy-text-1.15.0-rc.0.tgz", - "integrity": "sha512-HeV6yEZ6do7JkJfDLTZqD1Z4EHuev65KFx3JVNHSg+fDfFQgs1fcM4Hrm7wBUsOLcIknvislCs8UumypdGeIBQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-copy-text/-/uui-button-copy-text-1.15.0.tgz", + "integrity": "sha512-MAaJzpwVnlyGJNvLv6qIwrYsI5SaXXiVKgVi47I8+x//QmnArmetCN04766gGzmAb0m2uuC3ht0BXMDv05pxvw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button-group": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.15.0-rc.0.tgz", - "integrity": "sha512-C8goOUkPe6LzVJbkeIIMzEBpqt8rkqGwpLMxYnEnkFx5HW+pQK8JHEivpGiznzl3mGLglPZC/WxnTtKuNb9ZYg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.15.0.tgz", + "integrity": "sha512-YPEnubKNbKmw04eWRH24/3Uxu+zhtLPeJoaT6ykPCyjr/EKc82rSTvn8fwQuP41UokQrXOac2pKn7SncyoST1Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button-inline-create": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.15.0-rc.0.tgz", - "integrity": "sha512-4TOly3u5cWBJFBJZvtNkYNM0pnuiEz2u0kRQhrXOhutXH7jJ19yxSrAg+KntZDGalyd22a5nv7L3+P6kTiLibA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.15.0.tgz", + "integrity": "sha512-nLJZ6P5eK1rYgqjP5zCxbZp8g4WJ23RnUZQ49o7QpU/7zoPOK72/fuM3Ky00Iapixm/kAD6dYHO/P+GtNz8/CA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.15.0-rc.0.tgz", - "integrity": "sha512-A/sKTH8BxtjeEFFp1ou8v9TNBCw2jkMdXly3Ps+TmQZW/I0/bfZoRMOhHqLU+QyfF6/JH4v+IruVtcjqZJizMg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.15.0.tgz", + "integrity": "sha512-pNjpk2iIdSsmTtDdBsWaEr8JX0RcWbl8yKGaqLvo/S7d3bly5z+FjcsgGnX1i1GHo7dqmgVJfbdvN9V1jgn+FA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-checkbox": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-checkbox": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-block-type": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-block-type/-/uui-card-block-type-1.15.0-rc.0.tgz", - "integrity": "sha512-KZtZof1Tuierk9ztnoYcSqbtwFevBCYYnv4poTaoRTwoigxN1rK+aEdVZFejmHg9Jn6BxV6RIHjDI1P0+388tA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-block-type/-/uui-card-block-type-1.15.0.tgz", + "integrity": "sha512-cWag+D0XrogYZesAN8NMPQCCuU7L7uZ4Xz8dmirKQk1gjMrFDC4vYPZRQ/5O3ETTFupfDipVKimgRDsmarbLSQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-card": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-content-node": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.15.0-rc.0.tgz", - "integrity": "sha512-Bzw4gH+3f/gCVJZIV9+V7tzQrqIVUUy7Y44ZsMunwcSWUKldrKLfJvwkG2RmhrUmxlus8MYEJRHOEX2fQqJ4zQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.15.0.tgz", + "integrity": "sha512-DZ6JYNvGb5wVkhhLShENMm+Y6kTpz37YrApQTJVUUgPXhIABO2CDCnqgpH5tkQX73s9jjVB3Ca7SeivuYv8G9A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-card": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-media": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.15.0-rc.0.tgz", - "integrity": "sha512-SDrY63OyNvV3HjhAy+bNONX/cGTX+9Oe8ItlJvX/r7a8qN6j1QaoechUXCVDC4rlAwpaiyPILQ+hPs2eizevzw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.15.0.tgz", + "integrity": "sha512-EzYebWCzR0wHY902NmAcTRSVSscYac3QntCz+xwSulrhzfy4copeOd1qE+Lz7FjHs+ho0IBPZol8sF4W6rK8FQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-card": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-file": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-folder": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0", + "@umbraco-ui/uui-symbol-file": "1.15.0", + "@umbraco-ui/uui-symbol-folder": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-user": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.15.0-rc.0.tgz", - "integrity": "sha512-19a9edL1zmwK5ufyV15hYU6k5aWcLTf6YCOqjcZsnVZfZTpqu22pnDHH1eA5KYh4usGFIG6fTS5dQh1b/o7y6w==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.15.0.tgz", + "integrity": "sha512-oo7gCs3RGJ4ujFs+LpG9I1DS/XSNkz9gaqvp4BkaR0kBXzw5f2SLLGhA9S3M6M+OPlsXuuJNKlTV1tn2+LF6Ng==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-avatar": "1.15.0-rc.0", - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-card": "1.15.0-rc.0" + "@umbraco-ui/uui-avatar": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0" } }, "node_modules/@umbraco-ui/uui-caret": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.15.0-rc.0.tgz", - "integrity": "sha512-ym+6OpksGsJDL7TkRtnvnGu+1kq6VOyxKlvYR+1pqATQfU61t8DBPTuZXYdyiXLKkh5iOSxmxnoq7jIYi89VSA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.15.0.tgz", + "integrity": "sha512-cnKP5GeaI028hGabVCki1kPqAVSekFeP7QEwu7lncA+dcX8uvg+ffV6kW9FV0emOhI5Tmxvh8o+UDKlLs28q3A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-checkbox": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.15.0-rc.0.tgz", - "integrity": "sha512-vCXJi1x3HGr25l1BubJcJJU6XN+Mw7Wlq1sCThS5MBBDi/SaZojV0Xpo5EwREnf8kNn2ozKG5qhKCfHLptO0QQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.15.0.tgz", + "integrity": "sha512-vPkgrFAPDMvJdJTADIWNj48D8gJWD3dBotucUghg/wHhvJv8h/2MvnwMUNnnSB1REHbanl7hJBVvKcNkoil0gA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-boolean-input": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-boolean-input": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-color-area": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.15.0-rc.0.tgz", - "integrity": "sha512-MB0iM4pCVEs3JCBHMUa4Zu9AQJt+89JkZuTHzOMJKaZG31rWx4Jm5BzLazstnxRTkrBsY3IRq/PSnU7bT5jXUA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.15.0.tgz", + "integrity": "sha512-k6u//b+s6UYmzKYMizIf2MRGD4kFy1qWdSk1GnIeDdiQxABJuBZEtkACIe66j+lxnonFvZ/assbLbhRiu15ZCw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", + "@umbraco-ui/uui-base": "1.15.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-picker": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.15.0-rc.0.tgz", - "integrity": "sha512-Qxd0jRZtCkpoKkWaNLs9zGqqynXLA57XDDz3BpC/KdyUDL9Ab8HDUdtZJdTNla7+Paf2kZ0jqINClas/0AiWaA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.15.0.tgz", + "integrity": "sha512-I4KGyzZZazjeifcavHp7qnMbP0Jh0dM+gzZhV+YtdPR2JT0o7y6stkbY0f+dOln0K6Bu6BQLV0HLHl/1f/1NDg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-popover-container": "1.15.0-rc.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-slider": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.15.0-rc.0.tgz", - "integrity": "sha512-gRKjEEB93OBLxkkq8rnix8Ve5hIIHkjgsO0EoolEHUNx0R3E9nlzc0fkG1xdht3Ifd20CFQS7PsQ3ciJjUvQwg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.15.0.tgz", + "integrity": "sha512-lpT9kapypGkTelG9COSk169VKs0MSiKweX8menDDn0p6I4RfKQBy0N27HecCcf1RqPsCnTbP3lPr5DJy00KdzA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-color-swatch": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.15.0-rc.0.tgz", - "integrity": "sha512-LuyExHAC9nv2gK1sd4QolUreAAvqfNzQR1iDggfRqx9RG+X7yXaxssDRZ0L8uL7ga1sefYSQlYO0L28e2hpLCw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.15.0.tgz", + "integrity": "sha512-1AI0QMr046fKc8xZ4aBO7FDwvggsS9plIpY0W4AGrqQxqGUR2u/mTU49+8xMtboaFOen5RQpJ65DN9hAgeNZ+w==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-swatches": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.15.0-rc.0.tgz", - "integrity": "sha512-OPT9M21/5dHxEMXdxMH6Vum5XDPhSqCgJ81OKvXk/KfYCMXdh8mfkOu+EqchKL2bgDsAbc5eaqk5aLqTwVF+hA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.15.0.tgz", + "integrity": "sha512-UzlgWdsVHyCM/znFThrfA4A/S/K/R9Nc2KyRYiyy2xgBoP7x2vJ5Rn4mnR02W4bhI3gNgCJ2fqhmyiW4dxyk0Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-color-swatch": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-color-swatch": "1.15.0" } }, "node_modules/@umbraco-ui/uui-combobox": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.15.0-rc.0.tgz", - "integrity": "sha512-vkJZT4bno93Xyamky2vM1dVh8vClX2nm7P3Vyd/drBCihcBDcijv7tRCn+97HzEXyUO5aEs4lV43niyOzsRIoQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.15.0.tgz", + "integrity": "sha512-CKslvVRCKCReMr/ZZh4wc3TKJNvFjKVm/hSIvFqCIoJuSKfC4XuLU9SK9FL1s42NUAUmccSD3hATZJZ9VXqY+Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0", - "@umbraco-ui/uui-combobox-list": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0", - "@umbraco-ui/uui-popover-container": "1.15.0-rc.0", - "@umbraco-ui/uui-scroll-container": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-expand": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-combobox-list": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", + "@umbraco-ui/uui-scroll-container": "1.15.0", + "@umbraco-ui/uui-symbol-expand": "1.15.0" } }, "node_modules/@umbraco-ui/uui-combobox-list": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.15.0-rc.0.tgz", - "integrity": "sha512-7kCNzHY51hBY3YTXzCTWfsmyMMbyxPb6ClXyeUBA2DAihP/YNm73lT3zSpR9eXowppEbnTFM8NpMa3PSqu67cw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.15.0.tgz", + "integrity": "sha512-e8IhqU9AC5pOqXuzPzI+BDsW97Ac0u1GU/5MIJqRcBZ+ZttPcH4fsm4u8siCHbK1khCG0Vzo7HiKPZ0IuuOslg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-css": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.15.0-rc.0.tgz", - "integrity": "sha512-S+fIODQMdBjfA/WNg950AvRnKfXOP5j2IZgXRb2zk5KhDLx7Hr/Zw8KICM/7CeOTnbedCm/BvZoVrZ8bCtMCRw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.15.0.tgz", + "integrity": "sha512-0FPJ/NHE8MSJ7vvdFp4cSWT5L73KS00bUHPyA6oiF/XnE0AfS9TzkSWObdSrU6kyPr/fybVwsycDZNBfPiyrCA==", "license": "MIT", "peerDependencies": { "lit": ">=2.8.0" } }, "node_modules/@umbraco-ui/uui-dialog": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.15.0-rc.0.tgz", - "integrity": "sha512-j81llRkeb+cL9DIPpfI0TDxi63xdiZchNpLg59a7wI9UBgoTAdsjhml6vuNgf7x2ivmy7OF8XswP98MQSoQnxw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.15.0.tgz", + "integrity": "sha512-iVsrVVnvBrCCT9uJhyBE7b1kXwWUUKDmimhs/TyF1SFjxWP/U0Z99QqqI1pawdad+BuK3oVCmxYOdaReWDQXkQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-css": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0" } }, "node_modules/@umbraco-ui/uui-dialog-layout": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.15.0-rc.0.tgz", - "integrity": "sha512-0UxrGcCThIBk15lsahGGnDzJXR0QD40JfqZGkc7jMddCF/uljBn/R2Ccke1VEic6x9SiB2csPLpA9L/sIui1hA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.15.0.tgz", + "integrity": "sha512-JdDRIzSGGDnvVqXSIhc+5rDXMdYMO+Hd7s2hqLp+iRSn8IHISN/qT1nfFVO9LMbLdcApanl3JJ4Rru9LN4Q3HA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-file-dropzone": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.15.0-rc.0.tgz", - "integrity": "sha512-37flID+ISdYZA9i1p7sVqjf6qwvrHtYFUYIh7xSuQCQPT+ftrg/db3S0lUaWJnslOGe6ChhLp4qSXo8p3ZLDVQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.15.0.tgz", + "integrity": "sha512-MhJRkVdDQWKEBvemNRD4bZCuIS0JUll1nNoPK7scA+e6vDmbv25vqPHNXGE/sIpVkChY/L+v+twokzlHn57XMw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0" } }, "node_modules/@umbraco-ui/uui-file-preview": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.15.0-rc.0.tgz", - "integrity": "sha512-sFBAUDSGV2fiLV4xdcou7t1GZKCtYTETUZW/zJf0QTAoexjlYyp9hcRw7f3IhOBbARlQvFeuoIiA5e1ZZA+3aw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.15.0.tgz", + "integrity": "sha512-AHKIdYLC0ga4Wgr68xtW/gG3NDqn+QhD2aus0l2n4lBoq6OAQ5aZiPwD9i1fCD7dgyjKQ6Ov9PJSaqRYQkOlNA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-file": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-folder": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-symbol-file": "1.15.0", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0", + "@umbraco-ui/uui-symbol-folder": "1.15.0" } }, "node_modules/@umbraco-ui/uui-form": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.15.0-rc.0.tgz", - "integrity": "sha512-+drFTajJ4i+Kzv0DD8mSMb8eRHMM5l8E4ucAXVpXjQ6oo8LxRemmjFoU+wq4y/xLZeYEvRXz6m33esRHjgFhug==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.15.0.tgz", + "integrity": "sha512-4u9ZryfVBunpb0IL0+TevytrISA6S1+AajiK/PUk0JMJfqMuQMjmpnNPdtYRNVgFFIcQFQKipjT/mrHbDVawxw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-form-layout-item": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.15.0-rc.0.tgz", - "integrity": "sha512-IU9WiRWC7/O+YeMRPhnJ+VCx7i+gwRIdjeCmpB8LbRBspK40PBYpHn14G4parwaKHGVfOnis+BbUjWP4TTOrMg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.15.0.tgz", + "integrity": "sha512-fiWGeQpREnl6k+6VNHz9ixNdEmOoFNm7qsgdIYJ1jCDXBGME1mjxJOr2Eq7UWJuzQM8BeyQEcXq5SVIOv21PRw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-form-validation-message": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-form-validation-message": "1.15.0" } }, "node_modules/@umbraco-ui/uui-form-validation-message": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.15.0-rc.0.tgz", - "integrity": "sha512-B8l/jlOtAWimDC2m7/pZjnZS/rVNayYVivwsHKnQn/KN0XQ2nyYq8cpYUA1XZ+ZqDbS/0BP/UUZIC3Fx4n4Eng==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.15.0.tgz", + "integrity": "sha512-RYfwmjPkY0KumjaalLW8gkasW25Mj87YFAzJn7mAYiZigURape9RqGpvrBfwcMmGj3W2/uVuHxpAHrvweQOt4A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-icon": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.15.0-rc.0.tgz", - "integrity": "sha512-x+HjEO92m4D31Xajzet7XwmAWDNim0XMn0IDB/qxHVza3N3ciisaMiqQ1kx/196RTcKFFWVOT6d2UMwPxwS5eQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.15.0.tgz", + "integrity": "sha512-e8/W6gu6kwrodH0f0U70LR5rHQhiZGq3NqLqikAQ1rvmwitXUqtkVXIhkGxSf7M6yPhpmoi2qEEZDQH9cvCE5A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-icon-registry": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.15.0-rc.0.tgz", - "integrity": "sha512-/iNgSrVtXUQzwYRLjAI3XcIcr0EnN00trdOFCGd/2TnEhR1QOxNHIw/0FvSqjDder1y5gYFwLregle0pOvzkow==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.15.0.tgz", + "integrity": "sha512-nIdzCqoABeRVG6jW045ok649MiAhm5zPdfuMKc1a+TNw9xkKj+vnA1YcjaBN502+AekMhhwnqgj9mLL+mC2VPQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0" } }, "node_modules/@umbraco-ui/uui-icon-registry-essential": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.15.0-rc.0.tgz", - "integrity": "sha512-sj7R4u1DYXOHpjeYnlJPA3qjdp4SZSen1/XUdbQxouANcI5a8ZCVfg1+7WIvYWIDBJ2c4VMabGkZYkAvpgLanw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.15.0.tgz", + "integrity": "sha512-llHFVMlV3Uyg2fHiNt1qfDgRhLthD37uQD2FzlQb0GEYjp+4dE8Jyc/eZW2mqABPweUJACVwbrwBUVrCeQJ1OQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.15.0-rc.0.tgz", - "integrity": "sha512-UeoW+WzqfR01kDqgDDsRX+N7ELujghXqDoOx364kJjlwfiemh+58490bujbOT7a+AG1LDNsV27px0OJBpNsErA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.15.0.tgz", + "integrity": "sha512-vPc4I/kkQM9RWfHI0F/OQhoTu+KefplbQp0JEQ4gfr6MwxIm6bBTEuw8T5K9t1DQs8EZ7yeLEsSh65FDPepRtg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input-file": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.15.0-rc.0.tgz", - "integrity": "sha512-NNbOzLtRPeWnzJoRqLP9BKyCrZODsuOeJuFKQUUPo6NuT2bg1SIu51PHdRcO8a709UDH/lB3wBSuwt3Be71TEw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.15.0.tgz", + "integrity": "sha512-VVn2FMsflvEWd6fOX0HQ3JaUh7haznqSqCLTSTOduh/H3jE+dVYCW6YC5uTsxArmOwsSBYSfBQNetW23eJim3Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-action-bar": "1.15.0-rc.0", - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0", - "@umbraco-ui/uui-file-dropzone": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0" + "@umbraco-ui/uui-action-bar": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-file-dropzone": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input-lock": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.15.0-rc.0.tgz", - "integrity": "sha512-CJKssXf7E8szjGRXghkyHRMo8seyXq9jxrumWyxxhJCHGOXsGecIREc1oAd/a2C+BfZzdyykGiOiJLZoJRURGw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.15.0.tgz", + "integrity": "sha512-AFyVYNeExHXe10b3/5/BLZOmMKyMxzftsO0HKbaQQuxrxL2SCHsQJRUpxSY+/0vAl2JbNdmrk0HTsP1O4Y9zig==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0", - "@umbraco-ui/uui-input": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-input": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input-password": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.15.0-rc.0.tgz", - "integrity": "sha512-H0G6xtLeWE1z8hi0cgMA4DnE6ay84Z4y2vtb5R9hvS5oocMbpybjOwaKuiV3H4qam/CUAhGtRnTqP0cEWqLahQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.15.0.tgz", + "integrity": "sha512-Pe8lNdHz/6IfbQyWEi0o+pKJ6/zunQ2b8HARCU0a9HFXRDk+XsAuBsn79zQXZl5MvseAUQrnouLwPHpdtMbeMg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0", - "@umbraco-ui/uui-input": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0", + "@umbraco-ui/uui-input": "1.15.0" } }, "node_modules/@umbraco-ui/uui-keyboard-shortcut": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.15.0-rc.0.tgz", - "integrity": "sha512-mR5SWcf+U01aJfNxtgTZxYJQ240MtxnfKNo7C/7soxLnTd1w0Pp7KRHkB6GgKlqTx0X4Umcdu8kn35cCOkoDtA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.15.0.tgz", + "integrity": "sha512-8Q/G5Lg6949BbMHQ1BhZ9UpoJjOQ19w1tl2y0d/rP3w/mKnTQaBSf+MQmA/6kQ/Unb2wHXJANr4pAGpUklOg6A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-label": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.15.0-rc.0.tgz", - "integrity": "sha512-P/wuJift88Sd7fq/BASMTb9JmqpA069GttPxiIoCwMb7zt+fX+xsjjzPHiD1FLihVPUFdw9lIq6d65ahbrDnMg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.15.0.tgz", + "integrity": "sha512-fnmRl+RGUROERvt+Jw0WiW3Btlddg0Xka6F+gR95gy5gr/v8s34uf1/bbPD3hWUXZPukLmxeMjbzyuqMrO8rpQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-loader": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.15.0-rc.0.tgz", - "integrity": "sha512-XD8DsEIQhVVnXtAFNVHwH9v6ysTyKbSpHeq9pHFWmupCpqvF1i0fBRYLnE+nTyzq5331WyoQieWrsmYz2C8dTw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.15.0.tgz", + "integrity": "sha512-HQ2zCp2kz45GWQ3wV153ytuYD2KcdeAA5RRUVrN0Zn3GQB3wfG7xMkQQNRAOWMUdnfqmdQHeK+COO7NaET3VBA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-loader-bar": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.15.0-rc.0.tgz", - "integrity": "sha512-rXH8dEagrmiWZHgdHfb7Er3FsA93ZBrvF/KF4tC4Jw+2xZC+tw+n/7yAKcWM8JpCphGaIl2e4BqoalNIazmd8g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.15.0.tgz", + "integrity": "sha512-4eMeerunFc5yZsJIwpHADn8oGcu0Nn36oyKbSd0qC0mNmmN2i8UOF9w4O+lndd2L0Mhv23FGvBRo7mb5EAvWlg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-loader-circle": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.15.0-rc.0.tgz", - "integrity": "sha512-JfjucJUjGMD9yKgOscYXPOY0KN9ABbmMTwOQTzWzWAPvY6P8/OgGUKrGAQAnZzQ2Qqcl4/MMGuN4L5HX5YC3gw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.15.0.tgz", + "integrity": "sha512-4rG8UHvyS2qvsjQYEmYjKX01SRwfk60oH8SSSx8r3z2BM62dCOa+4SBhLxqiBciC/u8FtN8X20MIGE0+eMdtoA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-menu-item": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.15.0-rc.0.tgz", - "integrity": "sha512-rGe/GsgWWyPZiRw0vjW7T1i00x3IKt502ESADdfK/ViF8rE9JgVIDvwCGvYHvbDPfVQci8YsQYS8I4VX29z77w==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.15.0.tgz", + "integrity": "sha512-BOebCMB/p4TaK4kJYrYgimC6SSGBHN4y1MytK3tyvObbuj3gVqkbwHW5CZrhK4jMaywRgGq96OsuaGfc52HFog==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-loader-bar": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-expand": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-loader-bar": "1.15.0", + "@umbraco-ui/uui-symbol-expand": "1.15.0" } }, "node_modules/@umbraco-ui/uui-modal": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.15.0-rc.0.tgz", - "integrity": "sha512-cKO6BE5tWDIfiGAMM/8/6GmOTrEzVqpSfe4yVFX4AvChOlCfx0+NS2gffICzFq7n5BZ7lOKo5dx8ByuRDkIhrw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.15.0.tgz", + "integrity": "sha512-EDz1Qx+mTXNvOu565IculPCyuuFHwBon2wYnfWDBMoHJ5+P54jBHzg2U/8fUVse7xKPvU21hF4JneAvycNIiGQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-pagination": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.15.0-rc.0.tgz", - "integrity": "sha512-NaxkYnfUSQNfXVpyQyqtFefpvA4ElBaXf+BdhwxEIYvki7qLsracZxPtLahgfxm08xP+kP5smIVSNbLsOUh1Kg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.15.0.tgz", + "integrity": "sha512-sPVs1bApKupNd2JcSMwFS1060Y++Fti1ybJrafcLh1+h4IjmLDIRTHTTL8C+kei5G2Oi3+Z7vGpLu7lrTAmRlw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0", - "@umbraco-ui/uui-button-group": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-button-group": "1.15.0" } }, "node_modules/@umbraco-ui/uui-popover": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.15.0-rc.0.tgz", - "integrity": "sha512-jkrJVREYar6tNG+DS01Wnqg656d6Cen2sUTYl/grKVsgLqdZPP42hzpClctlT8HdDYSj650e5JOCqSOFZiv2Zw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.15.0.tgz", + "integrity": "sha512-VCHVvO0fd5eL5UvB/RPL/K68UhOgsIpuyr+aXLblaYT/6at2LNosUxR4eRW2r0WOQzOiyE+Nu69pExBKyfT8bw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-popover-container": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover-container/-/uui-popover-container-1.15.0-rc.0.tgz", - "integrity": "sha512-s/j+dlKjtVhAXvs7FKwjL54xlrqfWnjqjycxIABHXasrJbLJwX8oxs2iL8pk4mb4ZbdIpdA5xkRjF4eTyfT1Jw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover-container/-/uui-popover-container-1.15.0.tgz", + "integrity": "sha512-54M4G0ru8j5ltPAdDGIxogdmos33hxeQeusI/uMFxo2yqHHyMHRi95vvCdcwFmGlEdFd2rsnxZKfNMUKM99GKQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-progress-bar": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.15.0-rc.0.tgz", - "integrity": "sha512-oYGogiagAay/ZqmDgTtB1FCjXZuaN/5Lj0TiOFwdVtIO2l+xmHwyUyX7byyt2kaZ6kGcuROTlPYn1gDvK5yRUg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.15.0.tgz", + "integrity": "sha512-vtGUwHaG4EDLQERkwym51OasoWLj30LQLhcCCYXDJtTL1dG2nIKScEtlSUiVh5qRsI+V+kaBYPGD4TFD5o43tQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-radio": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.15.0-rc.0.tgz", - "integrity": "sha512-l/+QPKyN+9CiDhKxOfmDnbpXLO7rkLM0F8AL+fy/Jjp33NC32blQYAkYV+Ayv0H898nkZBrcpA+tvVGkoiHKeQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.15.0.tgz", + "integrity": "sha512-5TUF/iWUzbVXvBs9Z273q6s9yLbns8itTiFHCITw5w5fZzDn8R6O5hrOW7tV79kCxAnBSOAVP8v1JhGTwXw19Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-range-slider": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.15.0-rc.0.tgz", - "integrity": "sha512-P8+e+JFlEhsZHntt3XVwKQkNvluIVqnlLM3VYFlOeqU+3pgsDIat4Tm2YiH23Cd8dCI0G5eLlmqVLPvwQjhhDA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.15.0.tgz", + "integrity": "sha512-HMHVdBoB1O39rojofezee2aXGv6CMn7dUFvNefdF9HxmNrIcpFBYXSL8aBt5QJeziFQMwbCtqyY21aUag0nzfw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.15.0-rc.0.tgz", - "integrity": "sha512-ZQ9U8x2ypxWqFFFDu3vjXPahUbr7TmGKUSBwDai4HPdLXOQqoAR5Fc0NOYxx4fc9yq5NQ2hczK1hd71V9ST28g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.15.0.tgz", + "integrity": "sha512-w7FZIe5mtsgvsf6hOH5mHKDBzg9Rd/+viyk/xNVs1NeZBn1nWEIHZs0R7YMpv+QxulklhAOpBcbGoUTB8xE+vA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-list": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.15.0-rc.0.tgz", - "integrity": "sha512-th86PCdgzsaIwtjLr8AccyvHYhpoRKWVDjDEcFkfpUvbogSI8u/0fSmkaNwUjtCehoRT/HCDj9we3Yn4A10xUQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.15.0.tgz", + "integrity": "sha512-UT65bpUmRlEgVuvn2RlTZ5l2WDF82jH1t8g+6HV6OJctpqTKlOfPkQmd6AluESPhHFEwwTydS/M7x+X3Adkdtw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.15.0-rc.0.tgz", - "integrity": "sha512-kw56OWmUdd2sFWeYBjcKaE4mDuLFjKv7JImwIfn8LYtZ/uTcwsdiGOQf6gQtNbMVtW5FMjJQXBFCagT+HwW0RQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.15.0.tgz", + "integrity": "sha512-ybDqIt1cXd7AiZLZsDrSHCMp2zM8I+0lmN599b3NROjm59SZXIvpbY1TS1gJ45htgsc18x2y+S4laInYu2dGUg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0", - "@umbraco-ui/uui-ref": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-ref": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-data-type": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.15.0-rc.0.tgz", - "integrity": "sha512-ZYNoUVBPmuxYM3obWfuiQNJCAEv7csDMpiQJ0Eaf3W3hxm6i1HxTC6V4NajO38zFVBsJjCaXzqgESLPtN1DS+g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.15.0.tgz", + "integrity": "sha512-59s16558ySCX7b9IT/Sorq0fdFeCRENSTa7DIkQUrvVPaFWqKFz9jCYFEqDnH11jZHGsNiYh5YCmWlF/VNbwJQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-document-type": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.15.0-rc.0.tgz", - "integrity": "sha512-ZEtyl+n/IkSflZxLwhKBGTMJYndJPHBGAqijqAajDWpBYrum/bxu8bYjE+oVkRRMHqQgCm/q6B4qTrX0qsPWfQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.15.0.tgz", + "integrity": "sha512-AWPZPkFGcAkRx4j6JnOi2r3EJxnvZUXfhOWNyWB2/dFRckatPH56+lVkqV+fRC+81emKBSQWkx2NphFzLEMr0A==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-form": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.15.0-rc.0.tgz", - "integrity": "sha512-cQER0tdwAGSzyO76RDDj/aoIDC3rLv3EobpL0BeSldYfgFQKfyS+96JthQkDytJP1RC8kJdQ8J5/QM2Z+QTDnA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.15.0.tgz", + "integrity": "sha512-knIIbbfoWtepOvyC54dCo3xF0Vuap6i5uMQPd+wITCmg56a+yiJFuke+dyzatOIeXzgspLgFUngwQZEj5mJnWA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-member": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.15.0-rc.0.tgz", - "integrity": "sha512-oOqA0Dl6Zc312Li8mLlTvIJ4MDiaMEGD5ip1plmSiNF7YxRIh+6srrPugAZQwsrU+q6JVEEul5HjgOd8Eu46pQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.15.0.tgz", + "integrity": "sha512-pXvL523m2JR3P8OO+E1AE4YAaYhJLc519CtjNXSuctNIk1yWvwxBu8VozLIQV+xrOXGz+SiXwDkoaRPwjTQKtg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-package": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.15.0-rc.0.tgz", - "integrity": "sha512-oXh030/wLZiU/9TBEfHvoGHXCRDcI43oJ0x/Den4S2U1Fc+5U4Y9F0LvA3611IL2EqUa3ZA0tQJLzAt6kPbpkw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.15.0.tgz", + "integrity": "sha512-bQWfZPKJyAf2O/YvOD6fVSSpKaYZMBsrEGT+ydLPv3BNJroYHS8+NEbulZxExWztNApTcs6Vo5T19AUz+vsnLQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-user": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.15.0-rc.0.tgz", - "integrity": "sha512-KqFQAaXGdf3N+RLj3tuU0TFeedNANT2fr6dRuVysEL8hKIpjkCKdNp4PCGePY1BR97/NVLNnXXuG3+Ccued3tQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.15.0.tgz", + "integrity": "sha512-4GpRzhGedMwjqW1Wk7AvgakNCc6S1edYpHWeO6cfmryIm0hvnCfkU132lzLmB+Ag2QIOI8p4Ak0OQHYWd+XZHw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-scroll-container": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.15.0-rc.0.tgz", - "integrity": "sha512-KfBdFU2zY5IfeNUMreCwHfWw0HoEPx9+2pbmc7UCPgg7SjYMkBNa8sce+bpc/OoUUpo9zbbvNjqF6eyXqeVwGw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.15.0.tgz", + "integrity": "sha512-L4qM6GPDqu0/9B2OVb3EljZT3zYxbwp6uOz1nfVYpGAWBxd6INOtNbn8WYdZLq6qqa8NR6qK+su2554nInvQGA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-select": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.15.0-rc.0.tgz", - "integrity": "sha512-IORtMOqTy/1+S6a7QRqg8LKgqRX4jLsQkz1J2PK2DtuKceX/tO5HmE+Ec9cTVSFBlDFE95uek6VEsGyGj5oGMw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.15.0.tgz", + "integrity": "sha512-yRx+TlXBB05jM8ShThRooFgCS5nSN7eAAnpttZgBWqY3sccIVy2Knbkz3kXLJE6ld+bO5nUXhsZBZ34MEHkiog==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-slider": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.15.0-rc.0.tgz", - "integrity": "sha512-CifB669wtpHvTzG9d9jKj1eVB9ePeJSO8L4DjNSCaDyvrsYxDpZYzOBQuaIpPRXwdGyznFSyOAb7d8renrlpBw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.15.0.tgz", + "integrity": "sha512-+OAzOutyUB2WCI+e5aFRoUNsFFuc/hUXnpIjx4P1moOYiggc/NxjaTHz5mxbmkC11yyS+0vpl8lVSZglkLCH5w==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-expand": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.15.0-rc.0.tgz", - "integrity": "sha512-GQ9SMmMVJ6b/vAMa22QVJOTRn6uFdu9IELRtwrBNDgywA5L+TG7MyJ4ZgKXc1DwAKwVXwlS0qTAWBis3z1CZRQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.15.0.tgz", + "integrity": "sha512-6y9rpFfhtuWMnaAamlzrB5Q12dsZ8dprmQaGtKr+g97PTNRPC3/dc5sdROam8VMDAhL9MkfBAZBoS6yAoJsPcQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-file": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.15.0-rc.0.tgz", - "integrity": "sha512-8FrKoBzm1YKM2L4dpNG9DjqrQZ/qnUfnx1oLzohxWZXKn13dxS7XdDFkn9B7PPgcxkxPK5DFR2Y8H0YQCTPEIw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.15.0.tgz", + "integrity": "sha512-F0BueWxu6J5P7xyzkp1c/eFZJjStsw65hB3bNEmWBOqkm/jbBKg9+Xs99tov+VwCHYOt8T+DuEDkkKmdxVAxyQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-file-dropzone": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.15.0-rc.0.tgz", - "integrity": "sha512-89og/JhpHbcQj2NuKnbJJBKKCvUWnixMw+yEDU6K4rQ7gOEWMUiYgEI87rfpp4tIRp4pKLL8jTDrvu6I1rS6jA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.15.0.tgz", + "integrity": "sha512-D5DottbukIFxL+YTVEMujHPdqB8Hhw02TKpegfDQb8UGSPC5pCQw4O212TSuyTalKb598niNmCzcjEG5TWNqww==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-file-thumbnail": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.15.0-rc.0.tgz", - "integrity": "sha512-LxNSR/v8NnAs7iyhDBy+ylf8C1OxxIelm3Q7/6ko474wsaBfQqwfJUbmzqCmcQhoptDZia0VxjWB80Sh5OtkAg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.15.0.tgz", + "integrity": "sha512-JLcEVnJqv2LL8VtscPCtPKda9ywWzV4vd0XODHLE3iI1cgHeNwMBhxqgkah0ULuw5w2Hrq8gwQ7/DuPHMSIFxw==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-folder": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.15.0-rc.0.tgz", - "integrity": "sha512-OqMe0IKp1qIhyQJ3Yw0CMcEt1ciuO/EnoUPtdeGUGLZBfZiTEkXoxBc2Yh/6kBLgySDydD+Ddaa1gIYuMpM3RQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.15.0.tgz", + "integrity": "sha512-CPsr1K5IkdxBgID+xoIcgbumm/z0q+Z/1NPxTO40EL7kx3KOLQ8vwLdOTSW1cTj90JFA9+XuRtOpmMEY0XjICg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-lock": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.15.0-rc.0.tgz", - "integrity": "sha512-U0hU0MAZGA6eYz5lMxKajwsEQnUGFGaDgeE6cnJBBManrlT24RmDSFmr7MlW2V0yTYOrWJOCv/P/RPFvZBNuXA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.15.0.tgz", + "integrity": "sha512-5QyDNFjiBeuPgalT9zwPMP220zJUHPpbPvCohWCFLn/2JJsa6IjSMtsAcqxI154ZJ9vYX7vYiYUn8tJTY8CHpA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-more": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.15.0-rc.0.tgz", - "integrity": "sha512-BJ264C8xpe92a9Rx2sDirpS1jqn/en3oVGUV4wDH/BJw+jQAgTt12LzHEjQbNNEbuQBYuZuzLnoW9UVQwyV5hg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.15.0.tgz", + "integrity": "sha512-BQq7BwZ7nCcgKE5tMhG6OVYTrrMEIXpx8kQKec/ULgVfs0/Ws6qeH9u4rGVK/yHU8gecd6DSeUczjjq2iS4djA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-sort": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.15.0-rc.0.tgz", - "integrity": "sha512-xj464OIL8Casqxk2S+SdmwBGn95k5SBh3Y93fZEUykZ4vFG2zmwk32chrJ8kX0uaQ7M3cg+lO5RZRk7QHBaPQA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.15.0.tgz", + "integrity": "sha512-5Akw8T0SV2OrwvPk1JSeFr1clvHE4N0DwceSU9bn9f6gLIGGRxvniJAclQDRI/Woe3hm8waMy6cC2fXfSdc6lg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-table": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.15.0-rc.0.tgz", - "integrity": "sha512-usidTyVmBgE+YYt1ITg0JQxurSAyfg6bz8Fh5FLQVS9hdUWKsRvRhJP7M+u9tSIjzv07mhIlZWBvt6GJUMjFlw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.15.0.tgz", + "integrity": "sha512-AnPp0QJeI70ucX8ludr3qaFmlxjKZUarX10DI8ieIB8VJiQZo0TjoPcPdSGmZupaPBLiszlpb3rKzGkZhXEIHg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-tabs": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.15.0-rc.0.tgz", - "integrity": "sha512-a5o7FXRpj3bAXTkyLlV7G7gn6nHlNn6uYEaSfwuk8sAAfcF84hp75OWLJuNrbIaH6IOblgn4FNBL01GgdAB0mg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.15.0.tgz", + "integrity": "sha512-oS0eA5Z8+s+5o2ks3WCED5VGP8AunRLyuB2y7kVdRUfhCfck7B9v83zNfxPVoGoVsTDLtAQM1S4P8SHwNRmk7g==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0", - "@umbraco-ui/uui-popover-container": "1.15.0-rc.0", - "@umbraco-ui/uui-symbol-more": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", + "@umbraco-ui/uui-symbol-more": "1.15.0" } }, "node_modules/@umbraco-ui/uui-tag": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.15.0-rc.0.tgz", - "integrity": "sha512-cnOEKEGM5BlpDEx4/Fz2o0D2n4o7si87A9UHMPbiDKFNFcJ0gfitwn7eJGn0EZs8C2GLti9wvxv24oUDJ5Hd4Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.15.0.tgz", + "integrity": "sha512-PgyZvAiOZmXmiRW4UhfD6Tybx3ft755aKAVqT8ELpskLSvVr1oz4uTI6+QxoeQ1AkrHovenvIdBX+Iwi91SheQ==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-textarea": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.15.0-rc.0.tgz", - "integrity": "sha512-J7+CFi16wJWMYpQ+c4VLQdA/bpDAIt6USCzoT+Rs+UYFcJKOHI4eEBxQknA61SZMbhcn9hXHI2FrIeR+2/S6GQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.15.0.tgz", + "integrity": "sha512-tk/RVzCxs+KPSJ+qH2Xlr9RYxcdrSNulDKk5sBCQR0A9nwOffa15SGreSMKWgq+gYOVYChHBg/WxLWLq3d7Rlg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toast-notification": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.15.0-rc.0.tgz", - "integrity": "sha512-dEu934tASMh4vbuzy11V7WIKrx5iMQ92j/1lw0ZHaDLHNdkpmkZtbSUKYlO66Wq0EMu3s9O5CAWRNFZJlV15EQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.15.0.tgz", + "integrity": "sha512-nz+snpjPFE+ftH5R/ekgZYy9ofGAf51yQYjWCtBwkrQ6D1dIBYA6kynZFdqIefrRwJJ5zHpe25BcS/AyRPc/9Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-button": "1.15.0-rc.0", - "@umbraco-ui/uui-css": "1.15.0-rc.0", - "@umbraco-ui/uui-icon": "1.15.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toast-notification-container": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.15.0-rc.0.tgz", - "integrity": "sha512-8fSSsBwAoflq7w9qwcKSmrnq6f5JADgzquEQWrK4RXvfvBeFXXlII14WbfYqIe3+FX4310VuPooHse1vd0UiCw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.15.0.tgz", + "integrity": "sha512-fd5d0DU/x2+u15rP0wrjw29M0oqsDFmnAfbPEdgQoPV+hvq9/SLhxJtzx10ZSNXoyuO9sTK50Q7nYsqOvGCzqg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-toast-notification": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-toast-notification": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toast-notification-layout": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.15.0-rc.0.tgz", - "integrity": "sha512-IX4w00PwV8BMbLeqs37Yn0CGGHtGlabMxwODtICze5TkPdD64Xc9W4oPbQ/Fr5CgJdiJhb6OyeVd92cr8n2lAg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.15.0.tgz", + "integrity": "sha512-uf/e/dVN6kqX76vcawiQM3w1nMHa8A+ZTtNwxtmAZi8bNPwjXLNaqKfeSp2thTByCIzFz7imnft56QtYLbksOA==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-css": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toggle": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.15.0-rc.0.tgz", - "integrity": "sha512-ReMVDGO303IIM34HPArTIcVSCfACW8+4gY+fJr46vdy+XPjeZupoBDbxVrn+zMacxxF92sv7gqdabMYhBH6k4g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.15.0.tgz", + "integrity": "sha512-WLooENcxuAobbXxN1W2uKGh/cN9k0f3cRmDDtCZdgjeheGlBYWatkc5HQte7zchXHUi0xTrsvBCBa9CsLKN/3Q==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0", - "@umbraco-ui/uui-boolean-input": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-boolean-input": "1.15.0" } }, "node_modules/@umbraco-ui/uui-visually-hidden": { - "version": "1.15.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-visually-hidden/-/uui-visually-hidden-1.15.0-rc.0.tgz", - "integrity": "sha512-1em6yB9KuZbe14ZQrwmL20YCuEeGKNHiJ4veZ5K/Dm/x9wvsd5skw5M7vMVK+gF77dJBDuGpPLtCtp/FqgFG8A==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-visually-hidden/-/uui-visually-hidden-1.15.0.tgz", + "integrity": "sha512-vn3dbpYGekAqG944Vkwd0ILQRtTaZtL1BVdsge2UsU8sOsEKwv5YzQal4b+o8yu8nb4vZbWHZ2zRmnpnPgPmjg==", "license": "MIT", "dependencies": { - "@umbraco-ui/uui-base": "1.15.0-rc.0" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@vitest/expect": { @@ -17298,8 +17298,8 @@ "src/external/uui": { "name": "@umbraco-backoffice/uui", "dependencies": { - "@umbraco-ui/uui": "^1.15.0-rc.0", - "@umbraco-ui/uui-css": "^1.15.0-rc.0" + "@umbraco-ui/uui": "^1.15.0", + "@umbraco-ui/uui-css": "^1.15.0" } }, "src/packages/block": { diff --git a/src/Umbraco.Web.UI.Client/src/external/uui/package.json b/src/Umbraco.Web.UI.Client/src/external/uui/package.json index 072fb13ef4..1c3a7b4b27 100644 --- a/src/Umbraco.Web.UI.Client/src/external/uui/package.json +++ b/src/Umbraco.Web.UI.Client/src/external/uui/package.json @@ -6,7 +6,7 @@ "build": "vite build" }, "dependencies": { - "@umbraco-ui/uui": "^1.15.0-rc.0", - "@umbraco-ui/uui-css": "^1.15.0-rc.0" + "@umbraco-ui/uui": "^1.15.0", + "@umbraco-ui/uui-css": "^1.15.0" } -} +} \ No newline at end of file From fb5b997090924f09e9069c7003336c230d4ab056 Mon Sep 17 00:00:00 2001 From: Nhu Dinh <150406148+nhudinh0309@users.noreply.github.com> Date: Tue, 26 Aug 2025 15:26:16 +0700 Subject: [PATCH 10/33] V16 QA Added acceptance tests for removing user groups from a user (#19994) * Added tests for removing user group from a user * Added skip tag and related issue to the failing tests * Bumped version --- .../package-lock.json | 8 +-- .../Umbraco.Tests.AcceptanceTest/package.json | 2 +- .../tests/DefaultConfig/Users/User.spec.ts | 54 +++++++++++++++++-- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/tests/Umbraco.Tests.AcceptanceTest/package-lock.json b/tests/Umbraco.Tests.AcceptanceTest/package-lock.json index 25408ef5f1..ca24b641de 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.37", - "@umbraco/playwright-testhelpers": "^16.0.37", + "@umbraco/playwright-testhelpers": "^16.0.39", "camelize": "^1.0.0", "dotenv": "^16.3.1", "node-fetch": "^2.6.7" @@ -67,9 +67,9 @@ } }, "node_modules/@umbraco/playwright-testhelpers": { - "version": "16.0.37", - "resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-16.0.37.tgz", - "integrity": "sha512-hpYrQJRxB8yK/1B2THsh2NDBaXM4DdM4npnjjFSwujBxnjOFjpJj8VfDU/D4eR8pyzZUu9qV4UkzrGxDuf9uvQ==", + "version": "16.0.39", + "resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-16.0.39.tgz", + "integrity": "sha512-rZ/e3Kc9Dzkd7L+V5J3VyGlODnUNLye4kksnaKdRM4PKAsSW6U1f8t3402+lywtTo0oot7JNrVvooJuLwuwc+w==", "license": "MIT", "dependencies": { "@umbraco/json-models-builders": "2.0.37", diff --git a/tests/Umbraco.Tests.AcceptanceTest/package.json b/tests/Umbraco.Tests.AcceptanceTest/package.json index a19b8ff520..82c0467e2e 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/package.json +++ b/tests/Umbraco.Tests.AcceptanceTest/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "@umbraco/json-models-builders": "^2.0.37", - "@umbraco/playwright-testhelpers": "^16.0.37", + "@umbraco/playwright-testhelpers": "^16.0.39", "camelize": "^1.0.0", "dotenv": "^16.3.1", "node-fetch": "^2.6.7" diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/User.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/User.spec.ts index 8ed4f3b7b8..3b8b6b34ec 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/User.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/User.spec.ts @@ -95,8 +95,10 @@ test('can add multiple user groups to a user', async ({umbracoApi, umbracoUi}) = test('can remove a user group from a user', {tag: '@smoke'}, async ({umbracoApi, umbracoUi}) => { // Arrange - const userGroup = await umbracoApi.userGroup.getByName(defaultUserGroupName); - await umbracoApi.user.createDefaultUser(nameOfTheUser, userEmail, [userGroup.id]); + const secondUserGroupName = 'Translators'; + const userGroupWriters = await umbracoApi.userGroup.getByName(defaultUserGroupName); + const userGroupTranslators = await umbracoApi.userGroup.getByName(secondUserGroupName); + await umbracoApi.user.createDefaultUser(nameOfTheUser, userEmail, [userGroupWriters.id, userGroupTranslators.id]); await umbracoUi.user.goToUsers(); // Act @@ -107,8 +109,7 @@ test('can remove a user group from a user', {tag: '@smoke'}, async ({umbracoApi, // Assert await umbracoUi.user.isSuccessStateVisibleForSaveButton(); - const userData = await umbracoApi.user.getByName(nameOfTheUser); - expect(userData.userGroupIds).toEqual([]); + expect(await umbracoApi.user.doesUserContainUserGroupIds(nameOfTheUser, [userGroupTranslators.id])).toBeTruthy(); }); test('can update culture for a user', {tag: '@release'}, async ({umbracoApi, umbracoUi}) => { @@ -597,3 +598,48 @@ test('can order by newest user', async ({umbracoApi, umbracoUi}) => { // TODO: Sometimes the frontend does not switch from grid to table, or table to grid. test.skip('can change from grid to table view', async ({page, umbracoApi, umbracoUi}) => { }); + +// This test is skipped because currently it is impossible to remove the admin user group from a user +// Related issue: https://github.com/umbraco/Umbraco-CMS/issues/19917 +test.skip('can remove admin user group from a user', {tag: '@release'}, async ({umbracoApi, umbracoUi}) => { + // Arrange + const adminUserGroupName = 'Administrators'; + const editorUserGroupName = 'Editors'; + const adminUserGroupData = await umbracoApi.userGroup.getByName(adminUserGroupName); + await umbracoApi.user.createDefaultUser(nameOfTheUser, userEmail, [adminUserGroupData.id]); + await umbracoUi.user.goToUsers(); + + // Act + await umbracoUi.user.clickUserWithName(nameOfTheUser); + // Removes the admin user group + await umbracoUi.user.clickRemoveButtonForUserGroupWithName(adminUserGroupName); + await umbracoUi.user.clickConfirmRemoveButton(); + // Adds another user group + await umbracoUi.user.clickChooseUserGroupsButton(); + await umbracoUi.user.clickButtonWithName(editorUserGroupName); + await umbracoUi.user.clickChooseModalButton(); + await umbracoUi.user.clickSaveButton(); + + // Assert + await umbracoUi.user.isSuccessStateVisibleForSaveButton(); + const editorUserGroupData = await umbracoApi.userGroup.getByName(editorUserGroupName); + expect(await umbracoApi.user.doesUserContainUserGroupIds(nameOfTheUser, [editorUserGroupData.id])).toBeTruthy(); +}); + +// This test is skipped because currently it is possible to remove all user groups from a user +// Related issue: https://github.com/umbraco/Umbraco-CMS/issues/19992 +test.skip('cannot remove all user group from a user', {tag: '@release'}, async ({umbracoApi, umbracoUi}) => { + // Arrange + const userGroup = await umbracoApi.userGroup.getByName(defaultUserGroupName); + await umbracoApi.user.createDefaultUser(nameOfTheUser, userEmail, [userGroup.id]); + await umbracoUi.user.goToUsers(); + + // Act + await umbracoUi.user.clickUserWithName(nameOfTheUser); + await umbracoUi.user.clickRemoveButtonForUserGroupWithName(defaultUserGroupName); + await umbracoUi.user.clickConfirmRemoveButton();; + await umbracoUi.user.clickSaveButton(); + + // Assert + await umbracoUi.user.isErrorNotificationVisible(); +}); \ No newline at end of file From bd967b3f75cdb3bd1c8e7707d5e4331345e6673c Mon Sep 17 00:00:00 2001 From: Nhu Dinh <150406148+nhudinh0309@users.noreply.github.com> Date: Tue, 26 Aug 2025 15:27:58 +0700 Subject: [PATCH 11/33] V16 QA Fixed the E2E failing tests (#19993) Bumped version From 6a4c7794b85bcc8647d27d6aba120de2676f18e7 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 26 Aug 2025 11:23:12 +0200 Subject: [PATCH 12/33] V16: Replacing media files does not update the preview (#19912) * fix: adds documentation to the UmbImagingRepository and makes the internal store optional, and deprecates an old method * fix: uses new method to request thumbnails * fix: ensures the internal data store has at least been attempted to be consumed before proceeding * feat: adds methods to clear cached resized images * feat: awaits the store before attempting to clear cache * fix: attempts to clear the imaging cache when a media item entity is updated or deleted * fix: awaits the store * fix: set unique as property * fix: ensures that the imaging component reloads its thumbnail if it has already been loaded once * chore: removes duplicate check for isLoading * chore: cleans imports * feat: marks method as internal so that we may change it later on * disable eslint check --- .../components/imaging-thumbnail.element.ts | 43 ++++++++++---- .../media/imaging/imaging.repository.ts | 57 ++++++++++++++----- .../packages/media/imaging/imaging.store.ts | 35 ++++++++++-- .../media-grid-collection-view.element.ts | 4 +- .../detail/media-detail.repository.ts | 30 ++++++++++ 5 files changed, 136 insertions(+), 33 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/imaging/components/imaging-thumbnail.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/imaging/components/imaging-thumbnail.element.ts index d4c69d01a6..b23d79e80a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/imaging/components/imaging-thumbnail.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/imaging/components/imaging-thumbnail.element.ts @@ -1,8 +1,10 @@ import { UmbImagingCropMode } from '../types.js'; import { UmbImagingRepository } from '../imaging.repository.js'; -import { css, customElement, html, nothing, property, state, when } from '@umbraco-cms/backoffice/external/lit'; +import { css, customElement, html, property, state, when } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import { UmbEntityUpdatedEvent } from '@umbraco-cms/backoffice/entity-action'; @customElement('umb-imaging-thumbnail') export class UmbImagingThumbnailElement extends UmbLitElement { @@ -66,7 +68,11 @@ export class UmbImagingThumbnailElement extends UmbLitElement { #intersectionObserver?: IntersectionObserver; override render() { - return html` ${this.#renderThumbnail()} ${when(this._isLoading, () => this.#renderLoading())} `; + return when( + this._isLoading, + () => this.#renderLoading(), + () => this.#renderThumbnail(), + ); } override connectedCallback() { @@ -77,11 +83,13 @@ export class UmbImagingThumbnailElement extends UmbLitElement { if (entries[0].isIntersecting) { this.#generateThumbnailUrl(); this.#intersectionObserver?.disconnect(); + this.#observeActionEvent(); } }); this.#intersectionObserver.observe(this); } else { this.#generateThumbnailUrl(); + this.#observeActionEvent(); } } @@ -90,13 +98,26 @@ export class UmbImagingThumbnailElement extends UmbLitElement { this.#intersectionObserver?.disconnect(); } + /** + * Observes the action events for the current media item. + * Reloads the thumbnail when the media item is updated. + * Note: Call this only when the media item is in view or otherwise is supposed to be loaded already. + */ + #observeActionEvent() { + this.consumeContext(UMB_ACTION_EVENT_CONTEXT, (actionEventContext) => { + actionEventContext?.addEventListener(UmbEntityUpdatedEvent.TYPE, (event) => { + if (event instanceof UmbEntityUpdatedEvent && event.getUnique() === this.unique) { + this.#generateThumbnailUrl(); + } + }); + }); + } + #renderLoading() { return html`
`; } #renderThumbnail() { - if (this._isLoading) return nothing; - return when( this._thumbnailUrl, (url) => html`${this.alt}`, @@ -105,12 +126,14 @@ export class UmbImagingThumbnailElement extends UmbLitElement { } async #generateThumbnailUrl() { - const { data } = await this.#imagingRepository.requestThumbnailUrls( - [this.unique], - this.height, - this.width, - this.mode, - ); + if (!this.unique) return; + this._isLoading = true; + + const { data } = await this.#imagingRepository.requestResizedItems([this.unique], { + height: this.height, + width: this.width, + mode: this.mode, + }); this._thumbnailUrl = data?.[0]?.url ?? ''; this._isLoading = false; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/imaging/imaging.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/imaging/imaging.repository.ts index 38c9cb3697..e9b7b515c0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/imaging/imaging.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/imaging/imaging.repository.ts @@ -6,26 +6,30 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; import type { UmbMediaUrlModel } from '@umbraco-cms/backoffice/media'; +/** + * Repository for managing imaging-related data. + * You can use it to request (cached) thumbnail URLs or new resized images. + */ export class UmbImagingRepository extends UmbRepositoryBase implements UmbApi { + #init; + #itemSource = new UmbImagingServerDataSource(this); #dataStore?: typeof UMB_IMAGING_STORE_CONTEXT.TYPE; - #itemSource: UmbImagingServerDataSource; constructor(host: UmbControllerHost) { super(host); - this.#itemSource = new UmbImagingServerDataSource(host); - this.consumeContext(UMB_IMAGING_STORE_CONTEXT, (instance) => { + this.#init = this.consumeContext(UMB_IMAGING_STORE_CONTEXT, (instance) => { if (instance) { this.#dataStore = instance; } - }); + }).asPromise({ preventTimeout: true }); } /** * Requests the items for the given uniques * @param {Array} uniques - The uniques * @param {UmbImagingResizeModel} imagingModel - The imaging model - * @returns {Promise<{ data: UmbMediaUrlModel[] }>} + * @returns {Promise<{ data: UmbMediaUrlModel[] }>} - The resized absolute media URLs * @memberof UmbImagingRepository */ async requestResizedItems( @@ -33,12 +37,17 @@ export class UmbImagingRepository extends UmbRepositoryBase implements UmbApi { imagingModel?: UmbImagingResizeModel, ): Promise<{ data: UmbMediaUrlModel[] }> { if (!uniques.length) throw new Error('Uniques are missing'); - if (!this.#dataStore) throw new Error('Data store is missing'); + + await this.#init; + + if (!this.#dataStore) { + console.warn('[UmbImagingRepository] No data store available. All thumbnails are uncached.'); + } const urls = new Map(); for (const unique of uniques) { - const existingCrop = this.#dataStore.getCrop(unique, imagingModel); + const existingCrop = this.#dataStore?.getCrop(unique, imagingModel); if (existingCrop !== undefined) { urls.set(unique, existingCrop); continue; @@ -53,7 +62,7 @@ export class UmbImagingRepository extends UmbRepositoryBase implements UmbApi { const url = urlModels?.[0]?.url; - this.#dataStore.addCrop(unique, url ?? '', imagingModel); + this.#dataStore?.addCrop(unique, url ?? '', imagingModel); if (url) { urls.set(unique, url); @@ -64,14 +73,32 @@ export class UmbImagingRepository extends UmbRepositoryBase implements UmbApi { } /** - * Requests the thumbnail URLs for the given uniques - * @param {Array} uniques - * @param {number} height - * @param {number} width - * @param {ImageCropModeModel} mode - The crop mode - * @memberof UmbImagingRepository + * Internal method to clear the cache for a specific image. + * @param {string} unique The unique identifier for the media item + * @internal */ - async requestThumbnailUrls(uniques: Array, height: number, width: number, mode = UmbImagingCropMode.MIN) { + // eslint-disable-next-line @typescript-eslint/naming-convention + async _internal_clearCropByUnique(unique: string) { + await this.#init; + this.#dataStore?.clearCropByUnique(unique); + } + + /** + * Requests the thumbnail URLs for the given uniques + * @param {Array} uniques - The unique identifiers for the media items + * @param {number} height - The desired height in pixels of the thumbnail + * @param {number} width - The desired width in pixels of the thumbnail + * @param {UmbImagingCropMode} mode - The crop mode + * @returns {Promise<{ data: UmbMediaUrlModel[] }>} - The resized absolute media URLs + * @memberof UmbImagingRepository + * @deprecated Use {@link UmbImagingRepository#requestResizedItems} instead for more flexibility and control over the imaging model. This will be removed in Umbraco 18. + */ + async requestThumbnailUrls( + uniques: Array, + height: number, + width: number, + mode: UmbImagingCropMode = UmbImagingCropMode.MIN, + ): Promise<{ data: UmbMediaUrlModel[] }> { const imagingModel: UmbImagingResizeModel = { height, width, mode }; return this.requestResizedItems(uniques, imagingModel); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/imaging/imaging.store.ts b/src/Umbraco.Web.UI.Client/src/packages/media/imaging/imaging.store.ts index 8b4bf068bd..29e832a9e6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/imaging/imaging.store.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/imaging/imaging.store.ts @@ -5,11 +5,10 @@ import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; export class UmbImagingStore extends UmbContextBase implements UmbApi { - #data; + #data = new Map>(); constructor(host: UmbControllerHost) { super(host, UMB_IMAGING_STORE_CONTEXT.toString()); - this.#data = new Map>(); } /** @@ -17,7 +16,7 @@ export class UmbImagingStore extends UmbContextBase implements UmbApi { * @param {string} unique - The media key * @returns {Map | undefined} - The data if it exists */ - getData(unique: string) { + getData(unique: string): Map | undefined { return this.#data.get(unique); } @@ -27,7 +26,7 @@ export class UmbImagingStore extends UmbContextBase implements UmbApi { * @param {string} data - The resize configuration * @returns {string | undefined} - The crop if it exists */ - getCrop(unique: string, data?: UmbImagingResizeModel) { + getCrop(unique: string, data?: UmbImagingResizeModel): string | undefined { return this.#data.get(unique)?.get(this.#generateCropKey(data)); } @@ -35,7 +34,7 @@ export class UmbImagingStore extends UmbContextBase implements UmbApi { * Adds a new crop to the store. * @param {string} unique - The media key * @param {string} urlInfo - The URL of the crop - * @param { | undefined} data - The resize configuration + * @param {UmbImagingResizeModel | undefined} data - The resize configuration */ addCrop(unique: string, urlInfo: string, data?: UmbImagingResizeModel) { if (!this.#data.has(unique)) { @@ -44,12 +43,36 @@ export class UmbImagingStore extends UmbContextBase implements UmbApi { this.#data.get(unique)?.set(this.#generateCropKey(data), urlInfo); } + /** + * Clears all crops from the store. + */ + clear() { + this.#data.clear(); + } + + /** + * Clears the crop for a specific unique identifier. + * @param {string} unique - The unique identifier for the media item + */ + clearCropByUnique(unique: string) { + this.#data.delete(unique); + } + + /** + * Clears the crop for a specific unique identifier and resize configuration. + * @param {string} unique - The unique identifier for the media item + * @param {UmbImagingResizeModel | undefined} data - The resize configuration + */ + clearCropByConfiguration(unique: string, data?: UmbImagingResizeModel) { + this.#data.get(unique)?.delete(this.#generateCropKey(data)); + } + /** * Generates a unique key for the crop based on the width, height and mode. * @param {UmbImagingResizeModel} data - The resize configuration * @returns {string} - The crop key */ - #generateCropKey(data?: UmbImagingResizeModel) { + #generateCropKey(data?: UmbImagingResizeModel): string { return data ? `${data.width}x${data.height};${data.mode}` : 'generic'; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts index 141443fd19..37492a1f51 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts @@ -7,9 +7,9 @@ import { css, customElement, html, ifDefined, repeat, state } from '@umbraco-cms import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbFileDropzoneItemStatus } from '@umbraco-cms/backoffice/dropzone'; +import type { UmbModalRouteBuilder } from '@umbraco-cms/backoffice/router'; import '@umbraco-cms/backoffice/imaging'; -import type { UmbModalRouteBuilder } from '@umbraco-cms/backoffice/router'; @customElement('umb-media-grid-collection-view') export class UmbMediaGridCollectionViewElement extends UmbLitElement { @@ -104,7 +104,7 @@ export class UmbMediaGridCollectionViewElement extends UmbLitElement { @selected=${() => this.#onSelect(item)} @deselected=${() => this.#onDeselect(item)}> diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/detail/media-detail.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/detail/media-detail.repository.ts index 3476a5b71a..aa3e6b4892 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/detail/media-detail.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/detail/media-detail.repository.ts @@ -1,13 +1,43 @@ import type { UmbMediaDetailModel } from '../../types.js'; import { UmbMediaServerDataSource } from './media-detail.server.data-source.js'; import { UMB_MEDIA_DETAIL_STORE_CONTEXT } from './media-detail.store.context-token.js'; +import { UmbImagingRepository } from '@umbraco-cms/backoffice/imaging'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbDetailRepositoryBase } from '@umbraco-cms/backoffice/repository'; export class UmbMediaDetailRepository extends UmbDetailRepositoryBase { + #imagingRepository = new UmbImagingRepository(this); constructor(host: UmbControllerHost) { super(host, UmbMediaServerDataSource, UMB_MEDIA_DETAIL_STORE_CONTEXT); } + + /** + * @inheritdoc + */ + override async save(model: UmbMediaDetailModel) { + const result = await super.save(model); + + if (!result.error) { + // Attempt to clear image cache + await this.#imagingRepository._internal_clearCropByUnique(model.unique); + } + + return result; + } + + /** + * @inheritdoc + */ + override async delete(unique: string) { + const result = await super.delete(unique); + + if (!result.error) { + // Attempt to clear image cache + await this.#imagingRepository._internal_clearCropByUnique(unique); + } + + return result; + } } export { UmbMediaDetailRepository as api }; From a0cea4bcb45ec77f3d324219d1b6eff0ccb8cafa Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 26 Aug 2025 13:29:22 +0200 Subject: [PATCH 13/33] build(deps-dev): bump vite from v6 to v7 (#19974) * build(deps-dev): bump vite from 7.1.2 to 7.1.3 * build(deps-dev): bump vite from v6 to v7 --- src/Umbraco.Web.UI.Client/package-lock.json | 10 +- src/Umbraco.Web.UI.Client/package.json | 2 +- src/Umbraco.Web.UI.Login/package-lock.json | 245 ++++++++++---------- src/Umbraco.Web.UI.Login/package.json | 4 +- 4 files changed, 132 insertions(+), 129 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 52a85edae6..79a2fc2595 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -61,7 +61,7 @@ "typescript": "5.9.2", "typescript-eslint": "^8.39.1", "typescript-json-schema": "^0.65.1", - "vite": "^7.1.2", + "vite": "^7.1.3", "vite-plugin-static-copy": "^3.1.2", "vite-tsconfig-paths": "^5.1.4", "web-component-analyzer": "^2.0.0" @@ -16390,14 +16390,14 @@ } }, "node_modules/vite": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.2.tgz", - "integrity": "sha512-J0SQBPlQiEXAF7tajiH+rUooJPo0l8KQgyg4/aMunNtrOa7bwuZJsJbDWzeljqQpgftxuq5yNJxQ91O9ts29UQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.3.tgz", + "integrity": "sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", - "fdir": "^6.4.6", + "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index d50f63f784..96f6663eda 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -259,7 +259,7 @@ "typescript": "5.9.2", "typescript-eslint": "^8.39.1", "typescript-json-schema": "^0.65.1", - "vite": "^7.1.2", + "vite": "^7.1.3", "vite-plugin-static-copy": "^3.1.2", "vite-tsconfig-paths": "^5.1.4", "web-component-analyzer": "^2.0.0" diff --git a/src/Umbraco.Web.UI.Login/package-lock.json b/src/Umbraco.Web.UI.Login/package-lock.json index e13ddcd52b..c46cff217d 100644 --- a/src/Umbraco.Web.UI.Login/package-lock.json +++ b/src/Umbraco.Web.UI.Login/package-lock.json @@ -10,8 +10,8 @@ "@hey-api/openapi-ts": "^0.67.6", "@umbraco-cms/backoffice": "16.0.0-rc4", "msw": "^2.7.0", - "typescript": "^5.8.3", - "vite": "^6.3.5" + "typescript": "^5.9.2", + "vite": "^7.1.3" }, "engines": { "node": ">=22", @@ -687,9 +687,9 @@ "peer": true }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.41.1.tgz", - "integrity": "sha512-NELNvyEWZ6R9QMkiytB4/L4zSEaBC03KIXEghptLGLZWJ6VPrL63ooZQCOnlx36aQPGhzuOMwDerC1Eb2VmrLw==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.47.1.tgz", + "integrity": "sha512-lTahKRJip0knffA/GTNFJMrToD+CM+JJ+Qt5kjzBK/sFQ0EWqfKW3AYQSlZXN98tX0lx66083U9JYIMioMMK7g==", "cpu": [ "arm" ], @@ -701,9 +701,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.41.1.tgz", - "integrity": "sha512-DXdQe1BJ6TK47ukAoZLehRHhfKnKg9BjnQYUu9gzhI8Mwa1d2fzxA1aw2JixHVl403bwp1+/o/NhhHtxWJBgEA==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.47.1.tgz", + "integrity": "sha512-uqxkb3RJLzlBbh/bbNQ4r7YpSZnjgMgyoEOY7Fy6GCbelkDSAzeiogxMG9TfLsBbqmGsdDObo3mzGqa8hps4MA==", "cpu": [ "arm64" ], @@ -715,9 +715,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.1.tgz", - "integrity": "sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.47.1.tgz", + "integrity": "sha512-tV6reObmxBDS4DDyLzTDIpymthNlxrLBGAoQx6m2a7eifSNEZdkXQl1PE4ZjCkEDPVgNXSzND/k9AQ3mC4IOEQ==", "cpu": [ "arm64" ], @@ -729,9 +729,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.1.tgz", - "integrity": "sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.47.1.tgz", + "integrity": "sha512-XuJRPTnMk1lwsSnS3vYyVMu4x/+WIw1MMSiqj5C4j3QOWsMzbJEK90zG+SWV1h0B1ABGCQ0UZUjti+TQK35uHQ==", "cpu": [ "x64" ], @@ -743,9 +743,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.41.1.tgz", - "integrity": "sha512-DBVMZH5vbjgRk3r0OzgjS38z+atlupJ7xfKIDJdZZL6sM6wjfDNo64aowcLPKIx7LMQi8vybB56uh1Ftck/Atg==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.47.1.tgz", + "integrity": "sha512-79BAm8Ag/tmJ5asCqgOXsb3WY28Rdd5Lxj8ONiQzWzy9LvWORd5qVuOnjlqiWWZJw+dWewEktZb5yiM1DLLaHw==", "cpu": [ "arm64" ], @@ -757,9 +757,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.41.1.tgz", - "integrity": "sha512-3FkydeohozEskBxNWEIbPfOE0aqQgB6ttTkJ159uWOFn42VLyfAiyD9UK5mhu+ItWzft60DycIN1Xdgiy8o/SA==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.47.1.tgz", + "integrity": "sha512-OQ2/ZDGzdOOlyfqBiip0ZX/jVFekzYrGtUsqAfLDbWy0jh1PUU18+jYp8UMpqhly5ltEqotc2miLngf9FPSWIA==", "cpu": [ "x64" ], @@ -771,9 +771,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.41.1.tgz", - "integrity": "sha512-wC53ZNDgt0pqx5xCAgNunkTzFE8GTgdZ9EwYGVcg+jEjJdZGtq9xPjDnFgfFozQI/Xm1mh+D9YlYtl+ueswNEg==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.47.1.tgz", + "integrity": "sha512-HZZBXJL1udxlCVvoVadstgiU26seKkHbbAMLg7680gAcMnRNP9SAwTMVet02ANA94kXEI2VhBnXs4e5nf7KG2A==", "cpu": [ "arm" ], @@ -785,9 +785,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.41.1.tgz", - "integrity": "sha512-jwKCca1gbZkZLhLRtsrka5N8sFAaxrGz/7wRJ8Wwvq3jug7toO21vWlViihG85ei7uJTpzbXZRcORotE+xyrLA==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.47.1.tgz", + "integrity": "sha512-sZ5p2I9UA7T950JmuZ3pgdKA6+RTBr+0FpK427ExW0t7n+QwYOcmDTK/aRlzoBrWyTpJNlS3kacgSlSTUg6P/Q==", "cpu": [ "arm" ], @@ -799,9 +799,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.1.tgz", - "integrity": "sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.47.1.tgz", + "integrity": "sha512-3hBFoqPyU89Dyf1mQRXCdpc6qC6At3LV6jbbIOZd72jcx7xNk3aAp+EjzAtN6sDlmHFzsDJN5yeUySvorWeRXA==", "cpu": [ "arm64" ], @@ -813,9 +813,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.1.tgz", - "integrity": "sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.47.1.tgz", + "integrity": "sha512-49J4FnMHfGodJWPw73Ve+/hsPjZgcXQGkmqBGZFvltzBKRS+cvMiWNLadOMXKGnYRhs1ToTGM0sItKISoSGUNA==", "cpu": [ "arm64" ], @@ -827,9 +827,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.41.1.tgz", - "integrity": "sha512-bkCfDJ4qzWfFRCNt5RVV4DOw6KEgFTUZi2r2RuYhGWC8WhCA8lCAJhDeAmrM/fdiAH54m0mA0Vk2FGRPyzI+tw==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.47.1.tgz", + "integrity": "sha512-4yYU8p7AneEpQkRX03pbpLmE21z5JNys16F1BZBZg5fP9rIlb0TkeQjn5du5w4agConCCEoYIG57sNxjryHEGg==", "cpu": [ "loong64" ], @@ -840,10 +840,10 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.41.1.tgz", - "integrity": "sha512-3mr3Xm+gvMX+/8EKogIZSIEF0WUu0HL9di+YWlJpO8CQBnoLAEL/roTCxuLncEdgcfJcvA4UMOf+2dnjl4Ut1A==", + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.47.1.tgz", + "integrity": "sha512-fAiq+J28l2YMWgC39jz/zPi2jqc0y3GSRo1yyxlBHt6UN0yYgnegHSRPa3pnHS5amT/efXQrm0ug5+aNEu9UuQ==", "cpu": [ "ppc64" ], @@ -855,9 +855,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.41.1.tgz", - "integrity": "sha512-3rwCIh6MQ1LGrvKJitQjZFuQnT2wxfU+ivhNBzmxXTXPllewOF7JR1s2vMX/tWtUYFgphygxjqMl76q4aMotGw==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.47.1.tgz", + "integrity": "sha512-daoT0PMENNdjVYYU9xec30Y2prb1AbEIbb64sqkcQcSaR0zYuKkoPuhIztfxuqN82KYCKKrj+tQe4Gi7OSm1ow==", "cpu": [ "riscv64" ], @@ -869,9 +869,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.41.1.tgz", - "integrity": "sha512-LdIUOb3gvfmpkgFZuccNa2uYiqtgZAz3PTzjuM5bH3nvuy9ty6RGc/Q0+HDFrHrizJGVpjnTZ1yS5TNNjFlklw==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.47.1.tgz", + "integrity": "sha512-JNyXaAhWtdzfXu5pUcHAuNwGQKevR+6z/poYQKVW+pLaYOj9G1meYc57/1Xv2u4uTxfu9qEWmNTjv/H/EpAisw==", "cpu": [ "riscv64" ], @@ -883,9 +883,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.41.1.tgz", - "integrity": "sha512-oIE6M8WC9ma6xYqjvPhzZYk6NbobIURvP/lEbh7FWplcMO6gn7MM2yHKA1eC/GvYwzNKK/1LYgqzdkZ8YFxR8g==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.47.1.tgz", + "integrity": "sha512-U/CHbqKSwEQyZXjCpY43/GLYcTVKEXeRHw0rMBJP7fP3x6WpYG4LTJWR3ic6TeYKX6ZK7mrhltP4ppolyVhLVQ==", "cpu": [ "s390x" ], @@ -897,9 +897,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.1.tgz", - "integrity": "sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.47.1.tgz", + "integrity": "sha512-uTLEakjxOTElfeZIGWkC34u2auLHB1AYS6wBjPGI00bWdxdLcCzK5awjs25YXpqB9lS8S0vbO0t9ZcBeNibA7g==", "cpu": [ "x64" ], @@ -911,9 +911,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.41.1.tgz", - "integrity": "sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.47.1.tgz", + "integrity": "sha512-Ft+d/9DXs30BK7CHCTX11FtQGHUdpNDLJW0HHLign4lgMgBcPFN3NkdIXhC5r9iwsMwYreBBc4Rho5ieOmKNVQ==", "cpu": [ "x64" ], @@ -925,9 +925,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.1.tgz", - "integrity": "sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.47.1.tgz", + "integrity": "sha512-N9X5WqGYzZnjGAFsKSfYFtAShYjwOmFJoWbLg3dYixZOZqU7hdMq+/xyS14zKLhFhZDhP9VfkzQnsdk0ZDS9IA==", "cpu": [ "arm64" ], @@ -939,9 +939,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.41.1.tgz", - "integrity": "sha512-+psFT9+pIh2iuGsxFYYa/LhS5MFKmuivRsx9iPJWNSGbh2XVEjk90fmpUEjCnILPEPJnikAU6SFDiEUyOv90Pg==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.47.1.tgz", + "integrity": "sha512-O+KcfeCORZADEY8oQJk4HK8wtEOCRE4MdOkb8qGZQNun3jzmj2nmhV/B/ZaaZOkPmJyvm/gW9n0gsB4eRa1eiQ==", "cpu": [ "ia32" ], @@ -953,9 +953,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.1.tgz", - "integrity": "sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.47.1.tgz", + "integrity": "sha512-CpKnYa8eHthJa3c+C38v/E+/KZyF1Jdh2Cz3DyKZqEWYgrM1IHFArXNWvBLPQCKUEsAqqKX27tTqVEFbDNUcOA==", "cpu": [ "x64" ], @@ -1541,9 +1541,9 @@ "peer": true }, "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, @@ -3116,11 +3116,14 @@ } }, "node_modules/fdir": { - "version": "6.4.4", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", - "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, "peerDependencies": { "picomatch": "^3 || ^4" }, @@ -3534,9 +3537,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.10.tgz", - "integrity": "sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { @@ -3645,9 +3648,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", "engines": { @@ -3677,9 +3680,9 @@ "license": "MIT" }, "node_modules/postcss": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", - "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ { @@ -3697,7 +3700,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.8", + "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -4020,13 +4023,13 @@ "license": "MIT" }, "node_modules/rollup": { - "version": "4.41.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.41.1.tgz", - "integrity": "sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw==", + "version": "4.47.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.47.1.tgz", + "integrity": "sha512-iasGAQoZ5dWDzULEUX3jiW0oB1qyFOepSyDyoU6S/OhVlDIwj5knI5QBa5RRQ0sK7OE0v+8VIi2JuV+G+3tfNg==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.7" + "@types/estree": "1.0.8" }, "bin": { "rollup": "dist/bin/rollup" @@ -4036,26 +4039,26 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.41.1", - "@rollup/rollup-android-arm64": "4.41.1", - "@rollup/rollup-darwin-arm64": "4.41.1", - "@rollup/rollup-darwin-x64": "4.41.1", - "@rollup/rollup-freebsd-arm64": "4.41.1", - "@rollup/rollup-freebsd-x64": "4.41.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.41.1", - "@rollup/rollup-linux-arm-musleabihf": "4.41.1", - "@rollup/rollup-linux-arm64-gnu": "4.41.1", - "@rollup/rollup-linux-arm64-musl": "4.41.1", - "@rollup/rollup-linux-loongarch64-gnu": "4.41.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.41.1", - "@rollup/rollup-linux-riscv64-gnu": "4.41.1", - "@rollup/rollup-linux-riscv64-musl": "4.41.1", - "@rollup/rollup-linux-s390x-gnu": "4.41.1", - "@rollup/rollup-linux-x64-gnu": "4.41.1", - "@rollup/rollup-linux-x64-musl": "4.41.1", - "@rollup/rollup-win32-arm64-msvc": "4.41.1", - "@rollup/rollup-win32-ia32-msvc": "4.41.1", - "@rollup/rollup-win32-x64-msvc": "4.41.1", + "@rollup/rollup-android-arm-eabi": "4.47.1", + "@rollup/rollup-android-arm64": "4.47.1", + "@rollup/rollup-darwin-arm64": "4.47.1", + "@rollup/rollup-darwin-x64": "4.47.1", + "@rollup/rollup-freebsd-arm64": "4.47.1", + "@rollup/rollup-freebsd-x64": "4.47.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.47.1", + "@rollup/rollup-linux-arm-musleabihf": "4.47.1", + "@rollup/rollup-linux-arm64-gnu": "4.47.1", + "@rollup/rollup-linux-arm64-musl": "4.47.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.47.1", + "@rollup/rollup-linux-ppc64-gnu": "4.47.1", + "@rollup/rollup-linux-riscv64-gnu": "4.47.1", + "@rollup/rollup-linux-riscv64-musl": "4.47.1", + "@rollup/rollup-linux-s390x-gnu": "4.47.1", + "@rollup/rollup-linux-x64-gnu": "4.47.1", + "@rollup/rollup-linux-x64-musl": "4.47.1", + "@rollup/rollup-win32-arm64-msvc": "4.47.1", + "@rollup/rollup-win32-ia32-msvc": "4.47.1", + "@rollup/rollup-win32-x64-msvc": "4.47.1", "fsevents": "~2.3.2" } }, @@ -4236,9 +4239,9 @@ } }, "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", "bin": { @@ -4315,24 +4318,24 @@ } }, "node_modules/vite": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", - "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.3.tgz", + "integrity": "sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", - "fdir": "^6.4.4", - "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.14" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -4341,14 +4344,14 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", - "less": "*", + "less": "^4.0.0", "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" diff --git a/src/Umbraco.Web.UI.Login/package.json b/src/Umbraco.Web.UI.Login/package.json index f108d937d2..3e698ee75f 100644 --- a/src/Umbraco.Web.UI.Login/package.json +++ b/src/Umbraco.Web.UI.Login/package.json @@ -18,8 +18,8 @@ "@hey-api/openapi-ts": "^0.67.6", "@umbraco-cms/backoffice": "16.0.0-rc4", "msw": "^2.7.0", - "typescript": "^5.8.3", - "vite": "^6.3.5" + "typescript": "^5.9.2", + "vite": "^7.1.3" }, "msw": { "workerDirectory": [ From 1bd9583cf174a7f31acc7767ebf99498ae8610d6 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 26 Aug 2025 13:40:06 +0200 Subject: [PATCH 14/33] V16: Bump @hey-api/openapi-ts to 0.81.1 (#19982) * build(deps): bump @hey-api/openapi-ts to 0.81.1 and pin the version to ensure compatibility between backoffice and extensions * chore: regenerate api types and replace where necessary * feat: pin version of @hey-api/openapi-ts and regenerate umbraco-extension files * chore: removes unused 'client' field * build(deps-dev): bump @hey-api/openapi-ts to 0.81.1 for the login app --- src/Umbraco.Web.UI.Client/package-lock.json | 223 ++- .../src/apps/installer/installer.context.ts | 11 +- .../apps/upgrader/upgrader-view.element.ts | 4 +- .../src/apps/upgrader/upgrader.element.ts | 4 +- .../src/mocks/data/examine.data.ts | 6 +- .../src/mocks/data/relation/relation.data.ts | 7 +- .../src/mocks/data/relation/relation.db.ts | 4 +- .../handlers/examine-management.handlers.ts | 4 +- .../src/mocks/handlers/install.handlers.ts | 4 +- .../src/mocks/handlers/package.handlers.ts | 16 +- .../src/mocks/handlers/upgrade.handlers.ts | 4 +- .../packages/core/backend-api/client.gen.ts | 2 +- .../core/backend-api/client/client.gen.ts | 240 +++ .../packages/core/backend-api/client/index.ts | 25 + .../core/backend-api/client/types.gen.ts | 268 +++ .../core/backend-api/client/utils.gen.ts | 327 ++++ .../core/backend-api/core/auth.gen.ts | 42 + .../backend-api/core/bodySerializer.gen.ts | 92 + .../core/backend-api/core/params.gen.ts | 153 ++ .../backend-api/core/pathSerializer.gen.ts | 181 ++ .../backend-api/core/serverSentEvents.gen.ts | 237 +++ .../core/backend-api/core/types.gen.ts | 118 ++ .../core/backend-api/core/utils.gen.ts | 114 ++ .../src/packages/core/backend-api/sdk.gen.ts | 43 +- .../packages/core/backend-api/types.gen.ts | 124 +- .../src/packages/core/http-client/index.ts | 1 - .../src/packages/core/openapi-ts.config.js | 2 - .../src/packages/core/package.json | 5 +- .../resources/api-interceptor.controller.ts | 6 +- .../document-validation.server.data-source.ts | 10 +- .../repository/sources/package.server.data.ts | 6 +- .../src/packages/search/types.ts | 7 +- src/Umbraco.Web.UI.Login/openapi-ts.config.ts | 15 +- src/Umbraco.Web.UI.Login/package-lock.json | 1515 ++++++++++------- src/Umbraco.Web.UI.Login/package.json | 7 +- .../src/api/client.gen.ts | 2 +- .../src/api/client/client.gen.ts | 240 +++ .../src/api/client/index.ts | 25 + .../src/api/client/types.gen.ts | 268 +++ .../src/api/client/utils.gen.ts | 327 ++++ .../src/api/core/auth.gen.ts | 42 + .../src/api/core/bodySerializer.gen.ts | 92 + .../src/api/core/params.gen.ts | 153 ++ .../src/api/core/pathSerializer.gen.ts | 181 ++ .../src/api/core/serverSentEvents.gen.ts | 237 +++ .../src/api/core/types.gen.ts | 118 ++ .../src/api/core/utils.gen.ts | 114 ++ src/Umbraco.Web.UI.Login/src/api/sdk.gen.ts | 61 +- src/Umbraco.Web.UI.Login/src/api/types.gen.ts | 199 +-- .../src/contexts/auth.repository.ts | 4 +- .../UmbracoExtension/Client/package.json | 4 +- .../Client/scripts/generate-openapi.js | 2 +- .../Client/src/api/client/client.gen.ts | 65 +- .../Client/src/api/client/types.gen.ts | 66 +- .../Client/src/api/client/utils.gen.ts | 146 +- .../src/api/core/serverSentEvents.gen.ts | 237 +++ .../Client/src/api/core/types.gen.ts | 42 +- .../Client/src/api/core/utils.gen.ts | 114 ++ 58 files changed, 5266 insertions(+), 1300 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/client.gen.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/types.gen.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/utils.gen.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/auth.gen.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/bodySerializer.gen.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/params.gen.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/pathSerializer.gen.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/serverSentEvents.gen.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/types.gen.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/utils.gen.ts create mode 100644 src/Umbraco.Web.UI.Login/src/api/client/client.gen.ts create mode 100644 src/Umbraco.Web.UI.Login/src/api/client/index.ts create mode 100644 src/Umbraco.Web.UI.Login/src/api/client/types.gen.ts create mode 100644 src/Umbraco.Web.UI.Login/src/api/client/utils.gen.ts create mode 100644 src/Umbraco.Web.UI.Login/src/api/core/auth.gen.ts create mode 100644 src/Umbraco.Web.UI.Login/src/api/core/bodySerializer.gen.ts create mode 100644 src/Umbraco.Web.UI.Login/src/api/core/params.gen.ts create mode 100644 src/Umbraco.Web.UI.Login/src/api/core/pathSerializer.gen.ts create mode 100644 src/Umbraco.Web.UI.Login/src/api/core/serverSentEvents.gen.ts create mode 100644 src/Umbraco.Web.UI.Login/src/api/core/types.gen.ts create mode 100644 src/Umbraco.Web.UI.Login/src/api/core/utils.gen.ts create mode 100644 templates/UmbracoExtension/Client/src/api/core/serverSentEvents.gen.ts create mode 100644 templates/UmbracoExtension/Client/src/api/core/utils.gen.ts diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 79a2fc2595..2288fa8383 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -1034,7 +1034,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/@hey-api/json-schema-ref-parser/-/json-schema-ref-parser-1.0.6.tgz", "integrity": "sha512-yktiFZoWPtEW8QKS65eqKwA5MTKp88CyiL8q72WynrBs/73SAaxlSWlA2zW/DZlywZ5hX1OYzrCC0wFdvO9c2w==", - "dev": true, "license": "MIT", "dependencies": { "@jsdevtools/ono": "^7.1.3", @@ -1050,10 +1049,9 @@ } }, "node_modules/@hey-api/openapi-ts": { - "version": "0.71.1", - "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.71.1.tgz", - "integrity": "sha512-LZhHH1CngE2vRgMdZGRI4UrxJ/JHvcsAy4Qjsbiu9BGWyZIraIqWLMsQgqB3TU5yJTrblFo9DA7RI5LIUol0yg==", - "dev": true, + "version": "0.81.1", + "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.81.1.tgz", + "integrity": "sha512-DdLEMbfQRMRDd+cOxG91G7Ro7vUUtt/zYlBGiYTahVO/4rn1HHnYl/WHL+to5I7CTX3sVVsVrxHWcJd0Fue7wg==", "license": "MIT", "dependencies": { "@hey-api/json-schema-ref-parser": "1.0.6", @@ -1061,7 +1059,10 @@ "c12": "2.0.1", "color-support": "1.1.3", "commander": "13.0.0", - "handlebars": "4.7.8" + "handlebars": "4.7.8", + "js-yaml": "4.1.0", + "open": "10.1.2", + "semver": "7.7.2" }, "bin": { "openapi-ts": "bin/index.cjs" @@ -1076,6 +1077,63 @@ "typescript": "^5.5.3" } }, + "node_modules/@hey-api/openapi-ts/node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@hey-api/openapi-ts/node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@hey-api/openapi-ts/node_modules/open": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.2.tgz", + "integrity": "sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==", + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@hey-api/openapi-ts/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -1214,7 +1272,6 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", - "dev": true, "license": "MIT" }, "node_modules/@lit-labs/ssr-dom-shim": { @@ -2985,7 +3042,6 @@ "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, "license": "MIT" }, "node_modules/@types/json5": { @@ -5081,7 +5137,6 @@ "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -5144,7 +5199,6 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -5768,6 +5822,21 @@ "node": "*" } }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -5782,7 +5851,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/c12/-/c12-2.0.1.tgz", "integrity": "sha512-Z4JgsKXHG37C6PYUtIxCfLJZvo6FyhHJoClwwb9ftUkLpPSkuYqn6Tr+vnaN8hymm0kIbcg6Ey3kv/Q71k5w/A==", - "dev": true, "license": "MIT", "dependencies": { "chokidar": "^4.0.1", @@ -6031,7 +6099,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, "license": "MIT", "dependencies": { "readdirp": "^4.0.1" @@ -6047,7 +6114,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, "license": "ISC", "engines": { "node": ">=10" @@ -6090,7 +6156,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", - "dev": true, "license": "MIT", "dependencies": { "consola": "^3.2.3" @@ -6227,7 +6292,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, "license": "ISC", "bin": { "color-support": "bin.js" @@ -6295,7 +6359,6 @@ "version": "13.0.0", "resolved": "https://registry.npmjs.org/commander/-/commander-13.0.0.tgz", "integrity": "sha512-oPYleIY8wmTVzkvQq10AEok6YcTC4sRUBl8F9gVuwchGVUCTbl/vhLTaQqutuuySYOsu8YTgV+OxKc/8Yvx+mQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -6329,14 +6392,12 @@ "version": "0.1.8", "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", - "dev": true, "license": "MIT" }, "node_modules/consola": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", - "dev": true, "license": "MIT", "engines": { "node": "^14.18.0 || >=16.10.0" @@ -6782,6 +6843,34 @@ "node": ">=0.10.0" } }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/default-gateway": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", @@ -6868,7 +6957,6 @@ "version": "6.1.4", "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", - "dev": true, "license": "MIT" }, "node_modules/degenerator": { @@ -6956,7 +7044,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", - "dev": true, "license": "MIT" }, "node_modules/destroy": { @@ -7247,7 +7334,6 @@ "version": "16.6.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -8452,7 +8538,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, "license": "ISC", "dependencies": { "minipass": "^3.0.0" @@ -8465,7 +8550,6 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, "license": "ISC", "dependencies": { "yallist": "^4.0.0" @@ -8478,7 +8562,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, "license": "ISC" }, "node_modules/fs.realpath": { @@ -8687,7 +8770,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/giget/-/giget-1.2.5.tgz", "integrity": "sha512-r1ekGw/Bgpi3HLV3h1MRBIlSAdHoIMklpaQ3OQLFcRw9PwAj2rqigvIbg+dBUI51OxVI2jsEtDywDBjSiuf7Ug==", - "dev": true, "license": "MIT", "dependencies": { "citty": "^0.1.6", @@ -8706,7 +8788,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, "license": "MIT" }, "node_modules/glob": { @@ -8866,7 +8947,6 @@ "version": "4.7.8", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, "license": "MIT", "dependencies": { "minimist": "^1.2.5", @@ -8888,7 +8968,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -9538,6 +9617,39 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -9952,7 +10064,6 @@ "version": "2.5.1", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", - "dev": true, "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" @@ -9986,7 +10097,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -10314,7 +10424,6 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, "license": "MIT" }, "node_modules/lodash.camelcase": { @@ -11493,7 +11602,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -11503,7 +11611,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, "license": "ISC", "engines": { "node": ">=8" @@ -11513,7 +11620,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, "license": "MIT", "dependencies": { "minipass": "^3.0.0", @@ -11527,7 +11633,6 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, "license": "ISC", "dependencies": { "yallist": "^4.0.0" @@ -11540,7 +11645,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, "license": "ISC" }, "node_modules/mitt": { @@ -11554,7 +11658,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" @@ -11567,7 +11670,6 @@ "version": "1.7.4", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", - "dev": true, "license": "MIT", "dependencies": { "acorn": "^8.14.0", @@ -11580,7 +11682,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, "license": "MIT" }, "node_modules/module-definition": { @@ -11821,7 +11922,6 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, "license": "MIT" }, "node_modules/netmask": { @@ -11858,7 +11958,6 @@ "version": "1.6.7", "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", - "dev": true, "license": "MIT" }, "node_modules/node-fetch/node_modules/tr46": { @@ -11943,7 +12042,6 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.5.4.tgz", "integrity": "sha512-X0SNNrZiGU8/e/zAB7sCTtdxWTMSIO73q+xuKgglm2Yvzwlo8UoC5FNySQFCvl84uPaeADkqHUZUkWy4aH4xOA==", - "dev": true, "license": "MIT", "dependencies": { "citty": "^0.1.6", @@ -11964,7 +12062,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, "license": "MIT" }, "node_modules/object-inspect": { @@ -12068,7 +12165,6 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.6.tgz", "integrity": "sha512-TBu7PtV8YkAZn0tSxobKY2n2aAQva936lhRrj6957aDaCf9IEtqsKbgMzXE/F/sjqYOwmrukeORHNLe5glk7Cg==", - "dev": true, "license": "MIT" }, "node_modules/on-finished": { @@ -12457,7 +12553,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true, "license": "MIT" }, "node_modules/pathval": { @@ -12481,7 +12576,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", - "dev": true, "license": "MIT" }, "node_modules/picocolors": { @@ -12518,7 +12612,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", - "dev": true, "license": "MIT", "dependencies": { "confbox": "^0.1.8", @@ -12530,7 +12623,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, "license": "MIT" }, "node_modules/playwright": { @@ -13954,7 +14046,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", - "dev": true, "license": "MIT", "dependencies": { "defu": "^6.1.4", @@ -14013,7 +14104,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 14.18.0" @@ -14393,6 +14483,18 @@ "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==", "license": "MIT" }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -15318,7 +15420,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dev": true, "license": "ISC", "dependencies": { "chownr": "^2.0.0", @@ -15363,7 +15464,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, "license": "ISC" }, "node_modules/text-decoder": { @@ -15412,7 +15512,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true, "license": "MIT" }, "node_modules/tinyglobby": { @@ -16086,14 +16185,12 @@ "version": "1.6.1", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", - "dev": true, "license": "MIT" }, "node_modules/uglify-js": { "version": "3.19.3", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "dev": true, "license": "BSD-2-Clause", "optional": true, "bin": { @@ -16803,7 +16900,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, "license": "MIT" }, "node_modules/wordwrapjs": { @@ -17070,23 +17166,10 @@ "src/packages/core": { "name": "@umbraco-backoffice/core", "dependencies": { - "@hey-api/client-fetch": "^0.12.0", + "@hey-api/openapi-ts": "0.81.1", "@types/diff": "^7.0.2", "diff": "^7.0.0", "uuid": "^11.1.0" - }, - "devDependencies": { - "@hey-api/openapi-ts": "^0.71.0" - } - }, - "src/packages/core/node_modules/@hey-api/client-fetch": { - "version": "0.12.0", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/hey-api" - }, - "peerDependencies": { - "@hey-api/openapi-ts": "< 2" } }, "src/packages/core/node_modules/diff": { 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 b638c1d94e..500922d9ab 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 @@ -1,8 +1,5 @@ import type { Observable } from '@umbraco-cms/backoffice/external/rxjs'; -import type { - InstallSettingsResponseModel, - InstallRequestModelReadable, -} from '@umbraco-cms/backoffice/external/backend-api'; +import type { InstallSettingsResponseModel, InstallRequestModel } from '@umbraco-cms/backoffice/external/backend-api'; import { InstallService, TelemetryLevelModel } from '@umbraco-cms/backoffice/external/backend-api'; import { tryExecute, UmbApiError, type UmbProblemDetails } from '@umbraco-cms/backoffice/resources'; import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; @@ -15,7 +12,7 @@ import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; * @class UmbInstallerContext */ export class UmbInstallerContext extends UmbContextBase { - private _data = new UmbObjectState({ + private _data = new UmbObjectState({ user: { name: '', email: '', password: '', subscribeToNewsletter: false }, database: { id: '', providerName: '', useIntegratedAuthentication: false, trustServerCertificate: false }, telemetryLevel: TelemetryLevelModel.DETAILED, @@ -90,7 +87,7 @@ export class UmbInstallerContext extends UmbContextBase { * @param {Partial} data The data to set * @memberof UmbInstallerContext */ - public appendData(data: Partial): void { + public appendData(data: Partial): void { this._data.setValue({ ...this.getData(), ...data }); } @@ -100,7 +97,7 @@ export class UmbInstallerContext extends UmbContextBase { * @returns {*} {PostInstallRequest} * @memberof UmbInstallerContext */ - public getData(): InstallRequestModelReadable { + public getData(): InstallRequestModel { return this._data.getValue(); } diff --git a/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader-view.element.ts b/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader-view.element.ts index 21fc60d6db..8ea5de2147 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader-view.element.ts @@ -1,6 +1,6 @@ import type { CSSResultGroup } from '@umbraco-cms/backoffice/external/lit'; import { css, html, LitElement, customElement, property, ifDefined } from '@umbraco-cms/backoffice/external/lit'; -import type { UpgradeSettingsResponseModelReadable } from '@umbraco-cms/backoffice/external/backend-api'; +import type { UpgradeSettingsResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; /** * @element umb-upgrader-view @@ -18,7 +18,7 @@ export class UmbUpgraderViewElement extends LitElement { errorMessage = ''; @property({ type: Object, reflect: true }) - settings?: UpgradeSettingsResponseModelReadable; + settings?: UpgradeSettingsResponseModel; private _renderLayout() { return html` diff --git a/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader.element.ts b/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader.element.ts index fa1b105c48..5107af5c8d 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader.element.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader.element.ts @@ -1,5 +1,5 @@ import { html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; -import type { UpgradeSettingsResponseModelReadable } from '@umbraco-cms/backoffice/external/backend-api'; +import type { UpgradeSettingsResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { UpgradeService } from '@umbraco-cms/backoffice/external/backend-api'; import { tryExecute, UmbApiError } from '@umbraco-cms/backoffice/resources'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -13,7 +13,7 @@ import './upgrader-view.element.js'; @customElement('umb-upgrader') export class UmbUpgraderElement extends UmbLitElement { @state() - private _upgradeSettings?: UpgradeSettingsResponseModelReadable; + private _upgradeSettings?: UpgradeSettingsResponseModel; @state() private _fetching = true; diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/examine.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/examine.data.ts index 4c04edc1ea..d639085407 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/examine.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/examine.data.ts @@ -1,7 +1,7 @@ import type { IndexResponseModel, PagedIndexResponseModel, - SearchResultResponseModelReadable, + SearchResultResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; import { HealthStatusModel } from '@umbraco-cms/backoffice/external/backend-api'; @@ -19,7 +19,7 @@ export function getIndexByName(indexName: string) { /** * */ -export function getSearchResultsMockData(): SearchResultResponseModelReadable[] { +export function getSearchResultsMockData(): SearchResultResponseModel[] { return searchResultMockData; } @@ -91,7 +91,7 @@ export const PagedIndexers: PagedIndexResponseModel = { total: 0, }; -export const searchResultMockData: SearchResultResponseModelReadable[] = [ +export const searchResultMockData: SearchResultResponseModel[] = [ { id: '1', score: 1, diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.data.ts index be5d35b460..11a9228118 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.data.ts @@ -1,9 +1,6 @@ -import type { - RelationResponseModelReadable, - RelationReferenceModel, -} from '@umbraco-cms/backoffice/external/backend-api'; +import type { RelationResponseModel, RelationReferenceModel } from '@umbraco-cms/backoffice/external/backend-api'; -export type UmbMockRelationModel = RelationResponseModelReadable; +export type UmbMockRelationModel = RelationResponseModel; export type UmbMockRelationReferenceModel = RelationReferenceModel; export const data: Array = [ diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.db.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.db.ts index d885a524af..122b1506cb 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.db.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.db.ts @@ -2,7 +2,7 @@ import { UmbMockEntityDetailManager } from '../utils/entity/entity-detail.manage import { UmbEntityMockDbBase } from '../utils/entity/entity-base.js'; import type { UmbMockRelationModel } from './relation.data.js'; import { data } from './relation.data.js'; -import type { RelationResponseModelReadable } from '@umbraco-cms/backoffice/external/backend-api'; +import type { RelationResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; class UmbRelationMockDB extends UmbEntityMockDbBase { item = new UmbMockEntityDetailManager(this, itemResponseMapper, createDetailMockMapper); @@ -16,7 +16,7 @@ const createDetailMockMapper = (): UmbMockRelationModel => { throw new Error('Not possible to create a relation'); }; -const itemResponseMapper = (item: UmbMockRelationModel): RelationResponseModelReadable => { +const itemResponseMapper = (item: UmbMockRelationModel): RelationResponseModel => { return { id: item.id, child: item.child, diff --git a/src/Umbraco.Web.UI.Client/src/mocks/handlers/examine-management.handlers.ts b/src/Umbraco.Web.UI.Client/src/mocks/handlers/examine-management.handlers.ts index feb5d83ac5..51fca662e2 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/handlers/examine-management.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/handlers/examine-management.handlers.ts @@ -6,7 +6,7 @@ import type { IndexResponseModel, PagedIndexResponseModel, PagedSearcherResponseModel, - PagedSearchResultResponseModelReadable, + PagedSearchResultResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; export const handlers = [ @@ -65,7 +65,7 @@ export const handlers = [ if (searcherName) { return res( ctx.status(200), - ctx.json({ + ctx.json({ total: 0, items: searchResultMockData, }), diff --git a/src/Umbraco.Web.UI.Client/src/mocks/handlers/install.handlers.ts b/src/Umbraco.Web.UI.Client/src/mocks/handlers/install.handlers.ts index 01b96ab3aa..8a259c12f4 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/handlers/install.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/handlers/install.handlers.ts @@ -1,7 +1,7 @@ const { rest } = window.MockServiceWorker; import type { DatabaseInstallRequestModel, - InstallRequestModelReadable, + InstallRequestModel, InstallSettingsResponseModel, ProblemDetails, } from '@umbraco-cms/backoffice/external/backend-api'; @@ -99,7 +99,7 @@ export const handlers = [ }), rest.post(umbracoPath('/install/setup'), async (req, res, ctx) => { - const body = await req.json(); + const body = await req.json(); if (body.database?.name === 'fail') { return res( diff --git a/src/Umbraco.Web.UI.Client/src/mocks/handlers/package.handlers.ts b/src/Umbraco.Web.UI.Client/src/mocks/handlers/package.handlers.ts index a58cb2b86a..144a1f3848 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/handlers/package.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/handlers/package.handlers.ts @@ -6,8 +6,8 @@ import type { PagedPackageMigrationStatusResponseModel, CreatePackageRequestModel, GetPackageConfigurationResponse, - PagedPackageDefinitionResponseModelReadable, - PackageDefinitionResponseModelReadable, + PagedPackageDefinitionResponseModel, + PackageDefinitionResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; export const handlers = [ @@ -55,7 +55,7 @@ export const handlers = [ // read all return res( ctx.status(200), - ctx.json({ + ctx.json({ total: packageArray.length, items: packageArray, }), @@ -65,9 +65,9 @@ export const handlers = [ rest.post(umbracoPath('/package/created'), async (_req, res, ctx) => { //save const data: CreatePackageRequestModel = await _req.json(); - const newPackage: PackageDefinitionResponseModelReadable = { ...data, id: UmbId.new(), packagePath: '' }; + const newPackage: PackageDefinitionResponseModel = { ...data, id: UmbId.new(), packagePath: '' }; packageArray.push(newPackage); - return res(ctx.status(200), ctx.json(newPackage)); + return res(ctx.status(200), ctx.json(newPackage)); }), rest.get(umbracoPath('/package/created/:id'), (_req, res, ctx) => { @@ -76,12 +76,12 @@ export const handlers = [ if (!id) return res(ctx.status(404)); const found = packageArray.find((p) => p.id == id); if (!found) return res(ctx.status(404)); - return res(ctx.status(200), ctx.json(found)); + return res(ctx.status(200), ctx.json(found)); }), rest.put(umbracoPath('/package/created/:id'), async (_req, res, ctx) => { //update - const data: PackageDefinitionResponseModelReadable = await _req.json(); + const data: PackageDefinitionResponseModel = await _req.json(); if (!data.id) return; const index = packageArray.findIndex((x) => x.id === data.id); packageArray[index] = data; @@ -104,7 +104,7 @@ export const handlers = [ }), ]; -const packageArray: PackageDefinitionResponseModelReadable[] = [ +const packageArray: PackageDefinitionResponseModel[] = [ { id: '2a0181ec-244b-4068-a1d7-2f95ed7e6da6', packagePath: '', diff --git a/src/Umbraco.Web.UI.Client/src/mocks/handlers/upgrade.handlers.ts b/src/Umbraco.Web.UI.Client/src/mocks/handlers/upgrade.handlers.ts index 61031c5ae7..6c733ed23f 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/handlers/upgrade.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/handlers/upgrade.handlers.ts @@ -1,14 +1,14 @@ const { rest } = window.MockServiceWorker; import { umbracoPath } from '@umbraco-cms/backoffice/utils'; -import type { UpgradeSettingsResponseModelReadable } from '@umbraco-cms/backoffice/external/backend-api'; +import type { UpgradeSettingsResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; export const handlers = [ rest.get(umbracoPath('/upgrade/settings'), (_req, res, ctx) => { return res( // Respond with a 200 status code ctx.status(200), - ctx.json({ + ctx.json({ currentState: '2b20c6e7', newState: '2b20c6e8', oldVersion: '13.0.0', diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client.gen.ts index fd97b4b69e..ee0c0bd98e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client.gen.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import type { ClientOptions } from './types.gen'; -import { type Config, type ClientOptions as DefaultClientOptions, createClient, createConfig } from '@hey-api/client-fetch'; +import { type Config, type ClientOptions as DefaultClientOptions, createClient, createConfig } from './client'; /** * The `createClientConfig()` function will be called on client initialization diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/client.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/client.gen.ts new file mode 100644 index 0000000000..0c60a9ab77 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/client.gen.ts @@ -0,0 +1,240 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { createSseClient } from '../core/serverSentEvents.gen'; +import type { HttpMethod } from '../core/types.gen'; +import type { + Client, + Config, + RequestOptions, + ResolvedRequestOptions, +} from './types.gen'; +import { + buildUrl, + createConfig, + createInterceptors, + getParseAs, + mergeConfigs, + mergeHeaders, + setAuthParams, +} from './utils.gen'; + +type ReqInit = Omit & { + body?: any; + headers: ReturnType; +}; + +export const createClient = (config: Config = {}): Client => { + let _config = mergeConfigs(createConfig(), config); + + const getConfig = (): Config => ({ ..._config }); + + const setConfig = (config: Config): Config => { + _config = mergeConfigs(_config, config); + return getConfig(); + }; + + const interceptors = createInterceptors< + Request, + Response, + unknown, + ResolvedRequestOptions + >(); + + const beforeRequest = async (options: RequestOptions) => { + const opts = { + ..._config, + ...options, + fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, + headers: mergeHeaders(_config.headers, options.headers), + serializedBody: undefined, + }; + + if (opts.security) { + await setAuthParams({ + ...opts, + security: opts.security, + }); + } + + if (opts.requestValidator) { + await opts.requestValidator(opts); + } + + if (opts.body && opts.bodySerializer) { + opts.serializedBody = opts.bodySerializer(opts.body); + } + + // remove Content-Type header if body is empty to avoid sending invalid requests + if (opts.serializedBody === undefined || opts.serializedBody === '') { + opts.headers.delete('Content-Type'); + } + + const url = buildUrl(opts); + + return { opts, url }; + }; + + const request: Client['request'] = async (options) => { + // @ts-expect-error + const { opts, url } = await beforeRequest(options); + const requestInit: ReqInit = { + redirect: 'follow', + ...opts, + body: opts.serializedBody, + }; + + let request = new Request(url, requestInit); + + for (const fn of interceptors.request._fns) { + if (fn) { + request = await fn(request, opts); + } + } + + // fetch must be assigned here, otherwise it would throw the error: + // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation + const _fetch = opts.fetch!; + let response = await _fetch(request); + + for (const fn of interceptors.response._fns) { + if (fn) { + response = await fn(response, request, opts); + } + } + + const result = { + request, + response, + }; + + if (response.ok) { + if ( + response.status === 204 || + response.headers.get('Content-Length') === '0' + ) { + return opts.responseStyle === 'data' + ? {} + : { + data: {}, + ...result, + }; + } + + const parseAs = + (opts.parseAs === 'auto' + ? getParseAs(response.headers.get('Content-Type')) + : opts.parseAs) ?? 'json'; + + let data: any; + switch (parseAs) { + case 'arrayBuffer': + case 'blob': + case 'formData': + case 'json': + case 'text': + data = await response[parseAs](); + break; + case 'stream': + return opts.responseStyle === 'data' + ? response.body + : { + data: response.body, + ...result, + }; + } + + if (parseAs === 'json') { + if (opts.responseValidator) { + await opts.responseValidator(data); + } + + if (opts.responseTransformer) { + data = await opts.responseTransformer(data); + } + } + + return opts.responseStyle === 'data' + ? data + : { + data, + ...result, + }; + } + + const textError = await response.text(); + let jsonError: unknown; + + try { + jsonError = JSON.parse(textError); + } catch { + // noop + } + + const error = jsonError ?? textError; + let finalError = error; + + for (const fn of interceptors.error._fns) { + if (fn) { + finalError = (await fn(error, response, request, opts)) as string; + } + } + + finalError = finalError || ({} as string); + + if (opts.throwOnError) { + throw finalError; + } + + // TODO: we probably want to return error and improve types + return opts.responseStyle === 'data' + ? undefined + : { + error: finalError, + ...result, + }; + }; + + const makeMethodFn = + (method: Uppercase) => (options: RequestOptions) => + request({ ...options, method }); + + const makeSseFn = + (method: Uppercase) => async (options: RequestOptions) => { + const { opts, url } = await beforeRequest(options); + return createSseClient({ + ...opts, + body: opts.body as BodyInit | null | undefined, + headers: opts.headers as unknown as Record, + method, + url, + }); + }; + + return { + buildUrl, + connect: makeMethodFn('CONNECT'), + delete: makeMethodFn('DELETE'), + get: makeMethodFn('GET'), + getConfig, + head: makeMethodFn('HEAD'), + interceptors, + options: makeMethodFn('OPTIONS'), + patch: makeMethodFn('PATCH'), + post: makeMethodFn('POST'), + put: makeMethodFn('PUT'), + request, + setConfig, + sse: { + connect: makeSseFn('CONNECT'), + delete: makeSseFn('DELETE'), + get: makeSseFn('GET'), + head: makeSseFn('HEAD'), + options: makeSseFn('OPTIONS'), + patch: makeSseFn('PATCH'), + post: makeSseFn('POST'), + put: makeSseFn('PUT'), + trace: makeSseFn('TRACE'), + }, + trace: makeMethodFn('TRACE'), + } as Client; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/index.ts new file mode 100644 index 0000000000..318a84b6a8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/index.ts @@ -0,0 +1,25 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type { Auth } from '../core/auth.gen'; +export type { QuerySerializerOptions } from '../core/bodySerializer.gen'; +export { + formDataBodySerializer, + jsonBodySerializer, + urlSearchParamsBodySerializer, +} from '../core/bodySerializer.gen'; +export { buildClientParams } from '../core/params.gen'; +export { createClient } from './client.gen'; +export type { + Client, + ClientOptions, + Config, + CreateClientConfig, + Options, + OptionsLegacyParser, + RequestOptions, + RequestResult, + ResolvedRequestOptions, + ResponseStyle, + TDataShape, +} from './types.gen'; +export { createConfig, mergeHeaders } from './utils.gen'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/types.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/types.gen.ts new file mode 100644 index 0000000000..5bde93851e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/types.gen.ts @@ -0,0 +1,268 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Auth } from '../core/auth.gen'; +import type { + ServerSentEventsOptions, + ServerSentEventsResult, +} from '../core/serverSentEvents.gen'; +import type { + Client as CoreClient, + Config as CoreConfig, +} from '../core/types.gen'; +import type { Middleware } from './utils.gen'; + +export type ResponseStyle = 'data' | 'fields'; + +export interface Config + extends Omit, + CoreConfig { + /** + * Base URL for all requests made by this client. + */ + baseUrl?: T['baseUrl']; + /** + * Fetch API implementation. You can use this option to provide a custom + * fetch instance. + * + * @default globalThis.fetch + */ + fetch?: (request: Request) => ReturnType; + /** + * Please don't use the Fetch client for Next.js applications. The `next` + * options won't have any effect. + * + * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead. + */ + next?: never; + /** + * Return the response data parsed in a specified format. By default, `auto` + * will infer the appropriate method from the `Content-Type` response header. + * You can override this behavior with any of the {@link Body} methods. + * Select `stream` if you don't want to parse response data at all. + * + * @default 'auto' + */ + parseAs?: + | 'arrayBuffer' + | 'auto' + | 'blob' + | 'formData' + | 'json' + | 'stream' + | 'text'; + /** + * Should we return only data or multiple fields (data, error, response, etc.)? + * + * @default 'fields' + */ + responseStyle?: ResponseStyle; + /** + * Throw an error instead of returning it in the response? + * + * @default false + */ + throwOnError?: T['throwOnError']; +} + +export interface RequestOptions< + TData = unknown, + TResponseStyle extends ResponseStyle = 'fields', + ThrowOnError extends boolean = boolean, + Url extends string = string, +> extends Config<{ + responseStyle: TResponseStyle; + throwOnError: ThrowOnError; + }>, + Pick< + ServerSentEventsOptions, + | 'onSseError' + | 'onSseEvent' + | 'sseDefaultRetryDelay' + | 'sseMaxRetryAttempts' + | 'sseMaxRetryDelay' + > { + /** + * Any body that you want to add to your request. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} + */ + body?: unknown; + path?: Record; + query?: Record; + /** + * Security mechanism(s) to use for the request. + */ + security?: ReadonlyArray; + url: Url; +} + +export interface ResolvedRequestOptions< + TResponseStyle extends ResponseStyle = 'fields', + ThrowOnError extends boolean = boolean, + Url extends string = string, +> extends RequestOptions { + serializedBody?: string; +} + +export type RequestResult< + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = boolean, + TResponseStyle extends ResponseStyle = 'fields', +> = ThrowOnError extends true + ? Promise< + TResponseStyle extends 'data' + ? TData extends Record + ? TData[keyof TData] + : TData + : { + data: TData extends Record + ? TData[keyof TData] + : TData; + request: Request; + response: Response; + } + > + : Promise< + TResponseStyle extends 'data' + ? + | (TData extends Record + ? TData[keyof TData] + : TData) + | undefined + : ( + | { + data: TData extends Record + ? TData[keyof TData] + : TData; + error: undefined; + } + | { + data: undefined; + error: TError extends Record + ? TError[keyof TError] + : TError; + } + ) & { + request: Request; + response: Response; + } + >; + +export interface ClientOptions { + baseUrl?: string; + responseStyle?: ResponseStyle; + throwOnError?: boolean; +} + +type MethodFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'>, +) => RequestResult; + +type SseFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'>, +) => Promise>; + +type RequestFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'> & + Pick< + Required>, + 'method' + >, +) => RequestResult; + +type BuildUrlFn = < + TData extends { + body?: unknown; + path?: Record; + query?: Record; + url: string; + }, +>( + options: Pick & Options, +) => string; + +export type Client = CoreClient< + RequestFn, + Config, + MethodFn, + BuildUrlFn, + SseFn +> & { + interceptors: Middleware; +}; + +/** + * The `createClientConfig()` function will be called on client initialization + * and the returned object will become the client's initial configuration. + * + * You may want to initialize your client this way instead of calling + * `setConfig()`. This is useful for example if you're using Next.js + * to ensure your client always has the correct values. + */ +export type CreateClientConfig = ( + override?: Config, +) => Config & T>; + +export interface TDataShape { + body?: unknown; + headers?: unknown; + path?: unknown; + query?: unknown; + url: string; +} + +type OmitKeys = Pick>; + +export type Options< + TData extends TDataShape = TDataShape, + ThrowOnError extends boolean = boolean, + TResponse = unknown, + TResponseStyle extends ResponseStyle = 'fields', +> = OmitKeys< + RequestOptions, + 'body' | 'path' | 'query' | 'url' +> & + Omit; + +export type OptionsLegacyParser< + TData = unknown, + ThrowOnError extends boolean = boolean, + TResponseStyle extends ResponseStyle = 'fields', +> = TData extends { body?: any } + ? TData extends { headers?: any } + ? OmitKeys< + RequestOptions, + 'body' | 'headers' | 'url' + > & + TData + : OmitKeys< + RequestOptions, + 'body' | 'url' + > & + TData & + Pick, 'headers'> + : TData extends { headers?: any } + ? OmitKeys< + RequestOptions, + 'headers' | 'url' + > & + TData & + Pick, 'body'> + : OmitKeys, 'url'> & + TData; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/utils.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/utils.gen.ts new file mode 100644 index 0000000000..a47509522b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/utils.gen.ts @@ -0,0 +1,327 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { getAuthToken } from '../core/auth.gen'; +import type { QuerySerializerOptions } from '../core/bodySerializer.gen'; +import { jsonBodySerializer } from '../core/bodySerializer.gen'; +import { + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from '../core/pathSerializer.gen'; +import { getUrl } from '../core/utils.gen'; +import type { Client, ClientOptions, Config, RequestOptions } from './types.gen'; + +export const createQuerySerializer = ({ + allowReserved, + array, + object, +}: QuerySerializerOptions = {}) => { + const querySerializer = (queryParams: T) => { + const search: string[] = []; + if (queryParams && typeof queryParams === 'object') { + for (const name in queryParams) { + const value = queryParams[name]; + + if (value === undefined || value === null) { + continue; + } + + if (Array.isArray(value)) { + const serializedArray = serializeArrayParam({ + allowReserved, + explode: true, + name, + style: 'form', + value, + ...array, + }); + if (serializedArray) search.push(serializedArray); + } else if (typeof value === 'object') { + const serializedObject = serializeObjectParam({ + allowReserved, + explode: true, + name, + style: 'deepObject', + value: value as Record, + ...object, + }); + if (serializedObject) search.push(serializedObject); + } else { + const serializedPrimitive = serializePrimitiveParam({ + allowReserved, + name, + value: value as string, + }); + if (serializedPrimitive) search.push(serializedPrimitive); + } + } + } + return search.join('&'); + }; + return querySerializer; +}; + +/** + * Infers parseAs value from provided Content-Type header. + */ +export const getParseAs = ( + contentType: string | null, +): Exclude => { + if (!contentType) { + // If no Content-Type header is provided, the best we can do is return the raw response body, + // which is effectively the same as the 'stream' option. + return 'stream'; + } + + const cleanContent = contentType.split(';')[0]?.trim(); + + if (!cleanContent) { + return; + } + + if ( + cleanContent.startsWith('application/json') || + cleanContent.endsWith('+json') + ) { + return 'json'; + } + + if (cleanContent === 'multipart/form-data') { + return 'formData'; + } + + if ( + ['application/', 'audio/', 'image/', 'video/'].some((type) => + cleanContent.startsWith(type), + ) + ) { + return 'blob'; + } + + if (cleanContent.startsWith('text/')) { + return 'text'; + } + + return; +}; + +const checkForExistence = ( + options: Pick & { + headers: Headers; + }, + name?: string, +): boolean => { + if (!name) { + return false; + } + if ( + options.headers.has(name) || + options.query?.[name] || + options.headers.get('Cookie')?.includes(`${name}=`) + ) { + return true; + } + return false; +}; + +export const setAuthParams = async ({ + security, + ...options +}: Pick, 'security'> & + Pick & { + headers: Headers; + }) => { + for (const auth of security) { + if (checkForExistence(options, auth.name)) { + continue; + } + + const token = await getAuthToken(auth, options.auth); + + if (!token) { + continue; + } + + const name = auth.name ?? 'Authorization'; + + switch (auth.in) { + case 'query': + if (!options.query) { + options.query = {}; + } + options.query[name] = token; + break; + case 'cookie': + options.headers.append('Cookie', `${name}=${token}`); + break; + case 'header': + default: + options.headers.set(name, token); + break; + } + } +}; + +export const buildUrl: Client['buildUrl'] = (options) => + getUrl({ + baseUrl: options.baseUrl as string, + path: options.path, + query: options.query, + querySerializer: + typeof options.querySerializer === 'function' + ? options.querySerializer + : createQuerySerializer(options.querySerializer), + url: options.url, + }); + +export const mergeConfigs = (a: Config, b: Config): Config => { + const config = { ...a, ...b }; + if (config.baseUrl?.endsWith('/')) { + config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1); + } + config.headers = mergeHeaders(a.headers, b.headers); + return config; +}; + +export const mergeHeaders = ( + ...headers: Array['headers'] | undefined> +): Headers => { + const mergedHeaders = new Headers(); + for (const header of headers) { + if (!header || typeof header !== 'object') { + continue; + } + + const iterator = + header instanceof Headers ? header.entries() : Object.entries(header); + + for (const [key, value] of iterator) { + if (value === null) { + mergedHeaders.delete(key); + } else if (Array.isArray(value)) { + for (const v of value) { + mergedHeaders.append(key, v as string); + } + } else if (value !== undefined) { + // assume object headers are meant to be JSON stringified, i.e. their + // content value in OpenAPI specification is 'application/json' + mergedHeaders.set( + key, + typeof value === 'object' ? JSON.stringify(value) : (value as string), + ); + } + } + } + return mergedHeaders; +}; + +type ErrInterceptor = ( + error: Err, + response: Res, + request: Req, + options: Options, +) => Err | Promise; + +type ReqInterceptor = ( + request: Req, + options: Options, +) => Req | Promise; + +type ResInterceptor = ( + response: Res, + request: Req, + options: Options, +) => Res | Promise; + +class Interceptors { + _fns: (Interceptor | null)[]; + + constructor() { + this._fns = []; + } + + clear() { + this._fns = []; + } + + getInterceptorIndex(id: number | Interceptor): number { + if (typeof id === 'number') { + return this._fns[id] ? id : -1; + } else { + return this._fns.indexOf(id); + } + } + exists(id: number | Interceptor) { + const index = this.getInterceptorIndex(id); + return !!this._fns[index]; + } + + eject(id: number | Interceptor) { + const index = this.getInterceptorIndex(id); + if (this._fns[index]) { + this._fns[index] = null; + } + } + + update(id: number | Interceptor, fn: Interceptor) { + const index = this.getInterceptorIndex(id); + if (this._fns[index]) { + this._fns[index] = fn; + return id; + } else { + return false; + } + } + + use(fn: Interceptor) { + this._fns = [...this._fns, fn]; + return this._fns.length - 1; + } +} + +// `createInterceptors()` response, meant for external use as it does not +// expose internals +export interface Middleware { + error: Pick< + Interceptors>, + 'eject' | 'use' + >; + request: Pick>, 'eject' | 'use'>; + response: Pick< + Interceptors>, + 'eject' | 'use' + >; +} + +// do not add `Middleware` as return type so we can use _fns internally +export const createInterceptors = () => ({ + error: new Interceptors>(), + request: new Interceptors>(), + response: new Interceptors>(), +}); + +const defaultQuerySerializer = createQuerySerializer({ + allowReserved: false, + array: { + explode: true, + style: 'form', + }, + object: { + explode: true, + style: 'deepObject', + }, +}); + +const defaultHeaders = { + 'Content-Type': 'application/json', +}; + +export const createConfig = ( + override: Config & T> = {}, +): Config & T> => ({ + ...jsonBodySerializer, + headers: defaultHeaders, + parseAs: 'auto', + querySerializer: defaultQuerySerializer, + ...override, +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/auth.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/auth.gen.ts new file mode 100644 index 0000000000..f8a73266f9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/auth.gen.ts @@ -0,0 +1,42 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type AuthToken = string | undefined; + +export interface Auth { + /** + * Which part of the request do we use to send the auth? + * + * @default 'header' + */ + in?: 'header' | 'query' | 'cookie'; + /** + * Header or query parameter name. + * + * @default 'Authorization' + */ + name?: string; + scheme?: 'basic' | 'bearer'; + type: 'apiKey' | 'http'; +} + +export const getAuthToken = async ( + auth: Auth, + callback: ((auth: Auth) => Promise | AuthToken) | AuthToken, +): Promise => { + const token = + typeof callback === 'function' ? await callback(auth) : callback; + + if (!token) { + return; + } + + if (auth.scheme === 'bearer') { + return `Bearer ${token}`; + } + + if (auth.scheme === 'basic') { + return `Basic ${btoa(token)}`; + } + + return token; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/bodySerializer.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/bodySerializer.gen.ts new file mode 100644 index 0000000000..49cd8925e3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/bodySerializer.gen.ts @@ -0,0 +1,92 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { + ArrayStyle, + ObjectStyle, + SerializerOptions, +} from './pathSerializer.gen'; + +export type QuerySerializer = (query: Record) => string; + +export type BodySerializer = (body: any) => any; + +export interface QuerySerializerOptions { + allowReserved?: boolean; + array?: SerializerOptions; + object?: SerializerOptions; +} + +const serializeFormDataPair = ( + data: FormData, + key: string, + value: unknown, +): void => { + if (typeof value === 'string' || value instanceof Blob) { + data.append(key, value); + } else if (value instanceof Date) { + data.append(key, value.toISOString()); + } else { + data.append(key, JSON.stringify(value)); + } +}; + +const serializeUrlSearchParamsPair = ( + data: URLSearchParams, + key: string, + value: unknown, +): void => { + if (typeof value === 'string') { + data.append(key, value); + } else { + data.append(key, JSON.stringify(value)); + } +}; + +export const formDataBodySerializer = { + bodySerializer: | Array>>( + body: T, + ): FormData => { + const data = new FormData(); + + Object.entries(body).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => serializeFormDataPair(data, key, v)); + } else { + serializeFormDataPair(data, key, value); + } + }); + + return data; + }, +}; + +export const jsonBodySerializer = { + bodySerializer: (body: T): string => + JSON.stringify(body, (_key, value) => + typeof value === 'bigint' ? value.toString() : value, + ), +}; + +export const urlSearchParamsBodySerializer = { + bodySerializer: | Array>>( + body: T, + ): string => { + const data = new URLSearchParams(); + + Object.entries(body).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => serializeUrlSearchParamsPair(data, key, v)); + } else { + serializeUrlSearchParamsPair(data, key, value); + } + }); + + return data.toString(); + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/params.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/params.gen.ts new file mode 100644 index 0000000000..71c88e852b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/params.gen.ts @@ -0,0 +1,153 @@ +// This file is auto-generated by @hey-api/openapi-ts + +type Slot = 'body' | 'headers' | 'path' | 'query'; + +export type Field = + | { + in: Exclude; + /** + * Field name. This is the name we want the user to see and use. + */ + key: string; + /** + * Field mapped name. This is the name we want to use in the request. + * If omitted, we use the same value as `key`. + */ + map?: string; + } + | { + in: Extract; + /** + * Key isn't required for bodies. + */ + key?: string; + map?: string; + }; + +export interface Fields { + allowExtra?: Partial>; + args?: ReadonlyArray; +} + +export type FieldsConfig = ReadonlyArray; + +const extraPrefixesMap: Record = { + $body_: 'body', + $headers_: 'headers', + $path_: 'path', + $query_: 'query', +}; +const extraPrefixes = Object.entries(extraPrefixesMap); + +type KeyMap = Map< + string, + { + in: Slot; + map?: string; + } +>; + +const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { + if (!map) { + map = new Map(); + } + + for (const config of fields) { + if ('in' in config) { + if (config.key) { + map.set(config.key, { + in: config.in, + map: config.map, + }); + } + } else if (config.args) { + buildKeyMap(config.args, map); + } + } + + return map; +}; + +interface Params { + body: unknown; + headers: Record; + path: Record; + query: Record; +} + +const stripEmptySlots = (params: Params) => { + for (const [slot, value] of Object.entries(params)) { + if (value && typeof value === 'object' && !Object.keys(value).length) { + delete params[slot as Slot]; + } + } +}; + +export const buildClientParams = ( + args: ReadonlyArray, + fields: FieldsConfig, +) => { + const params: Params = { + body: {}, + headers: {}, + path: {}, + query: {}, + }; + + const map = buildKeyMap(fields); + + let config: FieldsConfig[number] | undefined; + + for (const [index, arg] of args.entries()) { + if (fields[index]) { + config = fields[index]; + } + + if (!config) { + continue; + } + + if ('in' in config) { + if (config.key) { + const field = map.get(config.key)!; + const name = field.map || config.key; + (params[field.in] as Record)[name] = arg; + } else { + params.body = arg; + } + } else { + for (const [key, value] of Object.entries(arg ?? {})) { + const field = map.get(key); + + if (field) { + const name = field.map || key; + (params[field.in] as Record)[name] = value; + } else { + const extra = extraPrefixes.find(([prefix]) => + key.startsWith(prefix), + ); + + if (extra) { + const [prefix, slot] = extra; + (params[slot] as Record)[ + key.slice(prefix.length) + ] = value; + } else { + for (const [slot, allowed] of Object.entries( + config.allowExtra ?? {}, + )) { + if (allowed) { + (params[slot as Slot] as Record)[key] = value; + break; + } + } + } + } + } + } + } + + stripEmptySlots(params); + + return params; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/pathSerializer.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/pathSerializer.gen.ts new file mode 100644 index 0000000000..8d99931047 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/pathSerializer.gen.ts @@ -0,0 +1,181 @@ +// This file is auto-generated by @hey-api/openapi-ts + +interface SerializeOptions + extends SerializePrimitiveOptions, + SerializerOptions {} + +interface SerializePrimitiveOptions { + allowReserved?: boolean; + name: string; +} + +export interface SerializerOptions { + /** + * @default true + */ + explode: boolean; + style: T; +} + +export type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited'; +export type ArraySeparatorStyle = ArrayStyle | MatrixStyle; +type MatrixStyle = 'label' | 'matrix' | 'simple'; +export type ObjectStyle = 'form' | 'deepObject'; +type ObjectSeparatorStyle = ObjectStyle | MatrixStyle; + +interface SerializePrimitiveParam extends SerializePrimitiveOptions { + value: string; +} + +export const separatorArrayExplode = (style: ArraySeparatorStyle) => { + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } +}; + +export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { + switch (style) { + case 'form': + return ','; + case 'pipeDelimited': + return '|'; + case 'spaceDelimited': + return '%20'; + default: + return ','; + } +}; + +export const separatorObjectExplode = (style: ObjectSeparatorStyle) => { + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } +}; + +export const serializeArrayParam = ({ + allowReserved, + explode, + name, + style, + value, +}: SerializeOptions & { + value: unknown[]; +}) => { + if (!explode) { + const joinedValues = ( + allowReserved ? value : value.map((v) => encodeURIComponent(v as string)) + ).join(separatorArrayNoExplode(style)); + switch (style) { + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + case 'simple': + return joinedValues; + default: + return `${name}=${joinedValues}`; + } + } + + const separator = separatorArrayExplode(style); + const joinedValues = value + .map((v) => { + if (style === 'label' || style === 'simple') { + return allowReserved ? v : encodeURIComponent(v as string); + } + + return serializePrimitiveParam({ + allowReserved, + name, + value: v as string, + }); + }) + .join(separator); + return style === 'label' || style === 'matrix' + ? separator + joinedValues + : joinedValues; +}; + +export const serializePrimitiveParam = ({ + allowReserved, + name, + value, +}: SerializePrimitiveParam) => { + if (value === undefined || value === null) { + return ''; + } + + if (typeof value === 'object') { + throw new Error( + 'Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.', + ); + } + + return `${name}=${allowReserved ? value : encodeURIComponent(value)}`; +}; + +export const serializeObjectParam = ({ + allowReserved, + explode, + name, + style, + value, + valueOnly, +}: SerializeOptions & { + value: Record | Date; + valueOnly?: boolean; +}) => { + if (value instanceof Date) { + return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`; + } + + if (style !== 'deepObject' && !explode) { + let values: string[] = []; + Object.entries(value).forEach(([key, v]) => { + values = [ + ...values, + key, + allowReserved ? (v as string) : encodeURIComponent(v as string), + ]; + }); + const joinedValues = values.join(','); + switch (style) { + case 'form': + return `${name}=${joinedValues}`; + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + default: + return joinedValues; + } + } + + const separator = separatorObjectExplode(style); + const joinedValues = Object.entries(value) + .map(([key, v]) => + serializePrimitiveParam({ + allowReserved, + name: style === 'deepObject' ? `${name}[${key}]` : key, + value: v as string, + }), + ) + .join(separator); + return style === 'label' || style === 'matrix' + ? separator + joinedValues + : joinedValues; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/serverSentEvents.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/serverSentEvents.gen.ts new file mode 100644 index 0000000000..01b5818fdf --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/serverSentEvents.gen.ts @@ -0,0 +1,237 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Config } from './types.gen'; + +export type ServerSentEventsOptions = Omit< + RequestInit, + 'method' +> & + Pick & { + /** + * Callback invoked when a network or parsing error occurs during streaming. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param error The error that occurred. + */ + onSseError?: (error: unknown) => void; + /** + * Callback invoked when an event is streamed from the server. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param event Event streamed from the server. + * @returns Nothing (void). + */ + onSseEvent?: (event: StreamEvent) => void; + /** + * Default retry delay in milliseconds. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 3000 + */ + sseDefaultRetryDelay?: number; + /** + * Maximum number of retry attempts before giving up. + */ + sseMaxRetryAttempts?: number; + /** + * Maximum retry delay in milliseconds. + * + * Applies only when exponential backoff is used. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 30000 + */ + sseMaxRetryDelay?: number; + /** + * Optional sleep function for retry backoff. + * + * Defaults to using `setTimeout`. + */ + sseSleepFn?: (ms: number) => Promise; + url: string; + }; + +export interface StreamEvent { + data: TData; + event?: string; + id?: string; + retry?: number; +} + +export type ServerSentEventsResult< + TData = unknown, + TReturn = void, + TNext = unknown, +> = { + stream: AsyncGenerator< + TData extends Record ? TData[keyof TData] : TData, + TReturn, + TNext + >; +}; + +export const createSseClient = ({ + onSseError, + onSseEvent, + responseTransformer, + responseValidator, + sseDefaultRetryDelay, + sseMaxRetryAttempts, + sseMaxRetryDelay, + sseSleepFn, + url, + ...options +}: ServerSentEventsOptions): ServerSentEventsResult => { + let lastEventId: string | undefined; + + const sleep = + sseSleepFn ?? + ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))); + + const createStream = async function* () { + let retryDelay: number = sseDefaultRetryDelay ?? 3000; + let attempt = 0; + const signal = options.signal ?? new AbortController().signal; + + while (true) { + if (signal.aborted) break; + + attempt++; + + const headers = + options.headers instanceof Headers + ? options.headers + : new Headers(options.headers as Record | undefined); + + if (lastEventId !== undefined) { + headers.set('Last-Event-ID', lastEventId); + } + + try { + const response = await fetch(url, { ...options, headers, signal }); + + if (!response.ok) + throw new Error( + `SSE failed: ${response.status} ${response.statusText}`, + ); + + if (!response.body) throw new Error('No body in SSE response'); + + const reader = response.body + .pipeThrough(new TextDecoderStream()) + .getReader(); + + let buffer = ''; + + const abortHandler = () => { + try { + reader.cancel(); + } catch { + // noop + } + }; + + signal.addEventListener('abort', abortHandler); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + buffer += value; + + const chunks = buffer.split('\n\n'); + buffer = chunks.pop() ?? ''; + + for (const chunk of chunks) { + const lines = chunk.split('\n'); + const dataLines: Array = []; + let eventName: string | undefined; + + for (const line of lines) { + if (line.startsWith('data:')) { + dataLines.push(line.replace(/^data:\s*/, '')); + } else if (line.startsWith('event:')) { + eventName = line.replace(/^event:\s*/, ''); + } else if (line.startsWith('id:')) { + lastEventId = line.replace(/^id:\s*/, ''); + } else if (line.startsWith('retry:')) { + const parsed = Number.parseInt( + line.replace(/^retry:\s*/, ''), + 10, + ); + if (!Number.isNaN(parsed)) { + retryDelay = parsed; + } + } + } + + let data: unknown; + let parsedJson = false; + + if (dataLines.length) { + const rawData = dataLines.join('\n'); + try { + data = JSON.parse(rawData); + parsedJson = true; + } catch { + data = rawData; + } + } + + if (parsedJson) { + if (responseValidator) { + await responseValidator(data); + } + + if (responseTransformer) { + data = await responseTransformer(data); + } + } + + onSseEvent?.({ + data, + event: eventName, + id: lastEventId, + retry: retryDelay, + }); + + if (dataLines.length) { + yield data as any; + } + } + } + } finally { + signal.removeEventListener('abort', abortHandler); + reader.releaseLock(); + } + + break; // exit loop on normal completion + } catch (error) { + // connection failed or aborted; retry after delay + onSseError?.(error); + + if ( + sseMaxRetryAttempts !== undefined && + attempt >= sseMaxRetryAttempts + ) { + break; // stop after firing error + } + + // exponential backoff: double retry each attempt, cap at 30s + const backoff = Math.min( + retryDelay * 2 ** (attempt - 1), + sseMaxRetryDelay ?? 30000, + ); + await sleep(backoff); + } + } + }; + + const stream = createStream(); + + return { stream }; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/types.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/types.gen.ts new file mode 100644 index 0000000000..643c070c9d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/types.gen.ts @@ -0,0 +1,118 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Auth, AuthToken } from './auth.gen'; +import type { + BodySerializer, + QuerySerializer, + QuerySerializerOptions, +} from './bodySerializer.gen'; + +export type HttpMethod = + | 'connect' + | 'delete' + | 'get' + | 'head' + | 'options' + | 'patch' + | 'post' + | 'put' + | 'trace'; + +export type Client< + RequestFn = never, + Config = unknown, + MethodFn = never, + BuildUrlFn = never, + SseFn = never, +> = { + /** + * Returns the final request URL. + */ + buildUrl: BuildUrlFn; + getConfig: () => Config; + request: RequestFn; + setConfig: (config: Config) => Config; +} & { + [K in HttpMethod]: MethodFn; +} & ([SseFn] extends [never] + ? { sse?: never } + : { sse: { [K in HttpMethod]: SseFn } }); + +export interface Config { + /** + * Auth token or a function returning auth token. The resolved value will be + * added to the request payload as defined by its `security` array. + */ + auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken; + /** + * A function for serializing request body parameter. By default, + * {@link JSON.stringify()} will be used. + */ + bodySerializer?: BodySerializer | null; + /** + * An object containing any HTTP headers that you want to pre-populate your + * `Headers` object with. + * + * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} + */ + headers?: + | RequestInit['headers'] + | Record< + string, + | string + | number + | boolean + | (string | number | boolean)[] + | null + | undefined + | unknown + >; + /** + * The request method. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} + */ + method?: Uppercase; + /** + * A function for serializing request query parameters. By default, arrays + * will be exploded in form style, objects will be exploded in deepObject + * style, and reserved characters are percent-encoded. + * + * This method will have no effect if the native `paramsSerializer()` Axios + * API function is used. + * + * {@link https://swagger.io/docs/specification/serialization/#query View examples} + */ + querySerializer?: QuerySerializer | QuerySerializerOptions; + /** + * A function validating request data. This is useful if you want to ensure + * the request conforms to the desired shape, so it can be safely sent to + * the server. + */ + requestValidator?: (data: unknown) => Promise; + /** + * A function transforming response data before it's returned. This is useful + * for post-processing data, e.g. converting ISO strings into Date objects. + */ + responseTransformer?: (data: unknown) => Promise; + /** + * A function validating response data. This is useful if you want to ensure + * the response conforms to the desired shape, so it can be safely passed to + * the transformers and returned to the user. + */ + responseValidator?: (data: unknown) => Promise; +} + +type IsExactlyNeverOrNeverUndefined = [T] extends [never] + ? true + : [T] extends [never | undefined] + ? [undefined] extends [T] + ? false + : true + : false; + +export type OmitNever> = { + [K in keyof T as IsExactlyNeverOrNeverUndefined extends true + ? never + : K]: T[K]; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/utils.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/utils.gen.ts new file mode 100644 index 0000000000..ac31396fea --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/utils.gen.ts @@ -0,0 +1,114 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { QuerySerializer } from './bodySerializer.gen'; +import { + type ArraySeparatorStyle, + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from './pathSerializer.gen'; + +export interface PathSerializer { + path: Record; + url: string; +} + +export const PATH_PARAM_RE = /\{[^{}]+\}/g; + +export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { + let url = _url; + const matches = _url.match(PATH_PARAM_RE); + if (matches) { + for (const match of matches) { + let explode = false; + let name = match.substring(1, match.length - 1); + let style: ArraySeparatorStyle = 'simple'; + + if (name.endsWith('*')) { + explode = true; + name = name.substring(0, name.length - 1); + } + + if (name.startsWith('.')) { + name = name.substring(1); + style = 'label'; + } else if (name.startsWith(';')) { + name = name.substring(1); + style = 'matrix'; + } + + const value = path[name]; + + if (value === undefined || value === null) { + continue; + } + + if (Array.isArray(value)) { + url = url.replace( + match, + serializeArrayParam({ explode, name, style, value }), + ); + continue; + } + + if (typeof value === 'object') { + url = url.replace( + match, + serializeObjectParam({ + explode, + name, + style, + value: value as Record, + valueOnly: true, + }), + ); + continue; + } + + if (style === 'matrix') { + url = url.replace( + match, + `;${serializePrimitiveParam({ + name, + value: value as string, + })}`, + ); + continue; + } + + const replaceValue = encodeURIComponent( + style === 'label' ? `.${value as string}` : (value as string), + ); + url = url.replace(match, replaceValue); + } + } + return url; +}; + +export const getUrl = ({ + baseUrl, + path, + query, + querySerializer, + url: _url, +}: { + baseUrl?: string; + path?: Record; + query?: Record; + querySerializer: QuerySerializer; + url: string; +}) => { + const pathUrl = _url.startsWith('/') ? _url : `/${_url}`; + let url = (baseUrl ?? '') + pathUrl; + if (path) { + url = defaultPathSerializer({ path, url }); + } + let search = query ? querySerializer(query) : ''; + if (search.startsWith('?')) { + search = search.substring(1); + } + if (search) { + url += `?${search}`; + } + return url; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/sdk.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/sdk.gen.ts index 62ef1c6b23..5e723adbf2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/sdk.gen.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/sdk.gen.ts @@ -1,6 +1,6 @@ // This file is auto-generated by @hey-api/openapi-ts -import { type Options as ClientOptions, type TDataShape, type Client, formDataBodySerializer } from '@hey-api/client-fetch'; +import { type Options as ClientOptions, type TDataShape, type Client, formDataBodySerializer } from './client'; import type { GetCultureData, GetCultureResponses, GetCultureErrors, PostDataTypeData, PostDataTypeResponses, PostDataTypeErrors, DeleteDataTypeByIdData, DeleteDataTypeByIdResponses, DeleteDataTypeByIdErrors, GetDataTypeByIdData, GetDataTypeByIdResponses, GetDataTypeByIdErrors, PutDataTypeByIdData, PutDataTypeByIdResponses, PutDataTypeByIdErrors, PostDataTypeByIdCopyData, PostDataTypeByIdCopyResponses, PostDataTypeByIdCopyErrors, GetDataTypeByIdIsUsedData, GetDataTypeByIdIsUsedResponses, GetDataTypeByIdIsUsedErrors, PutDataTypeByIdMoveData, PutDataTypeByIdMoveResponses, PutDataTypeByIdMoveErrors, GetDataTypeByIdReferencedByData, GetDataTypeByIdReferencedByResponses, GetDataTypeByIdReferencedByErrors, GetDataTypeByIdReferencesData, GetDataTypeByIdReferencesResponses, GetDataTypeByIdReferencesErrors, GetDataTypeConfigurationData, GetDataTypeConfigurationResponses, GetDataTypeConfigurationErrors, PostDataTypeFolderData, PostDataTypeFolderResponses, PostDataTypeFolderErrors, DeleteDataTypeFolderByIdData, DeleteDataTypeFolderByIdResponses, DeleteDataTypeFolderByIdErrors, GetDataTypeFolderByIdData, GetDataTypeFolderByIdResponses, GetDataTypeFolderByIdErrors, PutDataTypeFolderByIdData, PutDataTypeFolderByIdResponses, PutDataTypeFolderByIdErrors, GetFilterDataTypeData, GetFilterDataTypeResponses, GetFilterDataTypeErrors, GetItemDataTypeData, GetItemDataTypeResponses, GetItemDataTypeErrors, GetItemDataTypeSearchData, GetItemDataTypeSearchResponses, GetItemDataTypeSearchErrors, GetTreeDataTypeAncestorsData, GetTreeDataTypeAncestorsResponses, GetTreeDataTypeAncestorsErrors, GetTreeDataTypeChildrenData, GetTreeDataTypeChildrenResponses, GetTreeDataTypeChildrenErrors, GetTreeDataTypeRootData, GetTreeDataTypeRootResponses, GetTreeDataTypeRootErrors, GetTreeDataTypeSiblingsData, GetTreeDataTypeSiblingsResponses, GetTreeDataTypeSiblingsErrors, GetDictionaryData, GetDictionaryResponses, GetDictionaryErrors, PostDictionaryData, PostDictionaryResponses, PostDictionaryErrors, DeleteDictionaryByIdData, DeleteDictionaryByIdResponses, DeleteDictionaryByIdErrors, GetDictionaryByIdData, GetDictionaryByIdResponses, GetDictionaryByIdErrors, PutDictionaryByIdData, PutDictionaryByIdResponses, PutDictionaryByIdErrors, GetDictionaryByIdExportData, GetDictionaryByIdExportResponses, GetDictionaryByIdExportErrors, PutDictionaryByIdMoveData, PutDictionaryByIdMoveResponses, PutDictionaryByIdMoveErrors, PostDictionaryImportData, PostDictionaryImportResponses, PostDictionaryImportErrors, GetItemDictionaryData, GetItemDictionaryResponses, GetItemDictionaryErrors, GetTreeDictionaryAncestorsData, GetTreeDictionaryAncestorsResponses, GetTreeDictionaryAncestorsErrors, GetTreeDictionaryChildrenData, GetTreeDictionaryChildrenResponses, GetTreeDictionaryChildrenErrors, GetTreeDictionaryRootData, GetTreeDictionaryRootResponses, GetTreeDictionaryRootErrors, PostDocumentBlueprintData, PostDocumentBlueprintResponses, PostDocumentBlueprintErrors, DeleteDocumentBlueprintByIdData, DeleteDocumentBlueprintByIdResponses, DeleteDocumentBlueprintByIdErrors, GetDocumentBlueprintByIdData, GetDocumentBlueprintByIdResponses, GetDocumentBlueprintByIdErrors, PutDocumentBlueprintByIdData, PutDocumentBlueprintByIdResponses, PutDocumentBlueprintByIdErrors, PutDocumentBlueprintByIdMoveData, PutDocumentBlueprintByIdMoveResponses, PutDocumentBlueprintByIdMoveErrors, GetDocumentBlueprintByIdScaffoldData, GetDocumentBlueprintByIdScaffoldResponses, GetDocumentBlueprintByIdScaffoldErrors, PostDocumentBlueprintFolderData, PostDocumentBlueprintFolderResponses, PostDocumentBlueprintFolderErrors, DeleteDocumentBlueprintFolderByIdData, DeleteDocumentBlueprintFolderByIdResponses, DeleteDocumentBlueprintFolderByIdErrors, GetDocumentBlueprintFolderByIdData, GetDocumentBlueprintFolderByIdResponses, GetDocumentBlueprintFolderByIdErrors, PutDocumentBlueprintFolderByIdData, PutDocumentBlueprintFolderByIdResponses, PutDocumentBlueprintFolderByIdErrors, PostDocumentBlueprintFromDocumentData, PostDocumentBlueprintFromDocumentResponses, PostDocumentBlueprintFromDocumentErrors, GetItemDocumentBlueprintData, GetItemDocumentBlueprintResponses, GetItemDocumentBlueprintErrors, GetTreeDocumentBlueprintAncestorsData, GetTreeDocumentBlueprintAncestorsResponses, GetTreeDocumentBlueprintAncestorsErrors, GetTreeDocumentBlueprintChildrenData, GetTreeDocumentBlueprintChildrenResponses, GetTreeDocumentBlueprintChildrenErrors, GetTreeDocumentBlueprintRootData, GetTreeDocumentBlueprintRootResponses, GetTreeDocumentBlueprintRootErrors, GetTreeDocumentBlueprintSiblingsData, GetTreeDocumentBlueprintSiblingsResponses, GetTreeDocumentBlueprintSiblingsErrors, PostDocumentTypeData, PostDocumentTypeResponses, PostDocumentTypeErrors, DeleteDocumentTypeByIdData, DeleteDocumentTypeByIdResponses, DeleteDocumentTypeByIdErrors, GetDocumentTypeByIdData, GetDocumentTypeByIdResponses, GetDocumentTypeByIdErrors, PutDocumentTypeByIdData, PutDocumentTypeByIdResponses, PutDocumentTypeByIdErrors, GetDocumentTypeByIdAllowedChildrenData, GetDocumentTypeByIdAllowedChildrenResponses, GetDocumentTypeByIdAllowedChildrenErrors, GetDocumentTypeByIdBlueprintData, GetDocumentTypeByIdBlueprintResponses, GetDocumentTypeByIdBlueprintErrors, GetDocumentTypeByIdCompositionReferencesData, GetDocumentTypeByIdCompositionReferencesResponses, GetDocumentTypeByIdCompositionReferencesErrors, PostDocumentTypeByIdCopyData, PostDocumentTypeByIdCopyResponses, PostDocumentTypeByIdCopyErrors, GetDocumentTypeByIdExportData, GetDocumentTypeByIdExportResponses, GetDocumentTypeByIdExportErrors, PutDocumentTypeByIdImportData, PutDocumentTypeByIdImportResponses, PutDocumentTypeByIdImportErrors, PutDocumentTypeByIdMoveData, PutDocumentTypeByIdMoveResponses, PutDocumentTypeByIdMoveErrors, GetDocumentTypeAllowedAtRootData, GetDocumentTypeAllowedAtRootResponses, GetDocumentTypeAllowedAtRootErrors, PostDocumentTypeAvailableCompositionsData, PostDocumentTypeAvailableCompositionsResponses, PostDocumentTypeAvailableCompositionsErrors, GetDocumentTypeConfigurationData, GetDocumentTypeConfigurationResponses, GetDocumentTypeConfigurationErrors, PostDocumentTypeFolderData, PostDocumentTypeFolderResponses, PostDocumentTypeFolderErrors, DeleteDocumentTypeFolderByIdData, DeleteDocumentTypeFolderByIdResponses, DeleteDocumentTypeFolderByIdErrors, GetDocumentTypeFolderByIdData, GetDocumentTypeFolderByIdResponses, GetDocumentTypeFolderByIdErrors, PutDocumentTypeFolderByIdData, PutDocumentTypeFolderByIdResponses, PutDocumentTypeFolderByIdErrors, PostDocumentTypeImportData, PostDocumentTypeImportResponses, PostDocumentTypeImportErrors, GetItemDocumentTypeData, GetItemDocumentTypeResponses, GetItemDocumentTypeErrors, GetItemDocumentTypeSearchData, GetItemDocumentTypeSearchResponses, GetItemDocumentTypeSearchErrors, GetTreeDocumentTypeAncestorsData, GetTreeDocumentTypeAncestorsResponses, GetTreeDocumentTypeAncestorsErrors, GetTreeDocumentTypeChildrenData, GetTreeDocumentTypeChildrenResponses, GetTreeDocumentTypeChildrenErrors, GetTreeDocumentTypeRootData, GetTreeDocumentTypeRootResponses, GetTreeDocumentTypeRootErrors, GetTreeDocumentTypeSiblingsData, GetTreeDocumentTypeSiblingsResponses, GetTreeDocumentTypeSiblingsErrors, GetDocumentVersionData, GetDocumentVersionResponses, GetDocumentVersionErrors, GetDocumentVersionByIdData, GetDocumentVersionByIdResponses, GetDocumentVersionByIdErrors, PutDocumentVersionByIdPreventCleanupData, PutDocumentVersionByIdPreventCleanupResponses, PutDocumentVersionByIdPreventCleanupErrors, PostDocumentVersionByIdRollbackData, PostDocumentVersionByIdRollbackResponses, PostDocumentVersionByIdRollbackErrors, GetCollectionDocumentByIdData, GetCollectionDocumentByIdResponses, GetCollectionDocumentByIdErrors, PostDocumentData, PostDocumentResponses, PostDocumentErrors, DeleteDocumentByIdData, DeleteDocumentByIdResponses, DeleteDocumentByIdErrors, GetDocumentByIdData, GetDocumentByIdResponses, GetDocumentByIdErrors, PutDocumentByIdData, PutDocumentByIdResponses, PutDocumentByIdErrors, GetDocumentByIdAuditLogData, GetDocumentByIdAuditLogResponses, GetDocumentByIdAuditLogErrors, PostDocumentByIdCopyData, PostDocumentByIdCopyResponses, PostDocumentByIdCopyErrors, GetDocumentByIdDomainsData, GetDocumentByIdDomainsResponses, GetDocumentByIdDomainsErrors, PutDocumentByIdDomainsData, PutDocumentByIdDomainsResponses, PutDocumentByIdDomainsErrors, PutDocumentByIdMoveData, PutDocumentByIdMoveResponses, PutDocumentByIdMoveErrors, PutDocumentByIdMoveToRecycleBinData, PutDocumentByIdMoveToRecycleBinResponses, PutDocumentByIdMoveToRecycleBinErrors, GetDocumentByIdNotificationsData, GetDocumentByIdNotificationsResponses, GetDocumentByIdNotificationsErrors, PutDocumentByIdNotificationsData, PutDocumentByIdNotificationsResponses, PutDocumentByIdNotificationsErrors, DeleteDocumentByIdPublicAccessData, DeleteDocumentByIdPublicAccessResponses, DeleteDocumentByIdPublicAccessErrors, GetDocumentByIdPublicAccessData, GetDocumentByIdPublicAccessResponses, GetDocumentByIdPublicAccessErrors, PostDocumentByIdPublicAccessData, PostDocumentByIdPublicAccessResponses, PostDocumentByIdPublicAccessErrors, PutDocumentByIdPublicAccessData, PutDocumentByIdPublicAccessResponses, PutDocumentByIdPublicAccessErrors, PutDocumentByIdPublishData, PutDocumentByIdPublishResponses, PutDocumentByIdPublishErrors, PutDocumentByIdPublishWithDescendantsData, PutDocumentByIdPublishWithDescendantsResponses, PutDocumentByIdPublishWithDescendantsErrors, GetDocumentByIdPublishWithDescendantsResultByTaskIdData, GetDocumentByIdPublishWithDescendantsResultByTaskIdResponses, GetDocumentByIdPublishWithDescendantsResultByTaskIdErrors, GetDocumentByIdPublishedData, GetDocumentByIdPublishedResponses, GetDocumentByIdPublishedErrors, GetDocumentByIdReferencedByData, GetDocumentByIdReferencedByResponses, GetDocumentByIdReferencedByErrors, GetDocumentByIdReferencedDescendantsData, GetDocumentByIdReferencedDescendantsResponses, GetDocumentByIdReferencedDescendantsErrors, PutDocumentByIdUnpublishData, PutDocumentByIdUnpublishResponses, PutDocumentByIdUnpublishErrors, PutUmbracoManagementApiV11DocumentByIdValidate11Data, PutUmbracoManagementApiV11DocumentByIdValidate11Responses, PutUmbracoManagementApiV11DocumentByIdValidate11Errors, GetDocumentAreReferencedData, GetDocumentAreReferencedResponses, GetDocumentAreReferencedErrors, GetDocumentConfigurationData, GetDocumentConfigurationResponses, GetDocumentConfigurationErrors, PutDocumentSortData, PutDocumentSortResponses, PutDocumentSortErrors, GetDocumentUrlsData, GetDocumentUrlsResponses, GetDocumentUrlsErrors, PostDocumentValidateData, PostDocumentValidateResponses, PostDocumentValidateErrors, GetItemDocumentData, GetItemDocumentResponses, GetItemDocumentErrors, GetItemDocumentSearchData, GetItemDocumentSearchResponses, GetItemDocumentSearchErrors, DeleteRecycleBinDocumentData, DeleteRecycleBinDocumentResponses, DeleteRecycleBinDocumentErrors, DeleteRecycleBinDocumentByIdData, DeleteRecycleBinDocumentByIdResponses, DeleteRecycleBinDocumentByIdErrors, GetRecycleBinDocumentByIdOriginalParentData, GetRecycleBinDocumentByIdOriginalParentResponses, GetRecycleBinDocumentByIdOriginalParentErrors, PutRecycleBinDocumentByIdRestoreData, PutRecycleBinDocumentByIdRestoreResponses, PutRecycleBinDocumentByIdRestoreErrors, GetRecycleBinDocumentChildrenData, GetRecycleBinDocumentChildrenResponses, GetRecycleBinDocumentChildrenErrors, GetRecycleBinDocumentReferencedByData, GetRecycleBinDocumentReferencedByResponses, GetRecycleBinDocumentReferencedByErrors, GetRecycleBinDocumentRootData, GetRecycleBinDocumentRootResponses, GetRecycleBinDocumentRootErrors, GetTreeDocumentAncestorsData, GetTreeDocumentAncestorsResponses, GetTreeDocumentAncestorsErrors, GetTreeDocumentChildrenData, GetTreeDocumentChildrenResponses, GetTreeDocumentChildrenErrors, GetTreeDocumentRootData, GetTreeDocumentRootResponses, GetTreeDocumentRootErrors, GetTreeDocumentSiblingsData, GetTreeDocumentSiblingsResponses, GetTreeDocumentSiblingsErrors, PostDynamicRootQueryData, PostDynamicRootQueryResponses, PostDynamicRootQueryErrors, GetDynamicRootStepsData, GetDynamicRootStepsResponses, GetDynamicRootStepsErrors, GetHealthCheckGroupData, GetHealthCheckGroupResponses, GetHealthCheckGroupErrors, GetHealthCheckGroupByNameData, GetHealthCheckGroupByNameResponses, GetHealthCheckGroupByNameErrors, PostHealthCheckGroupByNameCheckData, PostHealthCheckGroupByNameCheckResponses, PostHealthCheckGroupByNameCheckErrors, PostHealthCheckExecuteActionData, PostHealthCheckExecuteActionResponses, PostHealthCheckExecuteActionErrors, GetHelpData, GetHelpResponses, GetHelpErrors, GetImagingResizeUrlsData, GetImagingResizeUrlsResponses, GetImagingResizeUrlsErrors, GetImportAnalyzeData, GetImportAnalyzeResponses, GetImportAnalyzeErrors, GetIndexerData, GetIndexerResponses, GetIndexerErrors, GetIndexerByIndexNameData, GetIndexerByIndexNameResponses, GetIndexerByIndexNameErrors, PostIndexerByIndexNameRebuildData, PostIndexerByIndexNameRebuildResponses, PostIndexerByIndexNameRebuildErrors, GetInstallSettingsData, GetInstallSettingsResponses, GetInstallSettingsErrors, PostInstallSetupData, PostInstallSetupResponses, PostInstallSetupErrors, PostInstallValidateDatabaseData, PostInstallValidateDatabaseResponses, PostInstallValidateDatabaseErrors, GetItemLanguageData, GetItemLanguageResponses, GetItemLanguageErrors, GetItemLanguageDefaultData, GetItemLanguageDefaultResponses, GetItemLanguageDefaultErrors, GetLanguageData, GetLanguageResponses, GetLanguageErrors, PostLanguageData, PostLanguageResponses, PostLanguageErrors, DeleteLanguageByIsoCodeData, DeleteLanguageByIsoCodeResponses, DeleteLanguageByIsoCodeErrors, GetLanguageByIsoCodeData, GetLanguageByIsoCodeResponses, GetLanguageByIsoCodeErrors, PutLanguageByIsoCodeData, PutLanguageByIsoCodeResponses, PutLanguageByIsoCodeErrors, GetLogViewerLevelData, GetLogViewerLevelResponses, GetLogViewerLevelErrors, GetLogViewerLevelCountData, GetLogViewerLevelCountResponses, GetLogViewerLevelCountErrors, GetLogViewerLogData, GetLogViewerLogResponses, GetLogViewerLogErrors, GetLogViewerMessageTemplateData, GetLogViewerMessageTemplateResponses, GetLogViewerMessageTemplateErrors, GetLogViewerSavedSearchData, GetLogViewerSavedSearchResponses, GetLogViewerSavedSearchErrors, PostLogViewerSavedSearchData, PostLogViewerSavedSearchResponses, PostLogViewerSavedSearchErrors, DeleteLogViewerSavedSearchByNameData, DeleteLogViewerSavedSearchByNameResponses, DeleteLogViewerSavedSearchByNameErrors, GetLogViewerSavedSearchByNameData, GetLogViewerSavedSearchByNameResponses, GetLogViewerSavedSearchByNameErrors, GetLogViewerValidateLogsSizeData, GetLogViewerValidateLogsSizeResponses, GetLogViewerValidateLogsSizeErrors, GetManifestManifestData, GetManifestManifestResponses, GetManifestManifestErrors, GetManifestManifestPrivateData, GetManifestManifestPrivateResponses, GetManifestManifestPrivateErrors, GetManifestManifestPublicData, GetManifestManifestPublicResponses, GetItemMediaTypeData, GetItemMediaTypeResponses, GetItemMediaTypeErrors, GetItemMediaTypeAllowedData, GetItemMediaTypeAllowedResponses, GetItemMediaTypeAllowedErrors, GetItemMediaTypeFoldersData, GetItemMediaTypeFoldersResponses, GetItemMediaTypeFoldersErrors, GetItemMediaTypeSearchData, GetItemMediaTypeSearchResponses, GetItemMediaTypeSearchErrors, PostMediaTypeData, PostMediaTypeResponses, PostMediaTypeErrors, DeleteMediaTypeByIdData, DeleteMediaTypeByIdResponses, DeleteMediaTypeByIdErrors, GetMediaTypeByIdData, GetMediaTypeByIdResponses, GetMediaTypeByIdErrors, PutMediaTypeByIdData, PutMediaTypeByIdResponses, PutMediaTypeByIdErrors, GetMediaTypeByIdAllowedChildrenData, GetMediaTypeByIdAllowedChildrenResponses, GetMediaTypeByIdAllowedChildrenErrors, GetMediaTypeByIdCompositionReferencesData, GetMediaTypeByIdCompositionReferencesResponses, GetMediaTypeByIdCompositionReferencesErrors, PostMediaTypeByIdCopyData, PostMediaTypeByIdCopyResponses, PostMediaTypeByIdCopyErrors, GetMediaTypeByIdExportData, GetMediaTypeByIdExportResponses, GetMediaTypeByIdExportErrors, PutMediaTypeByIdImportData, PutMediaTypeByIdImportResponses, PutMediaTypeByIdImportErrors, PutMediaTypeByIdMoveData, PutMediaTypeByIdMoveResponses, PutMediaTypeByIdMoveErrors, GetMediaTypeAllowedAtRootData, GetMediaTypeAllowedAtRootResponses, GetMediaTypeAllowedAtRootErrors, PostMediaTypeAvailableCompositionsData, PostMediaTypeAvailableCompositionsResponses, PostMediaTypeAvailableCompositionsErrors, GetMediaTypeConfigurationData, GetMediaTypeConfigurationResponses, GetMediaTypeConfigurationErrors, PostMediaTypeFolderData, PostMediaTypeFolderResponses, PostMediaTypeFolderErrors, DeleteMediaTypeFolderByIdData, DeleteMediaTypeFolderByIdResponses, DeleteMediaTypeFolderByIdErrors, GetMediaTypeFolderByIdData, GetMediaTypeFolderByIdResponses, GetMediaTypeFolderByIdErrors, PutMediaTypeFolderByIdData, PutMediaTypeFolderByIdResponses, PutMediaTypeFolderByIdErrors, PostMediaTypeImportData, PostMediaTypeImportResponses, PostMediaTypeImportErrors, GetTreeMediaTypeAncestorsData, GetTreeMediaTypeAncestorsResponses, GetTreeMediaTypeAncestorsErrors, GetTreeMediaTypeChildrenData, GetTreeMediaTypeChildrenResponses, GetTreeMediaTypeChildrenErrors, GetTreeMediaTypeRootData, GetTreeMediaTypeRootResponses, GetTreeMediaTypeRootErrors, GetTreeMediaTypeSiblingsData, GetTreeMediaTypeSiblingsResponses, GetTreeMediaTypeSiblingsErrors, GetCollectionMediaData, GetCollectionMediaResponses, GetCollectionMediaErrors, GetItemMediaData, GetItemMediaResponses, GetItemMediaErrors, GetItemMediaSearchData, GetItemMediaSearchResponses, GetItemMediaSearchErrors, PostMediaData, PostMediaResponses, PostMediaErrors, DeleteMediaByIdData, DeleteMediaByIdResponses, DeleteMediaByIdErrors, GetMediaByIdData, GetMediaByIdResponses, GetMediaByIdErrors, PutMediaByIdData, PutMediaByIdResponses, PutMediaByIdErrors, GetMediaByIdAuditLogData, GetMediaByIdAuditLogResponses, GetMediaByIdAuditLogErrors, PutMediaByIdMoveData, PutMediaByIdMoveResponses, PutMediaByIdMoveErrors, PutMediaByIdMoveToRecycleBinData, PutMediaByIdMoveToRecycleBinResponses, PutMediaByIdMoveToRecycleBinErrors, GetMediaByIdReferencedByData, GetMediaByIdReferencedByResponses, GetMediaByIdReferencedByErrors, GetMediaByIdReferencedDescendantsData, GetMediaByIdReferencedDescendantsResponses, GetMediaByIdReferencedDescendantsErrors, PutMediaByIdValidateData, PutMediaByIdValidateResponses, PutMediaByIdValidateErrors, GetMediaAreReferencedData, GetMediaAreReferencedResponses, GetMediaAreReferencedErrors, GetMediaConfigurationData, GetMediaConfigurationResponses, GetMediaConfigurationErrors, PutMediaSortData, PutMediaSortResponses, PutMediaSortErrors, GetMediaUrlsData, GetMediaUrlsResponses, GetMediaUrlsErrors, PostMediaValidateData, PostMediaValidateResponses, PostMediaValidateErrors, DeleteRecycleBinMediaData, DeleteRecycleBinMediaResponses, DeleteRecycleBinMediaErrors, DeleteRecycleBinMediaByIdData, DeleteRecycleBinMediaByIdResponses, DeleteRecycleBinMediaByIdErrors, GetRecycleBinMediaByIdOriginalParentData, GetRecycleBinMediaByIdOriginalParentResponses, GetRecycleBinMediaByIdOriginalParentErrors, PutRecycleBinMediaByIdRestoreData, PutRecycleBinMediaByIdRestoreResponses, PutRecycleBinMediaByIdRestoreErrors, GetRecycleBinMediaChildrenData, GetRecycleBinMediaChildrenResponses, GetRecycleBinMediaChildrenErrors, GetRecycleBinMediaReferencedByData, GetRecycleBinMediaReferencedByResponses, GetRecycleBinMediaReferencedByErrors, GetRecycleBinMediaRootData, GetRecycleBinMediaRootResponses, GetRecycleBinMediaRootErrors, GetTreeMediaAncestorsData, GetTreeMediaAncestorsResponses, GetTreeMediaAncestorsErrors, GetTreeMediaChildrenData, GetTreeMediaChildrenResponses, GetTreeMediaChildrenErrors, GetTreeMediaRootData, GetTreeMediaRootResponses, GetTreeMediaRootErrors, GetTreeMediaSiblingsData, GetTreeMediaSiblingsResponses, GetTreeMediaSiblingsErrors, GetItemMemberGroupData, GetItemMemberGroupResponses, GetItemMemberGroupErrors, GetMemberGroupData, GetMemberGroupResponses, GetMemberGroupErrors, PostMemberGroupData, PostMemberGroupResponses, PostMemberGroupErrors, DeleteMemberGroupByIdData, DeleteMemberGroupByIdResponses, DeleteMemberGroupByIdErrors, GetMemberGroupByIdData, GetMemberGroupByIdResponses, GetMemberGroupByIdErrors, PutMemberGroupByIdData, PutMemberGroupByIdResponses, PutMemberGroupByIdErrors, GetTreeMemberGroupRootData, GetTreeMemberGroupRootResponses, GetTreeMemberGroupRootErrors, GetItemMemberTypeData, GetItemMemberTypeResponses, GetItemMemberTypeErrors, GetItemMemberTypeSearchData, GetItemMemberTypeSearchResponses, GetItemMemberTypeSearchErrors, PostMemberTypeData, PostMemberTypeResponses, PostMemberTypeErrors, DeleteMemberTypeByIdData, DeleteMemberTypeByIdResponses, DeleteMemberTypeByIdErrors, GetMemberTypeByIdData, GetMemberTypeByIdResponses, GetMemberTypeByIdErrors, PutMemberTypeByIdData, PutMemberTypeByIdResponses, PutMemberTypeByIdErrors, GetMemberTypeByIdCompositionReferencesData, GetMemberTypeByIdCompositionReferencesResponses, GetMemberTypeByIdCompositionReferencesErrors, PostMemberTypeByIdCopyData, PostMemberTypeByIdCopyResponses, PostMemberTypeByIdCopyErrors, PostMemberTypeAvailableCompositionsData, PostMemberTypeAvailableCompositionsResponses, PostMemberTypeAvailableCompositionsErrors, GetMemberTypeConfigurationData, GetMemberTypeConfigurationResponses, GetMemberTypeConfigurationErrors, GetTreeMemberTypeRootData, GetTreeMemberTypeRootResponses, GetTreeMemberTypeRootErrors, GetFilterMemberData, GetFilterMemberResponses, GetFilterMemberErrors, GetItemMemberData, GetItemMemberResponses, GetItemMemberErrors, GetItemMemberSearchData, GetItemMemberSearchResponses, GetItemMemberSearchErrors, PostMemberData, PostMemberResponses, PostMemberErrors, DeleteMemberByIdData, DeleteMemberByIdResponses, DeleteMemberByIdErrors, GetMemberByIdData, GetMemberByIdResponses, GetMemberByIdErrors, PutMemberByIdData, PutMemberByIdResponses, PutMemberByIdErrors, GetMemberByIdReferencedByData, GetMemberByIdReferencedByResponses, GetMemberByIdReferencedByErrors, GetMemberByIdReferencedDescendantsData, GetMemberByIdReferencedDescendantsResponses, GetMemberByIdReferencedDescendantsErrors, PutMemberByIdValidateData, PutMemberByIdValidateResponses, PutMemberByIdValidateErrors, GetMemberAreReferencedData, GetMemberAreReferencedResponses, GetMemberAreReferencedErrors, GetMemberConfigurationData, GetMemberConfigurationResponses, GetMemberConfigurationErrors, PostMemberValidateData, PostMemberValidateResponses, PostMemberValidateErrors, PostModelsBuilderBuildData, PostModelsBuilderBuildResponses, PostModelsBuilderBuildErrors, GetModelsBuilderDashboardData, GetModelsBuilderDashboardResponses, GetModelsBuilderDashboardErrors, GetModelsBuilderStatusData, GetModelsBuilderStatusResponses, GetModelsBuilderStatusErrors, GetObjectTypesData, GetObjectTypesResponses, GetObjectTypesErrors, GetOembedQueryData, GetOembedQueryResponses, GetOembedQueryErrors, PostPackageByNameRunMigrationData, PostPackageByNameRunMigrationResponses, PostPackageByNameRunMigrationErrors, GetPackageConfigurationData, GetPackageConfigurationResponses, GetPackageConfigurationErrors, GetPackageCreatedData, GetPackageCreatedResponses, GetPackageCreatedErrors, PostPackageCreatedData, PostPackageCreatedResponses, PostPackageCreatedErrors, DeletePackageCreatedByIdData, DeletePackageCreatedByIdResponses, DeletePackageCreatedByIdErrors, GetPackageCreatedByIdData, GetPackageCreatedByIdResponses, GetPackageCreatedByIdErrors, PutPackageCreatedByIdData, PutPackageCreatedByIdResponses, PutPackageCreatedByIdErrors, GetPackageCreatedByIdDownloadData, GetPackageCreatedByIdDownloadResponses, GetPackageCreatedByIdDownloadErrors, GetPackageMigrationStatusData, GetPackageMigrationStatusResponses, GetPackageMigrationStatusErrors, GetItemPartialViewData, GetItemPartialViewResponses, GetItemPartialViewErrors, PostPartialViewData, PostPartialViewResponses, PostPartialViewErrors, DeletePartialViewByPathData, DeletePartialViewByPathResponses, DeletePartialViewByPathErrors, GetPartialViewByPathData, GetPartialViewByPathResponses, GetPartialViewByPathErrors, PutPartialViewByPathData, PutPartialViewByPathResponses, PutPartialViewByPathErrors, PutPartialViewByPathRenameData, PutPartialViewByPathRenameResponses, PutPartialViewByPathRenameErrors, PostPartialViewFolderData, PostPartialViewFolderResponses, PostPartialViewFolderErrors, DeletePartialViewFolderByPathData, DeletePartialViewFolderByPathResponses, DeletePartialViewFolderByPathErrors, GetPartialViewFolderByPathData, GetPartialViewFolderByPathResponses, GetPartialViewFolderByPathErrors, GetPartialViewSnippetData, GetPartialViewSnippetResponses, GetPartialViewSnippetErrors, GetPartialViewSnippetByIdData, GetPartialViewSnippetByIdResponses, GetPartialViewSnippetByIdErrors, GetTreePartialViewAncestorsData, GetTreePartialViewAncestorsResponses, GetTreePartialViewAncestorsErrors, GetTreePartialViewChildrenData, GetTreePartialViewChildrenResponses, GetTreePartialViewChildrenErrors, GetTreePartialViewRootData, GetTreePartialViewRootResponses, GetTreePartialViewRootErrors, DeletePreviewData, DeletePreviewResponses, PostPreviewData, PostPreviewResponses, PostPreviewErrors, GetProfilingStatusData, GetProfilingStatusResponses, GetProfilingStatusErrors, PutProfilingStatusData, PutProfilingStatusResponses, PutProfilingStatusErrors, GetPropertyTypeIsUsedData, GetPropertyTypeIsUsedResponses, GetPropertyTypeIsUsedErrors, PostPublishedCacheRebuildData, PostPublishedCacheRebuildResponses, PostPublishedCacheRebuildErrors, GetPublishedCacheRebuildStatusData, GetPublishedCacheRebuildStatusResponses, GetPublishedCacheRebuildStatusErrors, PostPublishedCacheReloadData, PostPublishedCacheReloadResponses, PostPublishedCacheReloadErrors, GetRedirectManagementData, GetRedirectManagementResponses, GetRedirectManagementErrors, DeleteRedirectManagementByIdData, DeleteRedirectManagementByIdResponses, DeleteRedirectManagementByIdErrors, GetRedirectManagementByIdData, GetRedirectManagementByIdResponses, GetRedirectManagementByIdErrors, GetRedirectManagementStatusData, GetRedirectManagementStatusResponses, GetRedirectManagementStatusErrors, PostRedirectManagementStatusData, PostRedirectManagementStatusResponses, PostRedirectManagementStatusErrors, GetItemRelationTypeData, GetItemRelationTypeResponses, GetItemRelationTypeErrors, GetRelationTypeData, GetRelationTypeResponses, GetRelationTypeErrors, GetRelationTypeByIdData, GetRelationTypeByIdResponses, GetRelationTypeByIdErrors, GetRelationByRelationTypeIdData, GetRelationByRelationTypeIdResponses, GetRelationByRelationTypeIdErrors, GetItemScriptData, GetItemScriptResponses, GetItemScriptErrors, PostScriptData, PostScriptResponses, PostScriptErrors, DeleteScriptByPathData, DeleteScriptByPathResponses, DeleteScriptByPathErrors, GetScriptByPathData, GetScriptByPathResponses, GetScriptByPathErrors, PutScriptByPathData, PutScriptByPathResponses, PutScriptByPathErrors, PutScriptByPathRenameData, PutScriptByPathRenameResponses, PutScriptByPathRenameErrors, PostScriptFolderData, PostScriptFolderResponses, PostScriptFolderErrors, DeleteScriptFolderByPathData, DeleteScriptFolderByPathResponses, DeleteScriptFolderByPathErrors, GetScriptFolderByPathData, GetScriptFolderByPathResponses, GetScriptFolderByPathErrors, GetTreeScriptAncestorsData, GetTreeScriptAncestorsResponses, GetTreeScriptAncestorsErrors, GetTreeScriptChildrenData, GetTreeScriptChildrenResponses, GetTreeScriptChildrenErrors, GetTreeScriptRootData, GetTreeScriptRootResponses, GetTreeScriptRootErrors, GetSearcherData, GetSearcherResponses, GetSearcherErrors, GetSearcherBySearcherNameQueryData, GetSearcherBySearcherNameQueryResponses, GetSearcherBySearcherNameQueryErrors, GetSecurityConfigurationData, GetSecurityConfigurationResponses, GetSecurityConfigurationErrors, PostSecurityForgotPasswordData, PostSecurityForgotPasswordResponses, PostSecurityForgotPasswordErrors, PostSecurityForgotPasswordResetData, PostSecurityForgotPasswordResetResponses, PostSecurityForgotPasswordResetErrors, PostSecurityForgotPasswordVerifyData, PostSecurityForgotPasswordVerifyResponses, PostSecurityForgotPasswordVerifyErrors, GetSegmentData, GetSegmentResponses, GetSegmentErrors, GetServerConfigurationData, GetServerConfigurationResponses, GetServerInformationData, GetServerInformationResponses, GetServerInformationErrors, GetServerStatusData, GetServerStatusResponses, GetServerStatusErrors, GetServerTroubleshootingData, GetServerTroubleshootingResponses, GetServerTroubleshootingErrors, GetServerUpgradeCheckData, GetServerUpgradeCheckResponses, GetServerUpgradeCheckErrors, GetItemStaticFileData, GetItemStaticFileResponses, GetItemStaticFileErrors, GetTreeStaticFileAncestorsData, GetTreeStaticFileAncestorsResponses, GetTreeStaticFileAncestorsErrors, GetTreeStaticFileChildrenData, GetTreeStaticFileChildrenResponses, GetTreeStaticFileChildrenErrors, GetTreeStaticFileRootData, GetTreeStaticFileRootResponses, GetTreeStaticFileRootErrors, GetItemStylesheetData, GetItemStylesheetResponses, GetItemStylesheetErrors, PostStylesheetData, PostStylesheetResponses, PostStylesheetErrors, DeleteStylesheetByPathData, DeleteStylesheetByPathResponses, DeleteStylesheetByPathErrors, GetStylesheetByPathData, GetStylesheetByPathResponses, GetStylesheetByPathErrors, PutStylesheetByPathData, PutStylesheetByPathResponses, PutStylesheetByPathErrors, PutStylesheetByPathRenameData, PutStylesheetByPathRenameResponses, PutStylesheetByPathRenameErrors, PostStylesheetFolderData, PostStylesheetFolderResponses, PostStylesheetFolderErrors, DeleteStylesheetFolderByPathData, DeleteStylesheetFolderByPathResponses, DeleteStylesheetFolderByPathErrors, GetStylesheetFolderByPathData, GetStylesheetFolderByPathResponses, GetStylesheetFolderByPathErrors, GetTreeStylesheetAncestorsData, GetTreeStylesheetAncestorsResponses, GetTreeStylesheetAncestorsErrors, GetTreeStylesheetChildrenData, GetTreeStylesheetChildrenResponses, GetTreeStylesheetChildrenErrors, GetTreeStylesheetRootData, GetTreeStylesheetRootResponses, GetTreeStylesheetRootErrors, GetTagData, GetTagResponses, GetTagErrors, GetTelemetryData, GetTelemetryResponses, GetTelemetryErrors, GetTelemetryLevelData, GetTelemetryLevelResponses, GetTelemetryLevelErrors, PostTelemetryLevelData, PostTelemetryLevelResponses, PostTelemetryLevelErrors, GetItemTemplateData, GetItemTemplateResponses, GetItemTemplateErrors, GetItemTemplateSearchData, GetItemTemplateSearchResponses, GetItemTemplateSearchErrors, PostTemplateData, PostTemplateResponses, PostTemplateErrors, DeleteTemplateByIdData, DeleteTemplateByIdResponses, DeleteTemplateByIdErrors, GetTemplateByIdData, GetTemplateByIdResponses, GetTemplateByIdErrors, PutTemplateByIdData, PutTemplateByIdResponses, PutTemplateByIdErrors, GetTemplateConfigurationData, GetTemplateConfigurationResponses, GetTemplateConfigurationErrors, PostTemplateQueryExecuteData, PostTemplateQueryExecuteResponses, PostTemplateQueryExecuteErrors, GetTemplateQuerySettingsData, GetTemplateQuerySettingsResponses, GetTemplateQuerySettingsErrors, GetTreeTemplateAncestorsData, GetTreeTemplateAncestorsResponses, GetTreeTemplateAncestorsErrors, GetTreeTemplateChildrenData, GetTreeTemplateChildrenResponses, GetTreeTemplateChildrenErrors, GetTreeTemplateRootData, GetTreeTemplateRootResponses, GetTreeTemplateRootErrors, GetTreeTemplateSiblingsData, GetTreeTemplateSiblingsResponses, GetTreeTemplateSiblingsErrors, PostTemporaryFileData, PostTemporaryFileResponses, PostTemporaryFileErrors, DeleteTemporaryFileByIdData, DeleteTemporaryFileByIdResponses, DeleteTemporaryFileByIdErrors, GetTemporaryFileByIdData, GetTemporaryFileByIdResponses, GetTemporaryFileByIdErrors, GetTemporaryFileConfigurationData, GetTemporaryFileConfigurationResponses, GetTemporaryFileConfigurationErrors, PostUpgradeAuthorizeData, PostUpgradeAuthorizeResponses, PostUpgradeAuthorizeErrors, GetUpgradeSettingsData, GetUpgradeSettingsResponses, GetUpgradeSettingsErrors, GetUserDataData, GetUserDataResponses, GetUserDataErrors, PostUserDataData, PostUserDataResponses, PostUserDataErrors, PutUserDataData, PutUserDataResponses, PutUserDataErrors, GetUserDataByIdData, GetUserDataByIdResponses, GetUserDataByIdErrors, GetFilterUserGroupData, GetFilterUserGroupResponses, GetFilterUserGroupErrors, GetItemUserGroupData, GetItemUserGroupResponses, GetItemUserGroupErrors, DeleteUserGroupData, DeleteUserGroupResponses, DeleteUserGroupErrors, GetUserGroupData, GetUserGroupResponses, GetUserGroupErrors, PostUserGroupData, PostUserGroupResponses, PostUserGroupErrors, DeleteUserGroupByIdData, DeleteUserGroupByIdResponses, DeleteUserGroupByIdErrors, GetUserGroupByIdData, GetUserGroupByIdResponses, GetUserGroupByIdErrors, PutUserGroupByIdData, PutUserGroupByIdResponses, PutUserGroupByIdErrors, DeleteUserGroupByIdUsersData, DeleteUserGroupByIdUsersResponses, DeleteUserGroupByIdUsersErrors, PostUserGroupByIdUsersData, PostUserGroupByIdUsersResponses, PostUserGroupByIdUsersErrors, GetFilterUserData, GetFilterUserResponses, GetFilterUserErrors, GetItemUserData, GetItemUserResponses, GetItemUserErrors, DeleteUserData, DeleteUserResponses, DeleteUserErrors, GetUserData, GetUserResponses, GetUserErrors, PostUserData, PostUserResponses, PostUserErrors, DeleteUserByIdData, DeleteUserByIdResponses, DeleteUserByIdErrors, GetUserByIdData, GetUserByIdResponses, GetUserByIdErrors, PutUserByIdData, PutUserByIdResponses, PutUserByIdErrors, GetUserById2FaData, GetUserById2FaResponses, GetUserById2FaErrors, DeleteUserById2FaByProviderNameData, DeleteUserById2FaByProviderNameResponses, DeleteUserById2FaByProviderNameErrors, GetUserByIdCalculateStartNodesData, GetUserByIdCalculateStartNodesResponses, GetUserByIdCalculateStartNodesErrors, PostUserByIdChangePasswordData, PostUserByIdChangePasswordResponses, PostUserByIdChangePasswordErrors, GetUserByIdClientCredentialsData, GetUserByIdClientCredentialsResponses, GetUserByIdClientCredentialsErrors, PostUserByIdClientCredentialsData, PostUserByIdClientCredentialsResponses, PostUserByIdClientCredentialsErrors, DeleteUserByIdClientCredentialsByClientIdData, DeleteUserByIdClientCredentialsByClientIdResponses, DeleteUserByIdClientCredentialsByClientIdErrors, PostUserByIdResetPasswordData, PostUserByIdResetPasswordResponses, PostUserByIdResetPasswordErrors, DeleteUserAvatarByIdData, DeleteUserAvatarByIdResponses, DeleteUserAvatarByIdErrors, PostUserAvatarByIdData, PostUserAvatarByIdResponses, PostUserAvatarByIdErrors, GetUserConfigurationData, GetUserConfigurationResponses, GetUserConfigurationErrors, GetUserCurrentData, GetUserCurrentResponses, GetUserCurrentErrors, GetUserCurrent2FaData, GetUserCurrent2FaResponses, GetUserCurrent2FaErrors, DeleteUserCurrent2FaByProviderNameData, DeleteUserCurrent2FaByProviderNameResponses, DeleteUserCurrent2FaByProviderNameErrors, GetUserCurrent2FaByProviderNameData, GetUserCurrent2FaByProviderNameResponses, GetUserCurrent2FaByProviderNameErrors, PostUserCurrent2FaByProviderNameData, PostUserCurrent2FaByProviderNameResponses, PostUserCurrent2FaByProviderNameErrors, PostUserCurrentAvatarData, PostUserCurrentAvatarResponses, PostUserCurrentAvatarErrors, PostUserCurrentChangePasswordData, PostUserCurrentChangePasswordResponses, PostUserCurrentChangePasswordErrors, GetUserCurrentConfigurationData, GetUserCurrentConfigurationResponses, GetUserCurrentConfigurationErrors, GetUserCurrentLoginProvidersData, GetUserCurrentLoginProvidersResponses, GetUserCurrentLoginProvidersErrors, GetUserCurrentPermissionsData, GetUserCurrentPermissionsResponses, GetUserCurrentPermissionsErrors, GetUserCurrentPermissionsDocumentData, GetUserCurrentPermissionsDocumentResponses, GetUserCurrentPermissionsDocumentErrors, GetUserCurrentPermissionsMediaData, GetUserCurrentPermissionsMediaResponses, GetUserCurrentPermissionsMediaErrors, PostUserDisableData, PostUserDisableResponses, PostUserDisableErrors, PostUserEnableData, PostUserEnableResponses, PostUserEnableErrors, PostUserInviteData, PostUserInviteResponses, PostUserInviteErrors, PostUserInviteCreatePasswordData, PostUserInviteCreatePasswordResponses, PostUserInviteCreatePasswordErrors, PostUserInviteResendData, PostUserInviteResendResponses, PostUserInviteResendErrors, PostUserInviteVerifyData, PostUserInviteVerifyResponses, PostUserInviteVerifyErrors, PostUserSetUserGroupsData, PostUserSetUserGroupsResponses, PostUserSetUserGroupsErrors, PostUserUnlockData, PostUserUnlockResponses, PostUserUnlockErrors, GetItemWebhookData, GetItemWebhookResponses, GetItemWebhookErrors, GetWebhookData, GetWebhookResponses, GetWebhookErrors, PostWebhookData, PostWebhookResponses, PostWebhookErrors, DeleteWebhookByIdData, DeleteWebhookByIdResponses, DeleteWebhookByIdErrors, GetWebhookByIdData, GetWebhookByIdResponses, GetWebhookByIdErrors, PutWebhookByIdData, PutWebhookByIdResponses, PutWebhookByIdErrors, GetWebhookByIdLogsData, GetWebhookByIdLogsResponses, GetWebhookByIdLogsErrors, GetWebhookEventsData, GetWebhookEventsResponses, GetWebhookEventsErrors, GetWebhookLogsData, GetWebhookLogsResponses, GetWebhookLogsErrors } from './types.gen'; import { client as _heyApiClient } from './client.gen'; @@ -1160,6 +1160,29 @@ export class DocumentVersionService { } } +class DocumentByIdValidate1Service { + public static putUmbracoManagementApiV11DocumentByIdValidate11(options: Options) { + return (options.client ?? _heyApiClient).put({ + security: [ + { + scheme: 'bearer', + type: 'http' + } + ], + url: '/umbraco/management/api/v1.1/document/{id}/validate', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } + }); + } +} + +class PutUmbracoManagementApiV1Service { + static documentByIdValidate1Service = DocumentByIdValidate1Service; +} + export class DocumentService { public static getCollectionDocumentById(options: Options) { return (options.client ?? _heyApiClient).get({ @@ -1517,23 +1540,6 @@ export class DocumentService { }); } - public static putUmbracoManagementApiV11DocumentByIdValidate11(options: Options) { - return (options.client ?? _heyApiClient).put({ - security: [ - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/umbraco/management/api/v1.1/document/{id}/validate', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }); - } - public static getDocumentAreReferenced(options?: Options) { return (options?.client ?? _heyApiClient).get({ security: [ @@ -1779,6 +1785,7 @@ export class DocumentService { ...options }); } + static putUmbracoManagementApiV1Service = PutUmbracoManagementApiV1Service; } export class DynamicRootService { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/types.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/types.gen.ts index 15d6395949..115dd08c87 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/types.gen.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/types.gen.ts @@ -1124,14 +1124,8 @@ export type IndexResponseModel = { } | null; }; -export type InstallRequestModelReadable = { - user: UserInstallRequestModelReadable; - database: DatabaseInstallRequestModel; - telemetryLevel: TelemetryLevelModel; -}; - -export type InstallRequestModelWritable = { - user: UserInstallRequestModelWritable; +export type InstallRequestModel = { + user: UserInstallRequestModel; database: DatabaseInstallRequestModel; telemetryLevel: TelemetryLevelModel; }; @@ -1707,7 +1701,7 @@ export type PackageConfigurationResponseModel = { marketplaceUrl: string; }; -export type PackageDefinitionResponseModelReadable = { +export type PackageDefinitionResponseModel = { name: string; contentNodeId?: string | null; contentLoadChildNodes: boolean; @@ -1726,24 +1720,6 @@ export type PackageDefinitionResponseModelReadable = { readonly packagePath: string; }; -export type PackageDefinitionResponseModelWritable = { - name: string; - contentNodeId?: string | null; - contentLoadChildNodes: boolean; - mediaIds: Array; - mediaLoadChildNodes: boolean; - documentTypes: Array; - mediaTypes: Array; - dataTypes: Array; - templates: Array; - partialViews: Array; - stylesheets: Array; - scripts: Array; - languages: Array; - dictionaryItems: Array; - id: string; -}; - export type PackageMigrationStatusResponseModel = { packageName: string; hasPendingMigrations: boolean; @@ -1949,14 +1925,9 @@ export type PagedObjectTypeResponseModel = { items: Array; }; -export type PagedPackageDefinitionResponseModelReadable = { +export type PagedPackageDefinitionResponseModel = { total: number; - items: Array; -}; - -export type PagedPackageDefinitionResponseModelWritable = { - total: number; - items: Array; + items: Array; }; export type PagedPackageMigrationStatusResponseModel = { @@ -1984,14 +1955,9 @@ export type PagedReferenceByIdModel = { items: Array; }; -export type PagedRelationResponseModelReadable = { +export type PagedRelationResponseModel = { total: number; - items: Array; -}; - -export type PagedRelationResponseModelWritable = { - total: number; - items: Array; + items: Array; }; export type PagedRelationTypeResponseModel = { @@ -2004,14 +1970,9 @@ export type PagedSavedLogSearchResponseModel = { items: Array; }; -export type PagedSearchResultResponseModelReadable = { +export type PagedSearchResultResponseModel = { total: number; - items: Array; -}; - -export type PagedSearchResultResponseModelWritable = { - total: number; - items: Array; + items: Array; }; export type PagedSearcherResponseModel = { @@ -2209,7 +2170,7 @@ export type RelationReferenceModel = { name?: string | null; }; -export type RelationResponseModelReadable = { +export type RelationResponseModel = { id: string; relationType: ReferenceByIdModel; parent: RelationReferenceModel; @@ -2218,13 +2179,6 @@ export type RelationResponseModelReadable = { readonly comment?: string | null; }; -export type RelationResponseModelWritable = { - id: string; - relationType: ReferenceByIdModel; - parent: RelationReferenceModel; - child: RelationReferenceModel; -}; - export type RelationTypeItemResponseModel = { id: string; signs: Array; @@ -2323,19 +2277,13 @@ export type ScriptResponseModel = { content: string; }; -export type SearchResultResponseModelReadable = { +export type SearchResultResponseModel = { id: string; score: number; readonly fieldCount: number; fields: Array; }; -export type SearchResultResponseModelWritable = { - id: string; - score: number; - fields: Array; -}; - export type SearcherResponseModel = { name: string; }; @@ -2788,7 +2736,7 @@ export type UpdateMemberTypeRequestModel = { compositions: Array; }; -export type UpdatePackageRequestModelReadable = { +export type UpdatePackageRequestModel = { name: string; contentNodeId?: string | null; contentLoadChildNodes: boolean; @@ -2806,23 +2754,6 @@ export type UpdatePackageRequestModelReadable = { readonly packagePath: string; }; -export type UpdatePackageRequestModelWritable = { - name: string; - contentNodeId?: string | null; - contentLoadChildNodes: boolean; - mediaIds: Array; - mediaLoadChildNodes: boolean; - documentTypes: Array; - mediaTypes: Array; - dataTypes: Array; - templates: Array; - partialViews: Array; - stylesheets: Array; - scripts: Array; - languages: Array; - dictionaryItems: Array; -}; - export type UpdatePartialViewRequestModel = { content: string; }; @@ -2898,7 +2829,7 @@ export type UpgradeCheckResponseModel = { url: string; }; -export type UpgradeSettingsResponseModelReadable = { +export type UpgradeSettingsResponseModel = { currentState: string; newState: string; newVersion: string; @@ -2906,13 +2837,6 @@ export type UpgradeSettingsResponseModelReadable = { readonly reportUrl: string; }; -export type UpgradeSettingsResponseModelWritable = { - currentState: string; - newState: string; - newVersion: string; - oldVersion: string; -}; - export type UserConfigurationResponseModel = { canInviteUsers: boolean; usernameIsEmail: boolean; @@ -2974,19 +2898,13 @@ export type UserGroupResponseModel = { aliasCanBeChanged: boolean; }; -export type UserInstallRequestModelReadable = { +export type UserInstallRequestModel = { name: string; email: string; password: string; readonly subscribeToNewsletter: boolean; }; -export type UserInstallRequestModelWritable = { - name: string; - email: string; - password: string; -}; - export type UserItemResponseModel = { id: string; signs: Array; @@ -7681,7 +7599,7 @@ export type GetInstallSettingsResponses = { export type GetInstallSettingsResponse = GetInstallSettingsResponses[keyof GetInstallSettingsResponses]; export type PostInstallSetupData = { - body?: InstallRequestModelWritable; + body?: InstallRequestModel; path?: never; query?: never; url: '/umbraco/management/api/v1/install/setup'; @@ -11375,7 +11293,7 @@ export type GetPackageCreatedResponses = { /** * OK */ - 200: PagedPackageDefinitionResponseModelReadable; + 200: PagedPackageDefinitionResponseModel; }; export type GetPackageCreatedResponse = GetPackageCreatedResponses[keyof GetPackageCreatedResponses]; @@ -11478,13 +11396,13 @@ export type GetPackageCreatedByIdResponses = { /** * OK */ - 200: PackageDefinitionResponseModelReadable; + 200: PackageDefinitionResponseModel; }; export type GetPackageCreatedByIdResponse = GetPackageCreatedByIdResponses[keyof GetPackageCreatedByIdResponses]; export type PutPackageCreatedByIdData = { - body?: UpdatePackageRequestModelWritable; + body?: UpdatePackageRequestModel; path: { id: string; }; @@ -12510,7 +12428,7 @@ export type GetRelationByRelationTypeIdResponses = { /** * OK */ - 200: PagedRelationResponseModelReadable; + 200: PagedRelationResponseModel; }; export type GetRelationByRelationTypeIdResponse = GetRelationByRelationTypeIdResponses[keyof GetRelationByRelationTypeIdResponses]; @@ -12974,7 +12892,7 @@ export type GetSearcherBySearcherNameQueryResponses = { /** * OK */ - 200: PagedSearchResultResponseModelReadable; + 200: PagedSearchResultResponseModel; }; export type GetSearcherBySearcherNameQueryResponse = GetSearcherBySearcherNameQueryResponses[keyof GetSearcherBySearcherNameQueryResponses]; @@ -14454,7 +14372,7 @@ export type GetUpgradeSettingsResponses = { /** * OK */ - 200: UpgradeSettingsResponseModelReadable; + 200: UpgradeSettingsResponseModel; }; export type GetUpgradeSettingsResponse = GetUpgradeSettingsResponses[keyof GetUpgradeSettingsResponses]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/http-client/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/http-client/index.ts index 8b39688895..450649ecb2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/http-client/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/http-client/index.ts @@ -1,2 +1 @@ export { client as umbHttpClient } from '@umbraco-cms/backoffice/external/backend-api'; -export type { RequestOptions } from '@hey-api/client-fetch'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/openapi-ts.config.js b/src/Umbraco.Web.UI.Client/src/packages/core/openapi-ts.config.js index 41ee9c4301..db0a583eb4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/openapi-ts.config.js +++ b/src/Umbraco.Web.UI.Client/src/packages/core/openapi-ts.config.js @@ -1,7 +1,6 @@ import { defineConfig } from '@hey-api/openapi-ts'; export default defineConfig({ - debug: true, input: '../../../../Umbraco.Cms.Api.Management/OpenApi.json', output: { path: './backend-api', @@ -9,7 +8,6 @@ export default defineConfig({ plugins: [ { name: '@hey-api/client-fetch', - bundle: false, exportFromIndex: true, throwOnError: true, }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/package.json b/src/Umbraco.Web.UI.Client/src/packages/core/package.json index d4907d423e..ea1d94d79a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/package.json +++ b/src/Umbraco.Web.UI.Client/src/packages/core/package.json @@ -10,9 +10,6 @@ "@types/diff": "^7.0.2", "diff": "^7.0.0", "uuid": "^11.1.0", - "@hey-api/client-fetch": "^0.12.0" - }, - "devDependencies": { - "@hey-api/openapi-ts": "^0.71.0" + "@hey-api/openapi-ts": "0.81.1" } } \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/resources/api-interceptor.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/resources/api-interceptor.controller.ts index b5a0dc6c38..35436b03e0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/resources/api-interceptor.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/resources/api-interceptor.controller.ts @@ -5,7 +5,7 @@ import type { UmbProblemDetails } from './types.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import { UMB_AUTH_CONTEXT } from '@umbraco-cms/backoffice/auth'; import type { UmbNotificationColor } from '@umbraco-cms/backoffice/notification'; -import type { RequestOptions, umbHttpClient } from '@umbraco-cms/backoffice/http-client'; +import type { umbHttpClient } from '@umbraco-cms/backoffice/http-client'; const MAX_RETRIES = 3; @@ -16,7 +16,7 @@ export class UmbApiInterceptorController extends UmbControllerBase { */ #pending401Requests: Array<{ request: Request; - requestConfig: RequestOptions; + requestConfig: unknown; retry: () => Promise; resolve: (value: Response) => void; reject: (reason?: unknown) => void; @@ -29,7 +29,7 @@ export class UmbApiInterceptorController extends UmbControllerBase { * These requests will not be retried, as they are not idempotent. * Instead, we will notify the user about these requests after re-authentication. */ - #nonGet401Requests: Array<{ request: Request; requestConfig: RequestOptions }> = []; + #nonGet401Requests: Array<{ request: Request; requestConfig: unknown }> = []; /** * Binds the default interceptors to the client. diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts index 661687bc54..68b04408a0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts @@ -87,10 +87,12 @@ export class UmbDocumentValidationServerDataSource { // Maybe use: tryExecuteAndNotify const { data, error } = await tryExecute( this.#host, - DocumentService.putUmbracoManagementApiV11DocumentByIdValidate11({ - path: { id: model.unique }, - body, - }), + DocumentService.putUmbracoManagementApiV1Service.documentByIdValidate1Service.putUmbracoManagementApiV11DocumentByIdValidate11( + { + path: { id: model.unique }, + body, + }, + ), { disableNotifications: true, }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/sources/package.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/sources/package.server.data.ts index 945c7fe590..2277694786 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/sources/package.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/sources/package.server.data.ts @@ -2,13 +2,13 @@ import { tryExecute } from '@umbraco-cms/backoffice/resources'; import { ManifestService, PackageService } from '@umbraco-cms/backoffice/external/backend-api'; import type { CreatePackageRequestModel, - UpdatePackageRequestModelWritable, + UpdatePackageRequestModel, } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; /** * Data source for packages from the server - + */ export class UmbPackageServerDataSource { constructor(private readonly _host: UmbControllerHost) {} @@ -57,7 +57,7 @@ export class UmbPackageServerDataSource { return await tryExecute(this._host, PackageService.postPackageCreated({ body })); } - async updateCreatedPackage(id: string, body: UpdatePackageRequestModelWritable) { + async updateCreatedPackage(id: string, body: UpdatePackageRequestModel) { return await tryExecute(this._host, PackageService.putPackageCreatedById({ path: { id }, body })); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts index 3a59d87d6b..664ca34f3a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts @@ -1,9 +1,6 @@ import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; -import type { - FieldPresentationModel, - SearchResultResponseModelReadable, -} from '@umbraco-cms/backoffice/external/backend-api'; +import type { FieldPresentationModel, SearchResultResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbPagedModel, UmbRepositoryResponse } from '@umbraco-cms/backoffice/repository'; export type { UmbSearchDataSource } from './search-data-source.interface.js'; @@ -12,7 +9,7 @@ export type { UmbSearchRepository } from './search-repository.interface.js'; export type * from './extensions/types.js'; export type * from './global-search/types.js'; -export type UmbSearchResultModel = SearchResultResponseModelReadable; +export type UmbSearchResultModel = SearchResultResponseModel; // TODO: lower requirement for search provider item type export type UmbSearchResultItemModel = { diff --git a/src/Umbraco.Web.UI.Login/openapi-ts.config.ts b/src/Umbraco.Web.UI.Login/openapi-ts.config.ts index a91eeeb123..623ee2a4cd 100644 --- a/src/Umbraco.Web.UI.Login/openapi-ts.config.ts +++ b/src/Umbraco.Web.UI.Login/openapi-ts.config.ts @@ -2,10 +2,21 @@ import { defineConfig } from '@hey-api/openapi-ts'; export default defineConfig({ input: { - include: - '(ProblemDetails|ReferenceByIdModel|ResetPassword|PasswordConfiguration|SecurityConfiguration|InviteUser|CreateInitialPasswordUser|/security/|/user/invite/)', path: '../Umbraco.Cms.Api.Management/OpenApi.json', }, + parser: { + filters: { + operations: { + include: [ + 'POST /umbraco/management/api/v1/security/forgot-password', + 'POST /umbraco/management/api/v1/security/forgot-password/verify', + 'POST /umbraco/management/api/v1/security/forgot-password/reset', + 'POST /umbraco/management/api/v1/user/invite/verify', + 'POST /umbraco/management/api/v1/user/invite/create-password', + ], + }, + }, + }, output: { path: './src/api', }, diff --git a/src/Umbraco.Web.UI.Login/package-lock.json b/src/Umbraco.Web.UI.Login/package-lock.json index c46cff217d..130dc369c4 100644 --- a/src/Umbraco.Web.UI.Login/package-lock.json +++ b/src/Umbraco.Web.UI.Login/package-lock.json @@ -6,9 +6,8 @@ "": { "name": "login", "devDependencies": { - "@hey-api/client-fetch": "^0.10.2", - "@hey-api/openapi-ts": "^0.67.6", - "@umbraco-cms/backoffice": "16.0.0-rc4", + "@hey-api/openapi-ts": "0.81.1", + "@umbraco-cms/backoffice": "16.2.0-rc", "msw": "^2.7.0", "typescript": "^5.9.2", "vite": "^7.1.3" @@ -474,12 +473,25 @@ "node": ">=18" } }, + "node_modules/@heximal/expressions": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@heximal/expressions/-/expressions-0.1.5.tgz", + "integrity": "sha512-QdWz9vNrdzi24so9KGEM9w4UYLg1yk+LVvYBEDbw9EY1BzKHITWdtYc55xJ3Zuio0/9Naz/D1YtYlCnfsycNDQ==", + "dev": true, + "license": "BSD 3-Clause", + "peer": true, + "dependencies": { + "tslib": "^2.7.0" + } + }, "node_modules/@hey-api/client-fetch": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@hey-api/client-fetch/-/client-fetch-0.10.2.tgz", - "integrity": "sha512-AGiFYDx+y8VT1wlQ3EbzzZtfU8EfV+hLLRTtr8Y/tjYZaxIECwJagVZf24YzNbtEBXONFV50bwcU1wLVGXe1ow==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@hey-api/client-fetch/-/client-fetch-0.12.0.tgz", + "integrity": "sha512-/iZ6dhs39N0kjzCa9tlNeLNufVUd8zzv/wI1ewQt5AEHaVuDnAxvuQT+fRIPYkfIWKR3gVZKRp5mcCo29voYzQ==", + "deprecated": "Starting with v0.73.0, this package is bundled directly inside @hey-api/openapi-ts.", "dev": true, "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/hey-api" }, @@ -507,16 +519,21 @@ } }, "node_modules/@hey-api/openapi-ts": { - "version": "0.67.6", - "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.67.6.tgz", - "integrity": "sha512-ywZggKKYieVjM6O6T60/Bl+QBRvhcKAov8dAIQor7reyKpFbEn3Ws+9WKoXR8QUuXN8AR8nMFjOuYPer5db/dg==", + "version": "0.81.1", + "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.81.1.tgz", + "integrity": "sha512-DdLEMbfQRMRDd+cOxG91G7Ro7vUUtt/zYlBGiYTahVO/4rn1HHnYl/WHL+to5I7CTX3sVVsVrxHWcJd0Fue7wg==", "dev": true, "license": "MIT", "dependencies": { "@hey-api/json-schema-ref-parser": "1.0.6", + "ansi-colors": "4.1.3", "c12": "2.0.1", + "color-support": "1.1.3", "commander": "13.0.0", - "handlebars": "4.7.8" + "handlebars": "4.7.8", + "js-yaml": "4.1.0", + "open": "10.1.2", + "semver": "7.7.2" }, "bin": { "openapi-ts": "bin/index.cjs" @@ -617,22 +634,22 @@ "license": "MIT" }, "node_modules/@lit-labs/ssr-dom-shim": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.3.0.tgz", - "integrity": "sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.4.0.tgz", + "integrity": "sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==", "dev": true, "license": "BSD-3-Clause", "peer": true }, "node_modules/@lit/reactive-element": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.0.tgz", - "integrity": "sha512-L2qyoZSQClcBmq0qajBVbhYEcG6iK0XfLn66ifLe/RfC0/ihpc+pl0Wdn8bJ8o+hj38cG0fGXRgSS20MuXn7qA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.1.tgz", + "integrity": "sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==", "dev": true, "license": "BSD-3-Clause", "peer": true, "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.2.0" + "@lit-labs/ssr-dom-shim": "^1.4.0" } }, "node_modules/@mswjs/interceptors": { @@ -967,9 +984,9 @@ ] }, "node_modules/@tiptap/core": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.11.7.tgz", - "integrity": "sha512-zN+NFFxLsxNEL8Qioc+DL6b8+Tt2bmRbXH22Gk6F6nD30x83eaUSFlSv3wqvgyCq3I1i1NO394So+Agmayx6rQ==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.26.1.tgz", + "integrity": "sha512-fymyd/XZvYiHjBoLt1gxs024xP/LY26d43R1vluYq7AHBL/7DE3ywzy+1GEsGyAv5Je2L0KBhNIR/izbq3Kaqg==", "dev": true, "license": "MIT", "peer": true, @@ -982,9 +999,9 @@ } }, "node_modules/@tiptap/extension-blockquote": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.12.0.tgz", - "integrity": "sha512-XUC2A77YAPMJS2SqZ2S62IGcUH8gZ7cdhoWlYQb1pR4ZzXFByeKDJPxfYeAePSiuI01YGrlzgY2c6Ncx/DtO0A==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.26.1.tgz", + "integrity": "sha512-viQ6AHRhjCYYipKK6ZepBzwZpkuMvO9yhRHeUZDvlSOAh8rvsUTSre0y74nu8QRYUt4a44lJJ6BpphJK7bEgYA==", "dev": true, "license": "MIT", "peer": true, @@ -997,9 +1014,9 @@ } }, "node_modules/@tiptap/extension-bold": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.12.0.tgz", - "integrity": "sha512-lAUtoLDLRc5ofD2I9MFY6MQ7d1qBLLqS1rvpwaPjOaoQb/GPVnaHj9qXYG0SY9K3erMtto48bMFpAcscjZHzZQ==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.26.1.tgz", + "integrity": "sha512-zCce9PRuTNhadFir71luLo99HERDpGJ0EEflGm7RN8I1SnNi9gD5ooK42BOIQtejGCJqg3hTPZiYDJC2hXvckQ==", "dev": true, "license": "MIT", "peer": true, @@ -1012,9 +1029,9 @@ } }, "node_modules/@tiptap/extension-bullet-list": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.12.0.tgz", - "integrity": "sha512-YTCjztB8MaIpwyxFYr81H4+LdKCq1VlaSXQyrPdB44mVdhhRqc46BYQb8/B//XE3UIu3X2QWFjwrqRlUq6vUiw==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.26.1.tgz", + "integrity": "sha512-HHakuV4ckYCDOnBbne088FvCEP4YICw+wgPBz/V2dfpiFYQ4WzT0LPK9s7OFMCN+ROraoug+1ryN1Z1KdIgujQ==", "dev": true, "license": "MIT", "peer": true, @@ -1027,9 +1044,9 @@ } }, "node_modules/@tiptap/extension-character-count": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-character-count/-/extension-character-count-2.11.7.tgz", - "integrity": "sha512-gcVbKou+uxzg8N0BBKceLwtpWvN8g2TIjTuCdyAcAPukX63DqVWOkofFHn1RqZbstJmtF4pTGZs9OH/GJrp27Q==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-character-count/-/extension-character-count-2.26.1.tgz", + "integrity": "sha512-F7LP1a9GF28thbApowWT2I41baqX74HMUTrV9LGrNXaOkW2gxZz+CDOzfHsbHyfuwfIxIjv07Qf/HKA6Cc1qbA==", "dev": true, "license": "MIT", "peer": true, @@ -1043,9 +1060,9 @@ } }, "node_modules/@tiptap/extension-code": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.12.0.tgz", - "integrity": "sha512-R7RaS+hJeHFim7alImQ9L9CSWSMjWXvz0Ote568x9ea5gdBGUYW8PcH+5a91lh8e1XGYWBM12a8oJZRyxg/tQA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.26.1.tgz", + "integrity": "sha512-GU9deB1A/Tr4FMPu71CvlcjGKwRhGYz60wQ8m4aM+ELZcVIcZRa1ebR8bExRIEWnvRztQuyRiCQzw2N0xQJ1QQ==", "dev": true, "license": "MIT", "peer": true, @@ -1058,9 +1075,9 @@ } }, "node_modules/@tiptap/extension-code-block": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.12.0.tgz", - "integrity": "sha512-1D7cYAjgxEFHdfC/35Ooi4GqWKB5sszbW8iI7N16XILNln26xb0d5KflXqYrwr9CN/ZnZoCl2o6YsP7xEObcZA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.26.1.tgz", + "integrity": "sha512-/TDDOwONl0qEUc4+B6V9NnWtSjz95eg7/8uCb8Y8iRbGvI9vT4/znRKofFxstvKmW4URu/H74/g0ywV57h0B+A==", "dev": true, "license": "MIT", "peer": true, @@ -1074,9 +1091,9 @@ } }, "node_modules/@tiptap/extension-document": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.12.0.tgz", - "integrity": "sha512-sA1Q+mxDIv0Y3qQTBkYGwknNbDcGFiJ/fyAFholXpqbrcRx3GavwR/o0chBdsJZlFht0x7AWGwUYWvIo7wYilA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.26.1.tgz", + "integrity": "sha512-2P2IZp1NRAE+21mRuFBiP3X2WKfZ6kUC23NJKpn8bcOamY3obYqCt0ltGPhE4eR8n8QAl2fI/3jIgjR07dC8ow==", "dev": true, "license": "MIT", "peer": true, @@ -1089,9 +1106,9 @@ } }, "node_modules/@tiptap/extension-dropcursor": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.12.0.tgz", - "integrity": "sha512-zcZSOXFj+7LVnmdPWTfKr5AoxYIzFPFlLJe35AdTQC5IhkljLn1Exct8I30ZREojX/00hKYsO7JJmePS6TEVlQ==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.26.1.tgz", + "integrity": "sha512-JkDQU2ZYFOuT5mNYb8OiWGwD1HcjbtmX8tLNugQbToECmz9WvVPqJmn7V/q8VGpP81iEECz/IsyRmuf2kSD4uA==", "dev": true, "license": "MIT", "peer": true, @@ -1105,9 +1122,9 @@ } }, "node_modules/@tiptap/extension-gapcursor": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.12.0.tgz", - "integrity": "sha512-k8ji5v9YKn7bNjo8UtI9hEfXfl4tKUp1hpJOEmUxGJQa3LIwrwSbReupUTnHszGQelzxikS/l1xO9P0TIGwRoA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.26.1.tgz", + "integrity": "sha512-KOiMZc3PwJS3hR0nSq5d0TJi2jkNZkLZElcT6pCEnhRHzPH6dRMu9GM5Jj798ZRUy0T9UFcKJalFZaDxnmRnpg==", "dev": true, "license": "MIT", "peer": true, @@ -1121,9 +1138,9 @@ } }, "node_modules/@tiptap/extension-hard-break": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.12.0.tgz", - "integrity": "sha512-08MNS2PK5DzdnAfqXn4krmJ/xebKmWpRpYqqN5EM8AvetYKlAJyTVSpo0ZUeGbZ3EZiPm9djgSnrLqpFUDjRCg==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.26.1.tgz", + "integrity": "sha512-d6uStdNKi8kjPlHAyO59M6KGWATNwhLCD7dng0NXfwGndc22fthzIk/6j9F6ltQx30huy5qQram6j3JXwNACoA==", "dev": true, "license": "MIT", "peer": true, @@ -1136,9 +1153,9 @@ } }, "node_modules/@tiptap/extension-heading": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.12.0.tgz", - "integrity": "sha512-9DfES4Wd5TX1foI70N9sAL+35NN1UHrtzDYN2+dTHupnmKir9RaMXyZcbkUb4aDVzYrGxIqxJzHBVkquKIlTrw==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.26.1.tgz", + "integrity": "sha512-KSzL8WZV3pjJG9ke4RaU70+B5UlYR2S6olNt5UCAawM+fi11mobVztiBoC19xtpSVqIXC1AmXOqUgnuSvmE4ZA==", "dev": true, "license": "MIT", "peer": true, @@ -1151,9 +1168,9 @@ } }, "node_modules/@tiptap/extension-history": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.12.0.tgz", - "integrity": "sha512-+B9CAf2BFURC6mQiM1OQtahVTzdEOEgT/UUNlRZkeeBc0K5of3dr6UdBqaoaMAefja3jx5PqiQ7mhUBAjSt6AA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.26.1.tgz", + "integrity": "sha512-m6YR1gkkauIDo3PRl0gP+7Oc4n5OqDzcjVh6LvWREmZP8nmi94hfseYbqOXUb6RPHIc0JKF02eiRifT4MSd2nw==", "dev": true, "license": "MIT", "peer": true, @@ -1167,9 +1184,9 @@ } }, "node_modules/@tiptap/extension-horizontal-rule": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.12.0.tgz", - "integrity": "sha512-Vi2+6RIehDSpoJn/7PDuOieUj7W7WrEb4wBxK9TG8PDscihR0mehhhzm/K2xhH4TN48iPJGRsjDFrFjTbXmcnw==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.26.1.tgz", + "integrity": "sha512-mT6baqOhs/NakgrAeDeed194E/ZJFGL692H0C7f1N7WDRaWxUu2oR0LrnRqSH5OyPjELkzu6nQnNy0+0tFGHHg==", "dev": true, "license": "MIT", "peer": true, @@ -1183,9 +1200,9 @@ } }, "node_modules/@tiptap/extension-image": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.11.7.tgz", - "integrity": "sha512-YvCmTDB7Oo+A56tR4S/gcNaYpqU4DDlSQcRp5IQvmQV5EekSe0lnEazGDoqOCwsit9qQhj4MPQJhKrnaWrJUrg==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.26.1.tgz", + "integrity": "sha512-96+MaYBJebQlR/ik5W72GLUfXdEoxFs+6jsoERxbM5qEdhb7TEnodBFtWZOwgDO27kFd6rSNZuW9r5KJNtljEg==", "dev": true, "license": "MIT", "peer": true, @@ -1198,9 +1215,9 @@ } }, "node_modules/@tiptap/extension-italic": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.12.0.tgz", - "integrity": "sha512-JKcXK3LmEsmxNzEq5e06rPUGMRLUxmJ2mYtBY4NlJ6yLM9XMDljtgeTnWT0ySLYmfINSFTkX4S7WIRbpl9l4pw==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.26.1.tgz", + "integrity": "sha512-pOs6oU4LyGO89IrYE4jbE8ZYsPwMMIiKkYfXcfeD9NtpGNBnjeVXXF5I9ndY2ANrCAgC8k58C3/powDRf0T2yA==", "dev": true, "license": "MIT", "peer": true, @@ -1213,9 +1230,9 @@ } }, "node_modules/@tiptap/extension-link": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.11.7.tgz", - "integrity": "sha512-qKIowE73aAUrnQCIifYP34xXOHOsZw46cT/LBDlb0T60knVfQoKVE4ku08fJzAV+s6zqgsaaZ4HVOXkQYLoW7g==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.26.1.tgz", + "integrity": "sha512-7yfum5Jymkue/uOSTQPt2SmkZIdZx7t3QhZLqBU7R9ettkdSCBgEGok6N+scJM1R1Zes+maSckLm0JZw5BKYNA==", "dev": true, "license": "MIT", "peer": true, @@ -1232,9 +1249,9 @@ } }, "node_modules/@tiptap/extension-list-item": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.12.0.tgz", - "integrity": "sha512-4YwZooC8HP+gPxs6YrkB1ayggyYbgVvJx/rWBT6lKSW2MVVg8QXi1zAcSI3MhIhHmqDysXXFPL8JURlbeGjaFA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.26.1.tgz", + "integrity": "sha512-quOXckC73Luc3x+Dcm88YAEBW+Crh3x5uvtQOQtn2GEG91AshrvbnhGRiYnfvEN7UhWIS+FYI5liHFcRKSUKrQ==", "dev": true, "license": "MIT", "peer": true, @@ -1247,9 +1264,9 @@ } }, "node_modules/@tiptap/extension-ordered-list": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.12.0.tgz", - "integrity": "sha512-1ys0e/oqk09oXxrB1WzAx5EntK/QreObG/V1yhgihGm429fxHMsxzIYN6dKAYxx0YOPQG7qEZRrrPuWU70Ms7g==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.26.1.tgz", + "integrity": "sha512-UHKNRxq6TBnXMGFSq91knD6QaHsyyOwLOsXMzupmKM5Su0s+CRXEjfav3qKlbb9e4m7D7S/a0aPm8nC9KIXNhQ==", "dev": true, "license": "MIT", "peer": true, @@ -1262,9 +1279,9 @@ } }, "node_modules/@tiptap/extension-paragraph": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.12.0.tgz", - "integrity": "sha512-QNK5cgewCunWFxpLlbvvoO1rrLgEtNKxiY79fctP9toV+e59R+1i1Q9lXC1O5mOfDgVxCb6uFDMsqmKhFjpPog==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.26.1.tgz", + "integrity": "sha512-UezvM9VDRAVJlX1tykgHWSD1g3MKfVMWWZ+Tg+PE4+kizOwoYkRWznVPgCAxjmyHajxpCKRXgqTZkOxjJ9Kjzg==", "dev": true, "license": "MIT", "peer": true, @@ -1277,9 +1294,9 @@ } }, "node_modules/@tiptap/extension-placeholder": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.11.7.tgz", - "integrity": "sha512-/06zXV4HIjYoiaUq1fVJo/RcU8pHbzx21evOpeG/foCfNpMI4xLU/vnxdUi6/SQqpZMY0eFutDqod1InkSOqsg==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.26.1.tgz", + "integrity": "sha512-MBlqbkd+63btY7Qu+SqrXvWjPwooGZDsLTtl7jp52BczBl61cq9yygglt9XpM11TFMBdySgdLHBrLtQ0B7fBlw==", "dev": true, "license": "MIT", "peer": true, @@ -1293,9 +1310,9 @@ } }, "node_modules/@tiptap/extension-strike": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.12.0.tgz", - "integrity": "sha512-nBaa5YtBsLJPZFfSs36sBz4Zgi/c8b3MsmS/Az8uXaHb0R9yPewOVUMDIQbxMct8SXUlIo9VtKlOL+mVJ3Nkpw==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.26.1.tgz", + "integrity": "sha512-CkoRH+pAi6MgdCh7K0cVZl4N2uR4pZdabXAnFSoLZRSg6imLvEUmWHfSi1dl3Z7JOvd3a4yZ4NxerQn5MWbJ7g==", "dev": true, "license": "MIT", "peer": true, @@ -1308,9 +1325,9 @@ } }, "node_modules/@tiptap/extension-subscript": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-subscript/-/extension-subscript-2.11.7.tgz", - "integrity": "sha512-I25ZexCddFJ9701DCCtQbX3Vtxzj5d9ss2GAXVweIUCdATCScaebsznyUQoN5papmhTxXsw5OD+K2ZHxP82pew==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-subscript/-/extension-subscript-2.26.1.tgz", + "integrity": "sha512-tnXu18nBbTE6PqmkcpoPun5VxElupYacNfl2WkLB/trN3rBJbyDkn0diS8pL0Ku1vPNi2kSfrHq78/PbX0O1iA==", "dev": true, "license": "MIT", "peer": true, @@ -1323,9 +1340,9 @@ } }, "node_modules/@tiptap/extension-superscript": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-superscript/-/extension-superscript-2.11.7.tgz", - "integrity": "sha512-dNRpCcRJs0Qvv0sZRgbH7Y5hDVbWsGSZjtwFCs/mysPrvHqmXjzo7568kYWTggxEYxnXw6n0FfkCAEHlt0N90Q==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-superscript/-/extension-superscript-2.26.1.tgz", + "integrity": "sha512-YTUmppwJchqXxE4nf+wTMuZuUU9/9ibg8p73rif6WxldjuH0RGZQRY8ad5Ha1c5clG+60e0nrXthqqLgvWfjtw==", "dev": true, "license": "MIT", "peer": true, @@ -1338,9 +1355,9 @@ } }, "node_modules/@tiptap/extension-table": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table/-/extension-table-2.11.7.tgz", - "integrity": "sha512-rfwWkNXz/EZuhc8lylsCWPbx0Xr5FlIhreWFyeoXYrDEO3x4ytYcVOpNmbabJYP2semfM0PvPR5o84zfFkLZyg==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table/-/extension-table-2.26.1.tgz", + "integrity": "sha512-LQ63CK53qx2ZsbLTB4mUX0YCoGC0GbYQ82jS3kD+K7M/mb9MCkefvDk6rA8rXF8TjfGnv6o/Fseoot8uhH3qfg==", "dev": true, "license": "MIT", "peer": true, @@ -1354,9 +1371,9 @@ } }, "node_modules/@tiptap/extension-table-cell": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table-cell/-/extension-table-cell-2.11.7.tgz", - "integrity": "sha512-JMOkSYRckc5SJP86yGGiHzCxCR8ecrRENvTWAKib6qer2tutxs5u42W+Z8uTcHC2dRz7Fv54snOkDoqPwkf6cw==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-cell/-/extension-table-cell-2.26.1.tgz", + "integrity": "sha512-0P5zY+WGFnULggJkX6+CevmFoBmVv1aUiBBXfcFuLG2mnUsS3QALQTowFtz/0/VbtbjzcOSStaGDHRJxPbk9XQ==", "dev": true, "license": "MIT", "peer": true, @@ -1369,9 +1386,9 @@ } }, "node_modules/@tiptap/extension-table-header": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table-header/-/extension-table-header-2.11.7.tgz", - "integrity": "sha512-wPRKpliS5QQXgsp//ZjXrHMdLICMkjg2fUrQinOiBa7wDL5C7Y+SehtuK4s2tjeAkyAdj+nepfftyBRIlUSMXg==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-header/-/extension-table-header-2.26.1.tgz", + "integrity": "sha512-SAwTW9H+sjVYjoeU5z8pVDMHn3r3FCi+zp2KAxsEsmujcd7qrQdY0cAjQtWjckCq6H3sQkbICa+xlCCd7C8ZAQ==", "dev": true, "license": "MIT", "peer": true, @@ -1384,9 +1401,9 @@ } }, "node_modules/@tiptap/extension-table-row": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table-row/-/extension-table-row-2.11.7.tgz", - "integrity": "sha512-K254RiXWGXGjz5Cm835hqfQiwnYXm8aw6oOa3isDh4A1B+1Ev4DB2vEDKMrgaOor3nbTsSYmAx2iEMrZSbpaRg==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-row/-/extension-table-row-2.26.1.tgz", + "integrity": "sha512-c4oLrUfj1EVVDpbfKX36v7nnaeI4NxML2KRTQXocvcY65VCe0bPQh8ujpPgPcnKEzdWYdIuAX9RbEAkiYWe8Ww==", "dev": true, "license": "MIT", "peer": true, @@ -1399,9 +1416,9 @@ } }, "node_modules/@tiptap/extension-text": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.12.0.tgz", - "integrity": "sha512-0ytN9V1tZYTXdiYDQg4FB2SQ56JAJC9r/65snefb9ztl+gZzDrIvih7CflHs1ic9PgyjexfMLeH+VzuMccNyZw==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.26.1.tgz", + "integrity": "sha512-p2n8WVMd/2vckdJlol24acaTDIZAhI7qle5cM75bn01sOEZoFlSw6SwINOULrUCzNJsYb43qrLEibZb4j2LeQw==", "dev": true, "license": "MIT", "peer": true, @@ -1414,9 +1431,9 @@ } }, "node_modules/@tiptap/extension-text-align": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text-align/-/extension-text-align-2.11.7.tgz", - "integrity": "sha512-3M8zd9ROADXazVNpgR6Ejs1evSvBveN36qN4GgV71GqrNlTcjqYgQcXFLQrsd2hnE+aXir8/8bLJ+aaJXDninA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-align/-/extension-text-align-2.26.1.tgz", + "integrity": "sha512-x6mpNGELy2QtSPBoQqNgiXO9PjZoB+O2EAfXA9YRiBDSIRNOrw+7vOVpi+IgzswFmhMNgIYUVfQRud4FHUCNew==", "dev": true, "license": "MIT", "peer": true, @@ -1429,9 +1446,9 @@ } }, "node_modules/@tiptap/extension-text-style": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.12.0.tgz", - "integrity": "sha512-Pxwt23ZlvbQUahV0PvHy8Ej6IAuKR1FvHobUvwP3T8AiY7hob66fWRe7tQbESzSAzm5Vv2xkvyHeU8vekMTezA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.26.1.tgz", + "integrity": "sha512-t9Nc/UkrbCfnSHEUi1gvUQ2ZPzvfdYFT5TExoV2DTiUCkhG6+mecT5bTVFGW3QkPmbToL+nFhGn4ZRMDD0SP3Q==", "dev": true, "license": "MIT", "peer": true, @@ -1444,9 +1461,9 @@ } }, "node_modules/@tiptap/extension-underline": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.11.7.tgz", - "integrity": "sha512-NtoQw6PGijOAtXC6G+0Aq0/Z5wwEjPhNHs8nsjXogfWIgaj/aI4/zfBnA06eI3WT+emMYQTl0fTc4CUPnLVU8g==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.26.1.tgz", + "integrity": "sha512-/fufv41WDMdf0a4xmFAxONoAz08TonJXX6NEoSJmuGKO59M/Y0Pz8DTK1g32Wk44kn7dyScDiPlvvndl+UOv0A==", "dev": true, "license": "MIT", "peer": true, @@ -1459,14 +1476,14 @@ } }, "node_modules/@tiptap/pm": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.11.7.tgz", - "integrity": "sha512-7gEEfz2Q6bYKXM07vzLUD0vqXFhC5geWRA6LCozTiLdVFDdHWiBrvb2rtkL5T7mfLq03zc1QhH7rI3F6VntOEA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.26.1.tgz", + "integrity": "sha512-8aF+mY/vSHbGFqyG663ds84b+vca5Lge3tHdTMTKazxCnhXR9dn2oQJMnZ78YZvdRbkPkMJJHti9h3K7u2UQvw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "prosemirror-changeset": "^2.2.1", + "prosemirror-changeset": "^2.3.0", "prosemirror-collab": "^1.3.1", "prosemirror-commands": "^1.6.2", "prosemirror-dropcursor": "^1.8.1", @@ -1491,34 +1508,34 @@ } }, "node_modules/@tiptap/starter-kit": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.11.7.tgz", - "integrity": "sha512-K+q51KwNU/l0kqRuV5e1824yOLVftj6kGplGQLvJG56P7Rb2dPbM/JeaDbxQhnHT/KDGamG0s0Po0M3pPY163A==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.26.1.tgz", + "integrity": "sha512-oziMGCds8SVQ3s5dRpBxVdEKZAmO/O//BjZ69mhA3q4vJdR0rnfLb5fTxSeQvHiqB878HBNn76kNaJrHrV35GA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@tiptap/core": "^2.11.7", - "@tiptap/extension-blockquote": "^2.11.7", - "@tiptap/extension-bold": "^2.11.7", - "@tiptap/extension-bullet-list": "^2.11.7", - "@tiptap/extension-code": "^2.11.7", - "@tiptap/extension-code-block": "^2.11.7", - "@tiptap/extension-document": "^2.11.7", - "@tiptap/extension-dropcursor": "^2.11.7", - "@tiptap/extension-gapcursor": "^2.11.7", - "@tiptap/extension-hard-break": "^2.11.7", - "@tiptap/extension-heading": "^2.11.7", - "@tiptap/extension-history": "^2.11.7", - "@tiptap/extension-horizontal-rule": "^2.11.7", - "@tiptap/extension-italic": "^2.11.7", - "@tiptap/extension-list-item": "^2.11.7", - "@tiptap/extension-ordered-list": "^2.11.7", - "@tiptap/extension-paragraph": "^2.11.7", - "@tiptap/extension-strike": "^2.11.7", - "@tiptap/extension-text": "^2.11.7", - "@tiptap/extension-text-style": "^2.11.7", - "@tiptap/pm": "^2.11.7" + "@tiptap/core": "^2.26.1", + "@tiptap/extension-blockquote": "^2.26.1", + "@tiptap/extension-bold": "^2.26.1", + "@tiptap/extension-bullet-list": "^2.26.1", + "@tiptap/extension-code": "^2.26.1", + "@tiptap/extension-code-block": "^2.26.1", + "@tiptap/extension-document": "^2.26.1", + "@tiptap/extension-dropcursor": "^2.26.1", + "@tiptap/extension-gapcursor": "^2.26.1", + "@tiptap/extension-hard-break": "^2.26.1", + "@tiptap/extension-heading": "^2.26.1", + "@tiptap/extension-history": "^2.26.1", + "@tiptap/extension-horizontal-rule": "^2.26.1", + "@tiptap/extension-italic": "^2.26.1", + "@tiptap/extension-list-item": "^2.26.1", + "@tiptap/extension-ordered-list": "^2.26.1", + "@tiptap/extension-paragraph": "^2.26.1", + "@tiptap/extension-strike": "^2.26.1", + "@tiptap/extension-text": "^2.26.1", + "@tiptap/extension-text-style": "^2.26.1", + "@tiptap/pm": "^2.26.1" }, "funding": { "type": "github", @@ -1605,9 +1622,9 @@ "peer": true }, "node_modules/@umbraco-cms/backoffice": { - "version": "16.0.0-rc4", - "resolved": "https://registry.npmjs.org/@umbraco-cms/backoffice/-/backoffice-16.0.0-rc4.tgz", - "integrity": "sha512-qR9xkbgJjZzb8kI4p8W3xbfYVl4cHmoKde/83LBzdh3loaxjQ0VjbdU+FZfPbfAsp/KNdY7b6UP8ME+n+Be2TA==", + "version": "16.2.0-rc", + "resolved": "https://registry.npmjs.org/@umbraco-cms/backoffice/-/backoffice-16.2.0-rc.tgz", + "integrity": "sha512-DAimNYu3ZGy1my0BikVXW0iKxH6nmkUTCA2Lw1wjhHG93T8+KCyHCJSxpXBdLdxmgUdKjp6lWjlqKsZ3wQ6/gQ==", "dev": true, "license": "MIT", "engines": { @@ -1615,24 +1632,26 @@ "npm": ">=10.9" }, "peerDependencies": { - "@tiptap/core": "2.11.7", - "@tiptap/extension-character-count": "2.11.7", - "@tiptap/extension-image": "2.11.7", - "@tiptap/extension-link": "2.11.7", - "@tiptap/extension-placeholder": "2.11.7", - "@tiptap/extension-subscript": "2.11.7", - "@tiptap/extension-superscript": "2.11.7", - "@tiptap/extension-table": "2.11.7", - "@tiptap/extension-table-cell": "2.11.7", - "@tiptap/extension-table-header": "2.11.7", - "@tiptap/extension-table-row": "2.11.7", - "@tiptap/extension-text-align": "2.11.7", - "@tiptap/extension-underline": "2.11.7", - "@tiptap/pm": "2.11.7", - "@tiptap/starter-kit": "2.11.7", + "@heximal/expressions": "^0.1.5", + "@hey-api/client-fetch": "^0.12.0", + "@tiptap/core": "2.26.1", + "@tiptap/extension-character-count": "2.26.1", + "@tiptap/extension-image": "2.26.1", + "@tiptap/extension-link": "2.26.1", + "@tiptap/extension-placeholder": "2.26.1", + "@tiptap/extension-subscript": "2.26.1", + "@tiptap/extension-superscript": "2.26.1", + "@tiptap/extension-table": "2.26.1", + "@tiptap/extension-table-cell": "2.26.1", + "@tiptap/extension-table-header": "2.26.1", + "@tiptap/extension-table-row": "2.26.1", + "@tiptap/extension-text-align": "2.26.1", + "@tiptap/extension-underline": "2.26.1", + "@tiptap/pm": "2.26.1", + "@tiptap/starter-kit": "2.26.1", "@types/diff": "^7.0.2", - "@umbraco-ui/uui": "1.14.0-rc.3", - "@umbraco-ui/uui-css": "1.14.0-rc.2", + "@umbraco-ui/uui": "^1.15.0-rc.0", + "@umbraco-ui/uui-css": "^1.15.0-rc.0", "diff": "^7.0.0", "dompurify": "^3.2.5", "element-internals-polyfill": "^3.0.2", @@ -1644,148 +1663,148 @@ } }, "node_modules/@umbraco-ui/uui": { - "version": "1.14.0-rc.3", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.14.0-rc.3.tgz", - "integrity": "sha512-4uSpbJ72qOUMv3wel1c5ALWwC2Tgr/tARU2YwkulBP8v8HBD2OsaFWHl55Pkqu+63kGBw5BlVk5WTbq4DuHhOw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.15.0.tgz", + "integrity": "sha512-8yCzfKePv9zK+PMw1K3uwpnDDBZkbSCCOrt8dNDlZ1/6zf+yNLu+r/kVlMcauei6aNsCwXvcI4LhBGS1f5kJ/A==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-action-bar": "1.14.0-rc.1", - "@umbraco-ui/uui-avatar": "1.14.0-rc.1", - "@umbraco-ui/uui-avatar-group": "1.14.0-rc.1", - "@umbraco-ui/uui-badge": "1.14.0-rc.1", - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-boolean-input": "1.14.0-rc.1", - "@umbraco-ui/uui-box": "1.14.0-rc.2", - "@umbraco-ui/uui-breadcrumbs": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1", - "@umbraco-ui/uui-button-copy-text": "1.14.0-rc.1", - "@umbraco-ui/uui-button-group": "1.14.0-rc.1", - "@umbraco-ui/uui-button-inline-create": "1.14.0-rc.1", - "@umbraco-ui/uui-card": "1.14.0-rc.1", - "@umbraco-ui/uui-card-block-type": "1.14.0-rc.1", - "@umbraco-ui/uui-card-content-node": "1.14.0-rc.1", - "@umbraco-ui/uui-card-media": "1.14.0-rc.1", - "@umbraco-ui/uui-card-user": "1.14.0-rc.1", - "@umbraco-ui/uui-caret": "1.14.0-rc.1", - "@umbraco-ui/uui-checkbox": "1.14.0-rc.1", - "@umbraco-ui/uui-color-area": "1.14.0-rc.1", - "@umbraco-ui/uui-color-picker": "1.14.0-rc.1", - "@umbraco-ui/uui-color-slider": "1.14.0-rc.1", - "@umbraco-ui/uui-color-swatch": "1.14.0-rc.1", - "@umbraco-ui/uui-color-swatches": "1.14.0-rc.1", - "@umbraco-ui/uui-combobox": "1.14.0-rc.1", - "@umbraco-ui/uui-combobox-list": "1.14.0-rc.1", - "@umbraco-ui/uui-css": "1.14.0-rc.2", - "@umbraco-ui/uui-dialog": "1.14.0-rc.2", - "@umbraco-ui/uui-dialog-layout": "1.14.0-rc.1", - "@umbraco-ui/uui-file-dropzone": "1.14.0-rc.1", - "@umbraco-ui/uui-file-preview": "1.14.0-rc.1", - "@umbraco-ui/uui-form": "1.14.0-rc.1", - "@umbraco-ui/uui-form-layout-item": "1.14.0-rc.1", - "@umbraco-ui/uui-form-validation-message": "1.14.0-rc.1", - "@umbraco-ui/uui-icon": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry-essential": "1.14.0-rc.1", - "@umbraco-ui/uui-input": "1.14.0-rc.3", - "@umbraco-ui/uui-input-file": "1.14.0-rc.1", - "@umbraco-ui/uui-input-lock": "1.14.0-rc.3", - "@umbraco-ui/uui-input-password": "1.14.0-rc.3", - "@umbraco-ui/uui-keyboard-shortcut": "1.14.0-rc.1", - "@umbraco-ui/uui-label": "1.14.0-rc.1", - "@umbraco-ui/uui-loader": "1.14.0-rc.1", - "@umbraco-ui/uui-loader-bar": "1.14.0-rc.1", - "@umbraco-ui/uui-loader-circle": "1.14.0-rc.1", - "@umbraco-ui/uui-menu-item": "1.14.0-rc.1", - "@umbraco-ui/uui-modal": "1.14.0-rc.1", - "@umbraco-ui/uui-pagination": "1.14.0-rc.1", - "@umbraco-ui/uui-popover": "1.14.0-rc.1", - "@umbraco-ui/uui-popover-container": "1.14.0-rc.1", - "@umbraco-ui/uui-progress-bar": "1.14.0-rc.1", - "@umbraco-ui/uui-radio": "1.14.0-rc.1", - "@umbraco-ui/uui-range-slider": "1.14.0-rc.1", - "@umbraco-ui/uui-ref": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-list": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node-data-type": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node-document-type": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node-form": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node-member": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node-package": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node-user": "1.14.0-rc.1", - "@umbraco-ui/uui-scroll-container": "1.14.0-rc.1", - "@umbraco-ui/uui-select": "1.14.0-rc.1", - "@umbraco-ui/uui-slider": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-expand": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-file": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-file-dropzone": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-folder": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-lock": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-more": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-sort": "1.14.0-rc.1", - "@umbraco-ui/uui-table": "1.14.0-rc.1", - "@umbraco-ui/uui-tabs": "1.14.0-rc.1", - "@umbraco-ui/uui-tag": "1.14.0-rc.1", - "@umbraco-ui/uui-textarea": "1.14.0-rc.1", - "@umbraco-ui/uui-toast-notification": "1.14.0-rc.2", - "@umbraco-ui/uui-toast-notification-container": "1.14.0-rc.2", - "@umbraco-ui/uui-toast-notification-layout": "1.14.0-rc.2", - "@umbraco-ui/uui-toggle": "1.14.0-rc.1", - "@umbraco-ui/uui-visually-hidden": "1.14.0-rc.1" + "@umbraco-ui/uui-action-bar": "1.15.0", + "@umbraco-ui/uui-avatar": "1.15.0", + "@umbraco-ui/uui-avatar-group": "1.15.0", + "@umbraco-ui/uui-badge": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-boolean-input": "1.15.0", + "@umbraco-ui/uui-box": "1.15.0", + "@umbraco-ui/uui-breadcrumbs": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-button-copy-text": "1.15.0", + "@umbraco-ui/uui-button-group": "1.15.0", + "@umbraco-ui/uui-button-inline-create": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0", + "@umbraco-ui/uui-card-block-type": "1.15.0", + "@umbraco-ui/uui-card-content-node": "1.15.0", + "@umbraco-ui/uui-card-media": "1.15.0", + "@umbraco-ui/uui-card-user": "1.15.0", + "@umbraco-ui/uui-caret": "1.15.0", + "@umbraco-ui/uui-checkbox": "1.15.0", + "@umbraco-ui/uui-color-area": "1.15.0", + "@umbraco-ui/uui-color-picker": "1.15.0", + "@umbraco-ui/uui-color-slider": "1.15.0", + "@umbraco-ui/uui-color-swatch": "1.15.0", + "@umbraco-ui/uui-color-swatches": "1.15.0", + "@umbraco-ui/uui-combobox": "1.15.0", + "@umbraco-ui/uui-combobox-list": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0", + "@umbraco-ui/uui-dialog": "1.15.0", + "@umbraco-ui/uui-dialog-layout": "1.15.0", + "@umbraco-ui/uui-file-dropzone": "1.15.0", + "@umbraco-ui/uui-file-preview": "1.15.0", + "@umbraco-ui/uui-form": "1.15.0", + "@umbraco-ui/uui-form-layout-item": "1.15.0", + "@umbraco-ui/uui-form-validation-message": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-icon-registry": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0", + "@umbraco-ui/uui-input": "1.15.0", + "@umbraco-ui/uui-input-file": "1.15.0", + "@umbraco-ui/uui-input-lock": "1.15.0", + "@umbraco-ui/uui-input-password": "1.15.0", + "@umbraco-ui/uui-keyboard-shortcut": "1.15.0", + "@umbraco-ui/uui-label": "1.15.0", + "@umbraco-ui/uui-loader": "1.15.0", + "@umbraco-ui/uui-loader-bar": "1.15.0", + "@umbraco-ui/uui-loader-circle": "1.15.0", + "@umbraco-ui/uui-menu-item": "1.15.0", + "@umbraco-ui/uui-modal": "1.15.0", + "@umbraco-ui/uui-pagination": "1.15.0", + "@umbraco-ui/uui-popover": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", + "@umbraco-ui/uui-progress-bar": "1.15.0", + "@umbraco-ui/uui-radio": "1.15.0", + "@umbraco-ui/uui-range-slider": "1.15.0", + "@umbraco-ui/uui-ref": "1.15.0", + "@umbraco-ui/uui-ref-list": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0", + "@umbraco-ui/uui-ref-node-data-type": "1.15.0", + "@umbraco-ui/uui-ref-node-document-type": "1.15.0", + "@umbraco-ui/uui-ref-node-form": "1.15.0", + "@umbraco-ui/uui-ref-node-member": "1.15.0", + "@umbraco-ui/uui-ref-node-package": "1.15.0", + "@umbraco-ui/uui-ref-node-user": "1.15.0", + "@umbraco-ui/uui-scroll-container": "1.15.0", + "@umbraco-ui/uui-select": "1.15.0", + "@umbraco-ui/uui-slider": "1.15.0", + "@umbraco-ui/uui-symbol-expand": "1.15.0", + "@umbraco-ui/uui-symbol-file": "1.15.0", + "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0", + "@umbraco-ui/uui-symbol-folder": "1.15.0", + "@umbraco-ui/uui-symbol-lock": "1.15.0", + "@umbraco-ui/uui-symbol-more": "1.15.0", + "@umbraco-ui/uui-symbol-sort": "1.15.0", + "@umbraco-ui/uui-table": "1.15.0", + "@umbraco-ui/uui-tabs": "1.15.0", + "@umbraco-ui/uui-tag": "1.15.0", + "@umbraco-ui/uui-textarea": "1.15.0", + "@umbraco-ui/uui-toast-notification": "1.15.0", + "@umbraco-ui/uui-toast-notification-container": "1.15.0", + "@umbraco-ui/uui-toast-notification-layout": "1.15.0", + "@umbraco-ui/uui-toggle": "1.15.0", + "@umbraco-ui/uui-visually-hidden": "1.15.0" } }, "node_modules/@umbraco-ui/uui-action-bar": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.14.0-rc.1.tgz", - "integrity": "sha512-kgA6W28xL4RVoMj9pZjB5PmVXtPxg60rvgpR1Nz3gqPKFSv6SqdyXGwOg/SrnFKg7TtIgQqZ6uU0+xisoaMMUg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.15.0.tgz", + "integrity": "sha512-O0807+bWVWV/rsFihFVKSOkg9wBtLXKCszE5+eZk2KmONm93BFhIAE35rp7eD6X2SuJMHwYzInIxMIMjHzdpUQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button-group": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button-group": "1.15.0" } }, "node_modules/@umbraco-ui/uui-avatar": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.14.0-rc.1.tgz", - "integrity": "sha512-JrkkkhEuaAA5BWZbPSTVSBXAGRZEp/2fAzmlZf7iVZexovM0ET3u7dxWbHN/ERU5hryPKW6Ibaa5u63Wr7kAtA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.15.0.tgz", + "integrity": "sha512-eEX83zwRN3tCiHScKcmkROWAfLu3TgFI9SntlbyxiuSSYfhJxWSZXOf6lVvQ/1CyvKq8XqSbBnN3VKXgcaKOpg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-avatar-group": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.14.0-rc.1.tgz", - "integrity": "sha512-fe9OWBkjJZQFztE1I+QYZUgJ+vCKBcLl02oNY6oTZxT/PG/alzVOVtfpjox4deTTFo9nGSLSGm9FgSkC5zLkTQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.15.0.tgz", + "integrity": "sha512-CGYAFAHgNoQK2UTupP7pO0mwP6t9/Ms6WZ0gIC40a+kPjrGtaDWU52hiPsuXrUcR6WjJwZ5WRrJHOboRpdmM0g==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-avatar": "1.14.0-rc.1", - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-avatar": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-badge": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.14.0-rc.1.tgz", - "integrity": "sha512-FwejfZ5ejTohVk4sNyDeArKBcVyPb3j+4IQGRinR5KFBTMZqCJvig16b60cxxqinyeRkAMfQ+dHhj1WqsnNf7Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.15.0.tgz", + "integrity": "sha512-9aGmhRvey98kcR7wfsnno0BNftIRwJ0r2lCH6cNK2lhe69enYm0MWjp+4uutnlEWWskTLEI344BOqmqOHH1NPA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-base": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.14.0-rc.1.tgz", - "integrity": "sha512-pOI3Nu/QtYxJinJ+8DlmPD7F16+qaFV0UrxxaJZQdecxp2Yg1ri3rHh093ubV+0rIuZ9b5xXsAtbSJqL3tadvw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.15.0.tgz", + "integrity": "sha512-0vtKmjzUOn/tIUHNrsx7aZpy3eq9aRKqV9kkJTrhH92S4WcMy+cOB1iw9t3Fe3xlBPuL3JpszwuxMTIuIqJTgQ==", "dev": true, "license": "MIT", "peer": true, @@ -1794,265 +1813,266 @@ } }, "node_modules/@umbraco-ui/uui-boolean-input": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.14.0-rc.1.tgz", - "integrity": "sha512-SNrxTsvUGEfm+5ZDKDUsYuaUoHj7MnNP3yp5t6FcCUFDpd4XRryScI7eQf8VVCFkduXmnUnzU9IvkZeHLNiKSg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.15.0.tgz", + "integrity": "sha512-LkYX+p44mFVdvlZSliP5ClMcyHoOIVLWI3WVkaMLQdNi2LO9bbfaTneLzu4ruW6v0iF+kLsznr3bl73VHk7oEg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-box": { - "version": "1.14.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.14.0-rc.2.tgz", - "integrity": "sha512-I816yT+hbkpDNzRmRW8j9S3MDNtn3pVIb38mUgd72fw6VZX3mZRc+2RFCqUVlPl9dRg14gF2e27ni2MPYRQoYQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.15.0.tgz", + "integrity": "sha512-MhSNcKsVNymD/yt3NFXujuaQmAqMqj5S+CBoDHEk88H7Id9NMw9RStZFJ37mI2CxHWkeHDotNVgOhSBiHJNJnw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-css": "1.14.0-rc.2" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0" } }, "node_modules/@umbraco-ui/uui-breadcrumbs": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.14.0-rc.1.tgz", - "integrity": "sha512-mFMVxVBmqN44exBwL6eZ3HutKzE3qoSBTH6HUnDD83/94q4oNSgF1czEviExATQHLPzKOqejet62FACRjryf9g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.15.0.tgz", + "integrity": "sha512-TaUY+hNB0VIwv9SBi9fDjIFRtrmmkcT7hlhLCJLUVfQ7jJlGLPISAAdypSplNeCPthYvP1cJQ9m28OzscXHZxQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.14.0-rc.1.tgz", - "integrity": "sha512-4MKFpsXLw7TOTNGyqxKmCkoW8UUQZ78cDSaWkhELAsAmPGg7njLXsNvToNjc3qp0hxo9Ut5uGN6dAIZGRHfLKg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.15.0.tgz", + "integrity": "sha512-3Oaqj6Yta/Q/Ndme20YA1XbHdBBL71iNhpqREfTHli2YV4TEcgIiNy0s2op2oPhKjIEQPEfitU2BrruYEEWa7Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry-essential": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button-copy-text": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-copy-text/-/uui-button-copy-text-1.14.0-rc.1.tgz", - "integrity": "sha512-cHuOgMMgSMQSqeYBMZ0W1OIrsTpTieg9KiQCqkidMWISxVVf3XLqp4gP0w8MYF3ljl6/IWX5sZJs/Bg+0RSf4g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-copy-text/-/uui-button-copy-text-1.15.0.tgz", + "integrity": "sha512-MAaJzpwVnlyGJNvLv6qIwrYsI5SaXXiVKgVi47I8+x//QmnArmetCN04766gGzmAb0m2uuC3ht0BXMDv05pxvw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button-group": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.14.0-rc.1.tgz", - "integrity": "sha512-0Yirkr948H+zL44Vyc6y/Ts0v/02anxaaedKu6G41uCDVjl9CBx/y/cZ7+BLIa5i+uNetiGWMfQbDIqrK61PPw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.15.0.tgz", + "integrity": "sha512-YPEnubKNbKmw04eWRH24/3Uxu+zhtLPeJoaT6ykPCyjr/EKc82rSTvn8fwQuP41UokQrXOac2pKn7SncyoST1Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button-inline-create": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.14.0-rc.1.tgz", - "integrity": "sha512-36A/hzbipSR92bUpcLeEs78uralNt8OHDmpywiu0xTyRYjopUoo07R0mfJ9kUyRIWhcO3MidxgZ11X48xCh+Rg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.15.0.tgz", + "integrity": "sha512-nLJZ6P5eK1rYgqjP5zCxbZp8g4WJ23RnUZQ49o7QpU/7zoPOK72/fuM3Ky00Iapixm/kAD6dYHO/P+GtNz8/CA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.14.0-rc.1.tgz", - "integrity": "sha512-U9egiHuD3djkZyqkzzGhBL2TwxWJCzBAu+zxdBljpAH/0OSeooUiW2JEQmZF0B4zUgYNZJBU+Bgb10FhOgNF6w==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.15.0.tgz", + "integrity": "sha512-pNjpk2iIdSsmTtDdBsWaEr8JX0RcWbl8yKGaqLvo/S7d3bly5z+FjcsgGnX1i1GHo7dqmgVJfbdvN9V1jgn+FA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-checkbox": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-block-type": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-block-type/-/uui-card-block-type-1.14.0-rc.1.tgz", - "integrity": "sha512-1ebp+44VXm2Ob+iewd3JFsNn0jSyiBhaNmxfumq/B9M+TPBiupbLLSddR0CGNn3rk81IatgZwwW0H1yWfyHQ8Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-block-type/-/uui-card-block-type-1.15.0.tgz", + "integrity": "sha512-cWag+D0XrogYZesAN8NMPQCCuU7L7uZ4Xz8dmirKQk1gjMrFDC4vYPZRQ/5O3ETTFupfDipVKimgRDsmarbLSQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-card": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-content-node": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.14.0-rc.1.tgz", - "integrity": "sha512-d/DSllcF+ZO/17SZyq8I7hk8lC+yad8tKEHpveJEgO4EG86wljCS2mdmDUgu6x1yvidViqe/AbgRA7MzvdpSeQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.15.0.tgz", + "integrity": "sha512-DZ6JYNvGb5wVkhhLShENMm+Y6kTpz37YrApQTJVUUgPXhIABO2CDCnqgpH5tkQX73s9jjVB3Ca7SeivuYv8G9A==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-card": "1.14.0-rc.1", - "@umbraco-ui/uui-icon": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-media": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.14.0-rc.1.tgz", - "integrity": "sha512-XKDaXoLxEkeM50ExKmUejO0x3OWWiyQNtEZ23hvGC8iY8l9WUk9YZRlWqir8UlcZNQZpEnLuqSgxn/rBoXHZdQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.15.0.tgz", + "integrity": "sha512-EzYebWCzR0wHY902NmAcTRSVSscYac3QntCz+xwSulrhzfy4copeOd1qE+Lz7FjHs+ho0IBPZol8sF4W6rK8FQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-card": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-file": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-folder": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0", + "@umbraco-ui/uui-symbol-file": "1.15.0", + "@umbraco-ui/uui-symbol-folder": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-user": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.14.0-rc.1.tgz", - "integrity": "sha512-ONOpCMz3yZtZcyZYHUI0UpKJNDxISTzCV1lFzhjdBhmYdZ70Dmnl6/w6DZhpPg+s0z7SZvcck38XZ/UaBTCMnQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.15.0.tgz", + "integrity": "sha512-oo7gCs3RGJ4ujFs+LpG9I1DS/XSNkz9gaqvp4BkaR0kBXzw5f2SLLGhA9S3M6M+OPlsXuuJNKlTV1tn2+LF6Ng==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-avatar": "1.14.0-rc.1", - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-card": "1.14.0-rc.1" + "@umbraco-ui/uui-avatar": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0" } }, "node_modules/@umbraco-ui/uui-caret": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.14.0-rc.1.tgz", - "integrity": "sha512-P8jAhm98B+bgIyMok/ZHFHtFVDuICgJ+Vn/yyKfX3g1yXBqdgmVS/LJyxbvldZLekgOczQDiY+KrjiQ8Y72pUQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.15.0.tgz", + "integrity": "sha512-cnKP5GeaI028hGabVCki1kPqAVSekFeP7QEwu7lncA+dcX8uvg+ffV6kW9FV0emOhI5Tmxvh8o+UDKlLs28q3A==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-checkbox": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.14.0-rc.1.tgz", - "integrity": "sha512-DBjiZtNGJwWPG9VP/7SkWyNiUts6cTR16DCQAeaRtoX+LAz/2jYDA41hQGFW3aHds27BkGtFL5XjkR/1cNRGcg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.15.0.tgz", + "integrity": "sha512-vPkgrFAPDMvJdJTADIWNj48D8gJWD3dBotucUghg/wHhvJv8h/2MvnwMUNnnSB1REHbanl7hJBVvKcNkoil0gA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-boolean-input": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry-essential": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-boolean-input": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-color-area": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.14.0-rc.1.tgz", - "integrity": "sha512-HQ6IsRxQo2bNzEPbiHlOd9/cYP1uEug6wM6zGgz+80H7mkikl1gDboKEAZolksbsgMzkkBBNFNxKyUdtJjUVJw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.15.0.tgz", + "integrity": "sha512-k6u//b+s6UYmzKYMizIf2MRGD4kFy1qWdSk1GnIeDdiQxABJuBZEtkACIe66j+lxnonFvZ/assbLbhRiu15ZCw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", + "@umbraco-ui/uui-base": "1.15.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-picker": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.14.0-rc.1.tgz", - "integrity": "sha512-8GyAg0WAm4L7tiPB8Q9dEIeNwzPSf5SOgc8aAEoNnecJnlBdIj6iIFomV63Nosw3gVEXo8Hg/UuU8xw/BnsLjw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.15.0.tgz", + "integrity": "sha512-I4KGyzZZazjeifcavHp7qnMbP0Jh0dM+gzZhV+YtdPR2JT0o7y6stkbY0f+dOln0K6Bu6BQLV0HLHl/1f/1NDg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-popover-container": "1.14.0-rc.1", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-slider": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.14.0-rc.1.tgz", - "integrity": "sha512-sJm3Bw2XgC/rP+/I7a/WI+5/x6YBqMhLauCjV9WscaltsEQNQnSqQAkt1NJWGiv/H8mRH4IvmRvo+HFUQDtaPQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.15.0.tgz", + "integrity": "sha512-lpT9kapypGkTelG9COSk169VKs0MSiKweX8menDDn0p6I4RfKQBy0N27HecCcf1RqPsCnTbP3lPr5DJy00KdzA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-color-swatch": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.14.0-rc.1.tgz", - "integrity": "sha512-IKgEJ/Qo0MmBJDG8/3Izkxf/WVGVq9enNkyI0W3QLrKZeoIA93fNfHKcZxM94ojoW/5JOtzfkeurS5MpzrlC1Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.15.0.tgz", + "integrity": "sha512-1AI0QMr046fKc8xZ4aBO7FDwvggsS9plIpY0W4AGrqQxqGUR2u/mTU49+8xMtboaFOen5RQpJ65DN9hAgeNZ+w==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry-essential": "1.14.0-rc.1", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-swatches": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.14.0-rc.1.tgz", - "integrity": "sha512-NHRsgivUhyBnQKPjwDJkwZ2LCexNUH53a2/nbta58190qnYEvViiqiLx8AbyHUz6s294X2k3DgH6OG5GcaVxng==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.15.0.tgz", + "integrity": "sha512-UzlgWdsVHyCM/znFThrfA4A/S/K/R9Nc2KyRYiyy2xgBoP7x2vJ5Rn4mnR02W4bhI3gNgCJ2fqhmyiW4dxyk0Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-color-swatch": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-color-swatch": "1.15.0" } }, "node_modules/@umbraco-ui/uui-combobox": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.14.0-rc.1.tgz", - "integrity": "sha512-foggvau6rHfhm8zO4DaDJWT/Htbrlfrz6cs9idYQAAt8KKnmRfg4GLiGkDvt62IZl9/LBT2zKOKCa/D/dwVPwg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.15.0.tgz", + "integrity": "sha512-CKslvVRCKCReMr/ZZh4wc3TKJNvFjKVm/hSIvFqCIoJuSKfC4XuLU9SK9FL1s42NUAUmccSD3hATZJZ9VXqY+Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1", - "@umbraco-ui/uui-combobox-list": "1.14.0-rc.1", - "@umbraco-ui/uui-icon": "1.14.0-rc.1", - "@umbraco-ui/uui-popover-container": "1.14.0-rc.1", - "@umbraco-ui/uui-scroll-container": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-expand": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-combobox-list": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", + "@umbraco-ui/uui-scroll-container": "1.15.0", + "@umbraco-ui/uui-symbol-expand": "1.15.0" } }, "node_modules/@umbraco-ui/uui-combobox-list": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.14.0-rc.1.tgz", - "integrity": "sha512-WEJIPN9bm7vFdBbiqKUPaEQmJvcXj161T3AvQjW61cFsSq4Y+kTgTJx9IM2LYKWsXZCyy20yVJ2FW7ipv2K0Ag==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.15.0.tgz", + "integrity": "sha512-e8IhqU9AC5pOqXuzPzI+BDsW97Ac0u1GU/5MIJqRcBZ+ZttPcH4fsm4u8siCHbK1khCG0Vzo7HiKPZ0IuuOslg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-css": { - "version": "1.14.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.14.0-rc.2.tgz", - "integrity": "sha512-WnxD2XUGPykJ1uHKVIyZoVa6jlJBYciEmax6xy1sZlahDMIb0C8KgQ3GnocFPKIO5q+e/+zcMsaD5Iu3/4GB4g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.15.0.tgz", + "integrity": "sha512-0FPJ/NHE8MSJ7vvdFp4cSWT5L73KS00bUHPyA6oiF/XnE0AfS9TzkSWObdSrU6kyPr/fybVwsycDZNBfPiyrCA==", "dev": true, "license": "MIT", "peer": true, @@ -2061,659 +2081,659 @@ } }, "node_modules/@umbraco-ui/uui-dialog": { - "version": "1.14.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.14.0-rc.2.tgz", - "integrity": "sha512-qN3OypIfUfBb9Kwj5ZU+QdOwOvv5vjoOrfey7v6adl8hv78NsDMcH1ez5E2l9HcqZ69S5a5e00RAKQxtI0ftzQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.15.0.tgz", + "integrity": "sha512-iVsrVVnvBrCCT9uJhyBE7b1kXwWUUKDmimhs/TyF1SFjxWP/U0Z99QqqI1pawdad+BuK3oVCmxYOdaReWDQXkQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-css": "1.14.0-rc.2" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0" } }, "node_modules/@umbraco-ui/uui-dialog-layout": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.14.0-rc.1.tgz", - "integrity": "sha512-a22uNk4cpPg+WEzoHfQo1+TCHGPukZUhFpyDVvL4D+0hBSHAkhAHsv/SIxSbibshgrvFtD+l4SdKZvxeYVxWUA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.15.0.tgz", + "integrity": "sha512-JdDRIzSGGDnvVqXSIhc+5rDXMdYMO+Hd7s2hqLp+iRSn8IHISN/qT1nfFVO9LMbLdcApanl3JJ4Rru9LN4Q3HA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-file-dropzone": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.14.0-rc.1.tgz", - "integrity": "sha512-8YWpp/3Jbt7a+uDtIuAYQcJjlz6vxYQK4x5CtJ8Tod6Y9NR2bfTGM12BWz9Uhze5SnuYpR8iPsJrfkyTVQ3opQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.15.0.tgz", + "integrity": "sha512-MhJRkVdDQWKEBvemNRD4bZCuIS0JUll1nNoPK7scA+e6vDmbv25vqPHNXGE/sIpVkChY/L+v+twokzlHn57XMw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-file-dropzone": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0" } }, "node_modules/@umbraco-ui/uui-file-preview": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.14.0-rc.1.tgz", - "integrity": "sha512-T3aRndX7bUxqxvcbJhSbR99S2VZMI0aqiSXeItkDtZ4dD3wGagvklelPG5ff+CB0UWU7NJGjO6CU1GIpXCaiaQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.15.0.tgz", + "integrity": "sha512-AHKIdYLC0ga4Wgr68xtW/gG3NDqn+QhD2aus0l2n4lBoq6OAQ5aZiPwD9i1fCD7dgyjKQ6Ov9PJSaqRYQkOlNA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-file": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-folder": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-symbol-file": "1.15.0", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0", + "@umbraco-ui/uui-symbol-folder": "1.15.0" } }, "node_modules/@umbraco-ui/uui-form": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.14.0-rc.1.tgz", - "integrity": "sha512-vX1A0dWS5sA8H96DXnZ5NipkNRLKKvDn5mT2cWKdWV6ZuzrkTr6FOXIsuHDdXHdWCBWcGbnp5LHZQV0G7uwT2A==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.15.0.tgz", + "integrity": "sha512-4u9ZryfVBunpb0IL0+TevytrISA6S1+AajiK/PUk0JMJfqMuQMjmpnNPdtYRNVgFFIcQFQKipjT/mrHbDVawxw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-form-layout-item": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.14.0-rc.1.tgz", - "integrity": "sha512-qdakkGDP6c4zg0PatTrAK2sAPpLXaUFyPf7YG7ZLgU9VaKKqbubfF2qjz4R7bwcsKtkqBIBEgZOZgnFmqhHErA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.15.0.tgz", + "integrity": "sha512-fiWGeQpREnl6k+6VNHz9ixNdEmOoFNm7qsgdIYJ1jCDXBGME1mjxJOr2Eq7UWJuzQM8BeyQEcXq5SVIOv21PRw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-form-validation-message": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-form-validation-message": "1.15.0" } }, "node_modules/@umbraco-ui/uui-form-validation-message": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.14.0-rc.1.tgz", - "integrity": "sha512-qCcLn7F0n53HMFe47NDaGo99l84H2fQoJy5pTYKTT97WIWYfr8ZFwBhRh1NfJ2hSHYqnIb45/LJNH8IBXRCjtQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.15.0.tgz", + "integrity": "sha512-RYfwmjPkY0KumjaalLW8gkasW25Mj87YFAzJn7mAYiZigURape9RqGpvrBfwcMmGj3W2/uVuHxpAHrvweQOt4A==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-icon": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.14.0-rc.1.tgz", - "integrity": "sha512-gDObIbvGfv4ROoHqwj9Tc+dVHgDjGXQ5TxDF94ecL/ZqRR5wYT3Ug1jGzGsRc6yMpo/+GyA4fEpuvFcjOOr67Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.15.0.tgz", + "integrity": "sha512-e8/W6gu6kwrodH0f0U70LR5rHQhiZGq3NqLqikAQ1rvmwitXUqtkVXIhkGxSf7M6yPhpmoi2qEEZDQH9cvCE5A==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-icon-registry": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.14.0-rc.1.tgz", - "integrity": "sha512-NudOm3N+ESxsyV/TxbvMlhoxDfm7gdnD/mVrS8w/aITGQuxtfxIUu2eTtLua9l0vDYZ9qtcBgR6Qp9yKFFu+Ag==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.15.0.tgz", + "integrity": "sha512-nIdzCqoABeRVG6jW045ok649MiAhm5zPdfuMKc1a+TNw9xkKj+vnA1YcjaBN502+AekMhhwnqgj9mLL+mC2VPQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-icon": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0" } }, "node_modules/@umbraco-ui/uui-icon-registry-essential": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.14.0-rc.1.tgz", - "integrity": "sha512-GGocutOSKx0F1eoAud9DIiR2tfVGyjAzBdczQwE4BPE1R44l7IzKz5by7bHp+d4FmyLkNusaYmXAjBM0BxIV7w==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.15.0.tgz", + "integrity": "sha512-llHFVMlV3Uyg2fHiNt1qfDgRhLthD37uQD2FzlQb0GEYjp+4dE8Jyc/eZW2mqABPweUJACVwbrwBUVrCeQJ1OQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input": { - "version": "1.14.0-rc.3", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.14.0-rc.3.tgz", - "integrity": "sha512-mnyzgObVWdlitx+8aS4N84ji95Uekd9WhvesOb+bj5Vf5Q7Z8NLgozf8oNcxDa1gg3gFBtV4rwbiWgr2aaKp6Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.15.0.tgz", + "integrity": "sha512-vPc4I/kkQM9RWfHI0F/OQhoTu+KefplbQp0JEQ4gfr6MwxIm6bBTEuw8T5K9t1DQs8EZ7yeLEsSh65FDPepRtg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input-file": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.14.0-rc.1.tgz", - "integrity": "sha512-WIDKvzWSvSHT5VEGDjZuZC8G0DQUBN5a0l2XVGGc82hQPKfDPZKyaoW2KwJtwioYe/XWa6TT5o1W7MLZHkcIVQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.15.0.tgz", + "integrity": "sha512-VVn2FMsflvEWd6fOX0HQ3JaUh7haznqSqCLTSTOduh/H3jE+dVYCW6YC5uTsxArmOwsSBYSfBQNetW23eJim3Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-action-bar": "1.14.0-rc.1", - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1", - "@umbraco-ui/uui-file-dropzone": "1.14.0-rc.1", - "@umbraco-ui/uui-icon": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry-essential": "1.14.0-rc.1" + "@umbraco-ui/uui-action-bar": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-file-dropzone": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input-lock": { - "version": "1.14.0-rc.3", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.14.0-rc.3.tgz", - "integrity": "sha512-oC7CUGhdxyg48/Ul26F6Dl4P0MtHtCHR+N1x+M+FR1EFnItjifeJYYdzpbdd6XM1vGk8amFREPiIQdHU0n2HOA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.15.0.tgz", + "integrity": "sha512-AFyVYNeExHXe10b3/5/BLZOmMKyMxzftsO0HKbaQQuxrxL2SCHsQJRUpxSY+/0vAl2JbNdmrk0HTsP1O4Y9zig==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1", - "@umbraco-ui/uui-icon": "1.14.0-rc.1", - "@umbraco-ui/uui-input": "1.14.0-rc.3" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-input": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input-password": { - "version": "1.14.0-rc.3", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.14.0-rc.3.tgz", - "integrity": "sha512-XBpvLyBuOJcy06ukvcy16iInxg7V8bwGstEECoqxydzOdCYn+vNe4QbvXp8tf2EgHzM0vFnXLxReRVSUdE+Zkg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.15.0.tgz", + "integrity": "sha512-Pe8lNdHz/6IfbQyWEi0o+pKJ6/zunQ2b8HARCU0a9HFXRDk+XsAuBsn79zQXZl5MvseAUQrnouLwPHpdtMbeMg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry-essential": "1.14.0-rc.1", - "@umbraco-ui/uui-input": "1.14.0-rc.3" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0", + "@umbraco-ui/uui-input": "1.15.0" } }, "node_modules/@umbraco-ui/uui-keyboard-shortcut": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.14.0-rc.1.tgz", - "integrity": "sha512-6AkBtciq2D0kQHyATDLXJmLtlAOX4eO0PDQG4SQXY6CHwdU/oZM3EqBw8bFyavxVLmos2glaCImecPnXthfbrQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.15.0.tgz", + "integrity": "sha512-8Q/G5Lg6949BbMHQ1BhZ9UpoJjOQ19w1tl2y0d/rP3w/mKnTQaBSf+MQmA/6kQ/Unb2wHXJANr4pAGpUklOg6A==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-label": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.14.0-rc.1.tgz", - "integrity": "sha512-6FW1D5Tfcf1Eq5/S3n8yM9+bWQwJQv3UiVdok4Uy7MVpyIJ2wHvzG4gi/lIG1EcScZtCI+7jM+sQEtlJ6FQjhg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.15.0.tgz", + "integrity": "sha512-fnmRl+RGUROERvt+Jw0WiW3Btlddg0Xka6F+gR95gy5gr/v8s34uf1/bbPD3hWUXZPukLmxeMjbzyuqMrO8rpQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-loader": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.14.0-rc.1.tgz", - "integrity": "sha512-QbnFYYWpn9lb2VCqp1UGPHt8Ox9wQ+Gx9sDsxjwfu4FwV5tRxXX1DSmwPXkeErLs7mZCJ/00vWGv4f3uArYNWw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.15.0.tgz", + "integrity": "sha512-HQ2zCp2kz45GWQ3wV153ytuYD2KcdeAA5RRUVrN0Zn3GQB3wfG7xMkQQNRAOWMUdnfqmdQHeK+COO7NaET3VBA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-loader-bar": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.14.0-rc.1.tgz", - "integrity": "sha512-+5/hf3df9sHuckPMX1qLhG0ojhSo78FrOleRCU+73ekhamuHc63DhPvoWL+r4JBPcj8/bY6IOm6Wgxhfkdze9w==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.15.0.tgz", + "integrity": "sha512-4eMeerunFc5yZsJIwpHADn8oGcu0Nn36oyKbSd0qC0mNmmN2i8UOF9w4O+lndd2L0Mhv23FGvBRo7mb5EAvWlg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-loader-circle": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.14.0-rc.1.tgz", - "integrity": "sha512-0JLJmz6Zp+0sLnh7dhUMWEhAh3JFz7Ek7AKxIxl7lEiZsPyFVhdj/3m/RuZVFizhNmS2EAdijXedWrx1C5oDvA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.15.0.tgz", + "integrity": "sha512-4rG8UHvyS2qvsjQYEmYjKX01SRwfk60oH8SSSx8r3z2BM62dCOa+4SBhLxqiBciC/u8FtN8X20MIGE0+eMdtoA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-menu-item": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.14.0-rc.1.tgz", - "integrity": "sha512-tFUPa7xXu+Ol9eJ93gVOxhA0IIf14exO6iJKTIoglnRSz9s8SvPuTeCaLtRBJ3TBscVzvhn1MHktk9DSl74Eig==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.15.0.tgz", + "integrity": "sha512-BOebCMB/p4TaK4kJYrYgimC6SSGBHN4y1MytK3tyvObbuj3gVqkbwHW5CZrhK4jMaywRgGq96OsuaGfc52HFog==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-loader-bar": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-expand": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-loader-bar": "1.15.0", + "@umbraco-ui/uui-symbol-expand": "1.15.0" } }, "node_modules/@umbraco-ui/uui-modal": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.14.0-rc.1.tgz", - "integrity": "sha512-SMdArBh1/8cPNoFSsVsK6ntXULRgqLOZDMtTHgAz75nzV+109b22F2Jaj8g72oRVzfRMJN+VrinfKAYSN6dU8A==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.15.0.tgz", + "integrity": "sha512-EDz1Qx+mTXNvOu565IculPCyuuFHwBon2wYnfWDBMoHJ5+P54jBHzg2U/8fUVse7xKPvU21hF4JneAvycNIiGQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-pagination": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.14.0-rc.1.tgz", - "integrity": "sha512-MhzGJ6ZDq2GpKgtSmb+RPri10fWOEAtaFyYaV0dGSSqydv7/aZgFurqlVhuYwyvtZwd8Mc0KBdFPU8DIvacP8g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.15.0.tgz", + "integrity": "sha512-sPVs1bApKupNd2JcSMwFS1060Y++Fti1ybJrafcLh1+h4IjmLDIRTHTTL8C+kei5G2Oi3+Z7vGpLu7lrTAmRlw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1", - "@umbraco-ui/uui-button-group": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-button-group": "1.15.0" } }, "node_modules/@umbraco-ui/uui-popover": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.14.0-rc.1.tgz", - "integrity": "sha512-SAwvphLrI7dKJdpASGwewObweVMksKm42fx8ffBsTpDWvBqhbLj5pCnn89Nx39S1KIqVUDNOzzihiTluCgK0+g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.15.0.tgz", + "integrity": "sha512-VCHVvO0fd5eL5UvB/RPL/K68UhOgsIpuyr+aXLblaYT/6at2LNosUxR4eRW2r0WOQzOiyE+Nu69pExBKyfT8bw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-popover-container": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover-container/-/uui-popover-container-1.14.0-rc.1.tgz", - "integrity": "sha512-6pr47VkioxRToaXw+EfL+XxLXwXmRfaYFJeMJun6AXhXuMWTeWlfaRP2qOL0cpDoikCEXp7EfOs0RJF6dBE9zw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover-container/-/uui-popover-container-1.15.0.tgz", + "integrity": "sha512-54M4G0ru8j5ltPAdDGIxogdmos33hxeQeusI/uMFxo2yqHHyMHRi95vvCdcwFmGlEdFd2rsnxZKfNMUKM99GKQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-progress-bar": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.14.0-rc.1.tgz", - "integrity": "sha512-ECEVeldTgnfE2ke8DId0qRzKzhUxQgkTb5v0Qq6GyZ8PZ2o+8SPBEOCfLjWLWmh4mU089bQ52j+JXUdUwLanOA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.15.0.tgz", + "integrity": "sha512-vtGUwHaG4EDLQERkwym51OasoWLj30LQLhcCCYXDJtTL1dG2nIKScEtlSUiVh5qRsI+V+kaBYPGD4TFD5o43tQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-radio": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.14.0-rc.1.tgz", - "integrity": "sha512-pdBlfY9P9BtVuMSwkQJ7D4d75a1hFcubhHw5UNdpKewfymgZQ+mKP7tud9OXHmHedgl33fhVhnoT3hIA5sAJJQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.15.0.tgz", + "integrity": "sha512-5TUF/iWUzbVXvBs9Z273q6s9yLbns8itTiFHCITw5w5fZzDn8R6O5hrOW7tV79kCxAnBSOAVP8v1JhGTwXw19Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-range-slider": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.14.0-rc.1.tgz", - "integrity": "sha512-uOetRX6U+g5mNLRcDH787tEx068zrb8VNSLH8oYz5Gva7rCigz5U34VYjOjYjZRIph0W2CeUowI/FEil6N2/DQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.15.0.tgz", + "integrity": "sha512-HMHVdBoB1O39rojofezee2aXGv6CMn7dUFvNefdF9HxmNrIcpFBYXSL8aBt5QJeziFQMwbCtqyY21aUag0nzfw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.14.0-rc.1.tgz", - "integrity": "sha512-5O1ixILx04ZIm9JaQuEz/O5I/LNNY5lOcd+2k52AQEEQFszBrQnEdvmh4iKmzGXRRkfW2c5UjJP5Vt2iy21lag==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.15.0.tgz", + "integrity": "sha512-w7FZIe5mtsgvsf6hOH5mHKDBzg9Rd/+viyk/xNVs1NeZBn1nWEIHZs0R7YMpv+QxulklhAOpBcbGoUTB8xE+vA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-list": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.14.0-rc.1.tgz", - "integrity": "sha512-dw+RYYK83R8c8DiClTNYp3fpiecExIJtFgbViBbzAu0Y9YX7VT2pTjAQJJtYM+oZ9B+J+mPpCLfErMVNPXHHlA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.15.0.tgz", + "integrity": "sha512-UT65bpUmRlEgVuvn2RlTZ5l2WDF82jH1t8g+6HV6OJctpqTKlOfPkQmd6AluESPhHFEwwTydS/M7x+X3Adkdtw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.14.0-rc.1.tgz", - "integrity": "sha512-7G13F0C/h2mqtnejuCoPJQwp3Vcb0iFBjVaTP/6zkcpKe9o16DRbjHOr83mhV5ocFqg4z+LSELh+2faEz0uBag==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.15.0.tgz", + "integrity": "sha512-ybDqIt1cXd7AiZLZsDrSHCMp2zM8I+0lmN599b3NROjm59SZXIvpbY1TS1gJ45htgsc18x2y+S4laInYu2dGUg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-icon": "1.14.0-rc.1", - "@umbraco-ui/uui-ref": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-ref": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-data-type": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.14.0-rc.1.tgz", - "integrity": "sha512-CVsyxHab7Ck+spHGp+1JCVJptWSpKmN5AHRaxYX+5JB+bSMcJPEQ8gEcEnPm+or74Fhe1j7tqaxCJfaK+8eTMA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.15.0.tgz", + "integrity": "sha512-59s16558ySCX7b9IT/Sorq0fdFeCRENSTa7DIkQUrvVPaFWqKFz9jCYFEqDnH11jZHGsNiYh5YCmWlF/VNbwJQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-document-type": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.14.0-rc.1.tgz", - "integrity": "sha512-3C3cmNc1WdlHaqCteTOAAhxkK58xx4LtsolOXw2UbskQx+nZqy8T9+GvpZvMNqfa7AwM4egi/TQEWCS/pdLDog==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.15.0.tgz", + "integrity": "sha512-AWPZPkFGcAkRx4j6JnOi2r3EJxnvZUXfhOWNyWB2/dFRckatPH56+lVkqV+fRC+81emKBSQWkx2NphFzLEMr0A==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-form": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.14.0-rc.1.tgz", - "integrity": "sha512-npyTxiVLD0Td5e1VmAxccEqkXXPnZZWFim8ua0Np9YnpakPndILy1ojMixY5LiwR24zRztF6GNXEYJY5eAb4gQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.15.0.tgz", + "integrity": "sha512-knIIbbfoWtepOvyC54dCo3xF0Vuap6i5uMQPd+wITCmg56a+yiJFuke+dyzatOIeXzgspLgFUngwQZEj5mJnWA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-member": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.14.0-rc.1.tgz", - "integrity": "sha512-k2hRnwot0gjLi8nYz5sebglVFF2r2ZPTNTQW6RtyHRHmKHEwIQKCNYqcw98Fg8uNsLB3zlbu65BYtxhh9FMgfA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.15.0.tgz", + "integrity": "sha512-pXvL523m2JR3P8OO+E1AE4YAaYhJLc519CtjNXSuctNIk1yWvwxBu8VozLIQV+xrOXGz+SiXwDkoaRPwjTQKtg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-package": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.14.0-rc.1.tgz", - "integrity": "sha512-Ix72i/STydhfkyK8mzh0Uqem/wLF2h561Wfo8+2szMdiE4Df82YAv+dXOA/DDwBDyDqZ0RSdng4zUVLo4TyVtQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.15.0.tgz", + "integrity": "sha512-bQWfZPKJyAf2O/YvOD6fVSSpKaYZMBsrEGT+ydLPv3BNJroYHS8+NEbulZxExWztNApTcs6Vo5T19AUz+vsnLQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-user": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.14.0-rc.1.tgz", - "integrity": "sha512-axKvqQLksy2IlvW9jzGdKS6z+jZMpN+aoM1+oydiQT5oSTt7jKvV6hC+SFwY/C4ZwXT2wNK8Jcp4hxJdZVRUQg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.15.0.tgz", + "integrity": "sha512-4GpRzhGedMwjqW1Wk7AvgakNCc6S1edYpHWeO6cfmryIm0hvnCfkU132lzLmB+Ag2QIOI8p4Ak0OQHYWd+XZHw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-scroll-container": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.14.0-rc.1.tgz", - "integrity": "sha512-j+Ieq1wxfHouBXeqncHVsqR7cLC2lFDkmdUC2POJgFGNQre+qoLsBuxCW+DUIlnPDOYK6xtveyx72cnxbM3KVw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.15.0.tgz", + "integrity": "sha512-L4qM6GPDqu0/9B2OVb3EljZT3zYxbwp6uOz1nfVYpGAWBxd6INOtNbn8WYdZLq6qqa8NR6qK+su2554nInvQGA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-select": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.14.0-rc.1.tgz", - "integrity": "sha512-j0iC0pmMXj5pLAM/aiVtxQY3M9GJUrqB/ORB4lh/EdFzMCIYfuLBCuUsCVwBISLKahiwkbYgVDSSMqx6Wqm+KQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.15.0.tgz", + "integrity": "sha512-yRx+TlXBB05jM8ShThRooFgCS5nSN7eAAnpttZgBWqY3sccIVy2Knbkz3kXLJE6ld+bO5nUXhsZBZ34MEHkiog==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-slider": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.14.0-rc.1.tgz", - "integrity": "sha512-f9/vO3G1OnKpQ+ondvT3kPd9QbUm51jrPXoBDia0KmB4sst3md+SYhsCiuDFZHWKZJSiO+DQnJcC2kPnRzfcsg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.15.0.tgz", + "integrity": "sha512-+OAzOutyUB2WCI+e5aFRoUNsFFuc/hUXnpIjx4P1moOYiggc/NxjaTHz5mxbmkC11yyS+0vpl8lVSZglkLCH5w==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-expand": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.14.0-rc.1.tgz", - "integrity": "sha512-v2jyDByfc4c6xqn4MTGbjXHtQzYc0exEfz9IGmGocxmNnQI7EZaXzfHeEQngg3eDp8tOBt4H0rN/2FzZB0nkrA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.15.0.tgz", + "integrity": "sha512-6y9rpFfhtuWMnaAamlzrB5Q12dsZ8dprmQaGtKr+g97PTNRPC3/dc5sdROam8VMDAhL9MkfBAZBoS6yAoJsPcQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-file": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.14.0-rc.1.tgz", - "integrity": "sha512-fms6F/qRPA9nVGldJ03+/2WyvpQMXylWbo0OZm027egwtIsF5Pg/qLv/TNLd7tWjUPMTPglvdYvNDwSi1wiAIQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.15.0.tgz", + "integrity": "sha512-F0BueWxu6J5P7xyzkp1c/eFZJjStsw65hB3bNEmWBOqkm/jbBKg9+Xs99tov+VwCHYOt8T+DuEDkkKmdxVAxyQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-file-dropzone": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.14.0-rc.1.tgz", - "integrity": "sha512-Y3GB4UAOEQ1yDi7/YHORMZn9He4vXQwwK/KLJKfZZDUoARaOl7o9U742R/qxTtMSV9UNMbXW0fgduf1hHktzdg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.15.0.tgz", + "integrity": "sha512-D5DottbukIFxL+YTVEMujHPdqB8Hhw02TKpegfDQb8UGSPC5pCQw4O212TSuyTalKb598niNmCzcjEG5TWNqww==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-file-thumbnail": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.14.0-rc.1.tgz", - "integrity": "sha512-DR/Lk0vBA/IQEq0kGzS8gp980/1H1x1eRFkkQNQzByaacAXYlbC9ia0Sp9ecVubQxRRDik38uWSqCYr/CO+QeQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.15.0.tgz", + "integrity": "sha512-JLcEVnJqv2LL8VtscPCtPKda9ywWzV4vd0XODHLE3iI1cgHeNwMBhxqgkah0ULuw5w2Hrq8gwQ7/DuPHMSIFxw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-folder": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.14.0-rc.1.tgz", - "integrity": "sha512-j/p3f/TtwjMoGM/LMhlG6f/wF1ASOS22eyV0n3rPw934HeAEhNCEwGFlKpzm359BQY9gMA75ULW7K+f5jXrhEA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.15.0.tgz", + "integrity": "sha512-CPsr1K5IkdxBgID+xoIcgbumm/z0q+Z/1NPxTO40EL7kx3KOLQ8vwLdOTSW1cTj90JFA9+XuRtOpmMEY0XjICg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-lock": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.14.0-rc.1.tgz", - "integrity": "sha512-mlNE6XkBGf4VggJjsS5HGdmAseLICVloTg96HEoRFsYpAGMtzQb57rif5P5YQMH+S+KyQ4YEULuYAujwla2R3g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.15.0.tgz", + "integrity": "sha512-5QyDNFjiBeuPgalT9zwPMP220zJUHPpbPvCohWCFLn/2JJsa6IjSMtsAcqxI154ZJ9vYX7vYiYUn8tJTY8CHpA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-more": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.14.0-rc.1.tgz", - "integrity": "sha512-bZ6bsKdiprHr4O4IzOp7R7HkRZukIEySfLqkU1Q5CKjX4O25BE1Wlq1+GcSjWjTNAHJg9H3m4kgGh5WgRDKtvQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.15.0.tgz", + "integrity": "sha512-BQq7BwZ7nCcgKE5tMhG6OVYTrrMEIXpx8kQKec/ULgVfs0/Ws6qeH9u4rGVK/yHU8gecd6DSeUczjjq2iS4djA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-sort": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.14.0-rc.1.tgz", - "integrity": "sha512-K/RKOFSjt2YmnrTBaLg6kNHE9zzMaNRvETSWAbtxQz0TfttOkOszSQqo/HbgDAN+gNIWhRnhvgM1qcaqCLQleg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.15.0.tgz", + "integrity": "sha512-5Akw8T0SV2OrwvPk1JSeFr1clvHE4N0DwceSU9bn9f6gLIGGRxvniJAclQDRI/Woe3hm8waMy6cC2fXfSdc6lg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-table": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.14.0-rc.1.tgz", - "integrity": "sha512-UcIY938Iy96qoU63BIGOi+onW10aRN27y69npB6qeRlVlqMcwS8ywV51qS/KdF/uO7P7uCBhqrAlhE/miVsIGQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.15.0.tgz", + "integrity": "sha512-AnPp0QJeI70ucX8ludr3qaFmlxjKZUarX10DI8ieIB8VJiQZo0TjoPcPdSGmZupaPBLiszlpb3rKzGkZhXEIHg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-tabs": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.14.0-rc.1.tgz", - "integrity": "sha512-HjdeqlnB+Q+4DAB/N8n/H1MIZcCusJnx4yh2JlrgZjiiQ70cYRSIOfd5MDTjjHHnT/GEehH9Fma9TMBpvjV38A==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.15.0.tgz", + "integrity": "sha512-oS0eA5Z8+s+5o2ks3WCED5VGP8AunRLyuB2y7kVdRUfhCfck7B9v83zNfxPVoGoVsTDLtAQM1S4P8SHwNRmk7g==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1", - "@umbraco-ui/uui-popover-container": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-more": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", + "@umbraco-ui/uui-symbol-more": "1.15.0" } }, "node_modules/@umbraco-ui/uui-tag": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.14.0-rc.1.tgz", - "integrity": "sha512-aap19BcZnmGMxjEW2YEHbrgFn9NqZ0zrQDEdYJsUwxCof10nE7cjAqbnPiwUGG1N6P6xkjHAJgvCbyoE0d6pEA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.15.0.tgz", + "integrity": "sha512-PgyZvAiOZmXmiRW4UhfD6Tybx3ft755aKAVqT8ELpskLSvVr1oz4uTI6+QxoeQ1AkrHovenvIdBX+Iwi91SheQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-textarea": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.14.0-rc.1.tgz", - "integrity": "sha512-Cipf1trREF4MXeAV0YCuFBiEZ5LfmaL2v/gzFsSgSa55EEnmywBlw1J0HuFNBgPQR2o7CHmwiCBF/WKB1d6U1Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.15.0.tgz", + "integrity": "sha512-tk/RVzCxs+KPSJ+qH2Xlr9RYxcdrSNulDKk5sBCQR0A9nwOffa15SGreSMKWgq+gYOVYChHBg/WxLWLq3d7Rlg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toast-notification": { - "version": "1.14.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.14.0-rc.2.tgz", - "integrity": "sha512-2468kSLWvHpxgk2VrPJIdpA5u4Tk36OMvxmjcEOzJ+NT/Acw01l2DG5K5fL4aV61f9eCHrzjDatY9jNyNE9yfg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.15.0.tgz", + "integrity": "sha512-nz+snpjPFE+ftH5R/ekgZYy9ofGAf51yQYjWCtBwkrQ6D1dIBYA6kynZFdqIefrRwJJ5zHpe25BcS/AyRPc/9Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1", - "@umbraco-ui/uui-css": "1.14.0-rc.2", - "@umbraco-ui/uui-icon": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry-essential": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toast-notification-container": { - "version": "1.14.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.14.0-rc.2.tgz", - "integrity": "sha512-eGVZbkb/l9zGNu9JSxcbqJ6cC1Bqsytjw7aZN4g1n2KoCbjkqOCCQ+T6fY0CdwF5Au5RwZnTOuWdzvr43zU35w==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.15.0.tgz", + "integrity": "sha512-fd5d0DU/x2+u15rP0wrjw29M0oqsDFmnAfbPEdgQoPV+hvq9/SLhxJtzx10ZSNXoyuO9sTK50Q7nYsqOvGCzqg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-toast-notification": "1.14.0-rc.2" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-toast-notification": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toast-notification-layout": { - "version": "1.14.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.14.0-rc.2.tgz", - "integrity": "sha512-/oON/cmmLjOw6yhEp34EvHMZ/JKQWTtQJOmmC1hkyjG6fzoKOrcpncdJpp8sKgmxD5g8KMmLOElCFFOqyzBBSQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.15.0.tgz", + "integrity": "sha512-uf/e/dVN6kqX76vcawiQM3w1nMHa8A+ZTtNwxtmAZi8bNPwjXLNaqKfeSp2thTByCIzFz7imnft56QtYLbksOA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-css": "1.14.0-rc.2" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toggle": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.14.0-rc.1.tgz", - "integrity": "sha512-DtgowNYwm7PglwZIbyXGO3JlLUedYBVu8JNvWGQeWpOjZq8B3OQlsDCMPnjCfvTklE/pwI+6CCuiFHbZF2zz1A==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.15.0.tgz", + "integrity": "sha512-WLooENcxuAobbXxN1W2uKGh/cN9k0f3cRmDDtCZdgjeheGlBYWatkc5HQte7zchXHUi0xTrsvBCBa9CsLKN/3Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-boolean-input": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-boolean-input": "1.15.0" } }, "node_modules/@umbraco-ui/uui-visually-hidden": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-visually-hidden/-/uui-visually-hidden-1.14.0-rc.1.tgz", - "integrity": "sha512-PUCR/1mbeS4ziQ2uNp1egopUHvjwtJBgqyvMuXPSIk2KepkqiXCnU3P2+iDCuaLS79qTYzORiZXEDcNfZ6DSHA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-visually-hidden/-/uui-visually-hidden-1.15.0.tgz", + "integrity": "sha512-vn3dbpYGekAqG944Vkwd0ILQRtTaZtL1BVdsge2UsU8sOsEKwv5YzQal4b+o8yu8nb4vZbWHZ2zRmnpnPgPmjg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/acorn": { @@ -2729,6 +2749,16 @@ "node": ">=0.4.0" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -2791,6 +2821,22 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/c12": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/c12/-/c12-2.0.1.tgz", @@ -2919,6 +2965,16 @@ "dev": true, "license": "MIT" }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", @@ -2972,6 +3028,49 @@ "license": "MIT", "peer": true }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/defu": { "version": "6.1.4", "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", @@ -3249,6 +3348,22 @@ "dev": true, "license": "MIT" }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -3259,6 +3374,25 @@ "node": ">=8" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-node-process": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", @@ -3266,6 +3400,22 @@ "dev": true, "license": "MIT" }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/jiti": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", @@ -3309,9 +3459,9 @@ "peer": true }, "node_modules/lit": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lit/-/lit-3.3.0.tgz", - "integrity": "sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.3.1.tgz", + "integrity": "sha512-Ksr/8L3PTapbdXJCk+EJVB78jDodUMaP54gD24W186zGRARvwrsPfS60wae/SSCTCNZVPd1chXqio1qHQmu4NA==", "dev": true, "license": "BSD-3-Clause", "peer": true, @@ -3322,22 +3472,22 @@ } }, "node_modules/lit-element": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.0.tgz", - "integrity": "sha512-MGrXJVAI5x+Bfth/pU9Kst1iWID6GHDLEzFEnyULB/sFiRLgkd8NPK/PeeXxktA3T6EIIaq8U3KcbTU5XFcP2Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.1.tgz", + "integrity": "sha512-WGAWRGzirAgyphK2urmYOV72tlvnxw7YfyLDgQ+OZnM9vQQBQnumQ7jUJe6unEzwGU3ahFOjuz1iz1jjrpCPuw==", "dev": true, "license": "BSD-3-Clause", "peer": true, "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.2.0", + "@lit-labs/ssr-dom-shim": "^1.4.0", "@lit/reactive-element": "^2.1.0", "lit-html": "^3.3.0" } }, "node_modules/lit-html": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.0.tgz", - "integrity": "sha512-RHoswrFAxY2d8Cf2mm4OZ1DgzCoBKUKSPvA1fhtSELxUERq2aQQ2h05pO9j81gS1o7RIRJ+CePLogfyahwmynw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.1.tgz", + "integrity": "sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==", "dev": true, "license": "BSD-3-Clause", "peer": true, @@ -3604,6 +3754,25 @@ "dev": true, "license": "MIT" }, + "node_modules/open": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.2.tgz", + "integrity": "sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/orderedmap": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", @@ -3709,9 +3878,9 @@ } }, "node_modules/prosemirror-changeset": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.3.0.tgz", - "integrity": "sha512-8wRKhlEwEJ4I13Ju54q2NZR1pVKGTgJ/8XsQ8L5A5uUsQ/YQScQJuEAuh8Bn8i6IwAMjjLRABd9lVli+DlIiVw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.3.1.tgz", + "integrity": "sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==", "dev": true, "license": "MIT", "peer": true, @@ -3836,9 +4005,9 @@ } }, "node_modules/prosemirror-model": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.1.tgz", - "integrity": "sha512-AUvbm7qqmpZa5d9fPKMvH1Q5bqYQvAZWOGRvxsB6iFLyycvC9MwNemNVjHVrWgjaoxAfY8XVg7DbvQ/qxvI9Eg==", + "version": "1.25.3", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.3.tgz", + "integrity": "sha512-dY2HdaNXlARknJbrManZ1WyUtos+AP97AmvqdOQtWtrrC5g4mohVX5DTi9rXNFSk09eczLq9GuNTtq3EfMeMGA==", "dev": true, "license": "MIT", "peer": true, @@ -3927,9 +4096,9 @@ } }, "node_modules/prosemirror-view": { - "version": "1.39.3", - "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.39.3.tgz", - "integrity": "sha512-bY/7kg0LzRE7ytR0zRdSMWX3sknEjw68l836ffLPMh0OG3OYnNuBDUSF3v0vjvnzgYjgY9ZH/RypbARURlcMFA==", + "version": "1.40.1", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.40.1.tgz", + "integrity": "sha512-pbwUjt3G7TlsQQHDiYSupWBhJswpLVB09xXm1YiJPdkjkh9Pe7Y51XdLh5VWIZmROLY8UpUpG03lkdhm9lzIBA==", "dev": true, "license": "MIT", "peer": true, @@ -4070,6 +4239,19 @@ "license": "MIT", "peer": true }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/rxjs": { "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", @@ -4081,6 +4263,19 @@ "tslib": "^2.1.0" } }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", diff --git a/src/Umbraco.Web.UI.Login/package.json b/src/Umbraco.Web.UI.Login/package.json index 3e698ee75f..017961f872 100644 --- a/src/Umbraco.Web.UI.Login/package.json +++ b/src/Umbraco.Web.UI.Login/package.json @@ -14,9 +14,8 @@ "npm": ">=10.9" }, "devDependencies": { - "@hey-api/client-fetch": "^0.10.2", - "@hey-api/openapi-ts": "^0.67.6", - "@umbraco-cms/backoffice": "16.0.0-rc4", + "@hey-api/openapi-ts": "0.81.1", + "@umbraco-cms/backoffice": "16.2.0-rc", "msw": "^2.7.0", "typescript": "^5.9.2", "vite": "^7.1.3" @@ -26,4 +25,4 @@ "public" ] } -} +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Login/src/api/client.gen.ts b/src/Umbraco.Web.UI.Login/src/api/client.gen.ts index 6759c1f28e..163da4e54e 100644 --- a/src/Umbraco.Web.UI.Login/src/api/client.gen.ts +++ b/src/Umbraco.Web.UI.Login/src/api/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import type { ClientOptions } from './types.gen'; -import { type Config, type ClientOptions as DefaultClientOptions, createClient, createConfig } from '@hey-api/client-fetch'; +import { type Config, type ClientOptions as DefaultClientOptions, createClient, createConfig } from './client'; /** * The `createClientConfig()` function will be called on client initialization diff --git a/src/Umbraco.Web.UI.Login/src/api/client/client.gen.ts b/src/Umbraco.Web.UI.Login/src/api/client/client.gen.ts new file mode 100644 index 0000000000..0c60a9ab77 --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/client/client.gen.ts @@ -0,0 +1,240 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { createSseClient } from '../core/serverSentEvents.gen'; +import type { HttpMethod } from '../core/types.gen'; +import type { + Client, + Config, + RequestOptions, + ResolvedRequestOptions, +} from './types.gen'; +import { + buildUrl, + createConfig, + createInterceptors, + getParseAs, + mergeConfigs, + mergeHeaders, + setAuthParams, +} from './utils.gen'; + +type ReqInit = Omit & { + body?: any; + headers: ReturnType; +}; + +export const createClient = (config: Config = {}): Client => { + let _config = mergeConfigs(createConfig(), config); + + const getConfig = (): Config => ({ ..._config }); + + const setConfig = (config: Config): Config => { + _config = mergeConfigs(_config, config); + return getConfig(); + }; + + const interceptors = createInterceptors< + Request, + Response, + unknown, + ResolvedRequestOptions + >(); + + const beforeRequest = async (options: RequestOptions) => { + const opts = { + ..._config, + ...options, + fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, + headers: mergeHeaders(_config.headers, options.headers), + serializedBody: undefined, + }; + + if (opts.security) { + await setAuthParams({ + ...opts, + security: opts.security, + }); + } + + if (opts.requestValidator) { + await opts.requestValidator(opts); + } + + if (opts.body && opts.bodySerializer) { + opts.serializedBody = opts.bodySerializer(opts.body); + } + + // remove Content-Type header if body is empty to avoid sending invalid requests + if (opts.serializedBody === undefined || opts.serializedBody === '') { + opts.headers.delete('Content-Type'); + } + + const url = buildUrl(opts); + + return { opts, url }; + }; + + const request: Client['request'] = async (options) => { + // @ts-expect-error + const { opts, url } = await beforeRequest(options); + const requestInit: ReqInit = { + redirect: 'follow', + ...opts, + body: opts.serializedBody, + }; + + let request = new Request(url, requestInit); + + for (const fn of interceptors.request._fns) { + if (fn) { + request = await fn(request, opts); + } + } + + // fetch must be assigned here, otherwise it would throw the error: + // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation + const _fetch = opts.fetch!; + let response = await _fetch(request); + + for (const fn of interceptors.response._fns) { + if (fn) { + response = await fn(response, request, opts); + } + } + + const result = { + request, + response, + }; + + if (response.ok) { + if ( + response.status === 204 || + response.headers.get('Content-Length') === '0' + ) { + return opts.responseStyle === 'data' + ? {} + : { + data: {}, + ...result, + }; + } + + const parseAs = + (opts.parseAs === 'auto' + ? getParseAs(response.headers.get('Content-Type')) + : opts.parseAs) ?? 'json'; + + let data: any; + switch (parseAs) { + case 'arrayBuffer': + case 'blob': + case 'formData': + case 'json': + case 'text': + data = await response[parseAs](); + break; + case 'stream': + return opts.responseStyle === 'data' + ? response.body + : { + data: response.body, + ...result, + }; + } + + if (parseAs === 'json') { + if (opts.responseValidator) { + await opts.responseValidator(data); + } + + if (opts.responseTransformer) { + data = await opts.responseTransformer(data); + } + } + + return opts.responseStyle === 'data' + ? data + : { + data, + ...result, + }; + } + + const textError = await response.text(); + let jsonError: unknown; + + try { + jsonError = JSON.parse(textError); + } catch { + // noop + } + + const error = jsonError ?? textError; + let finalError = error; + + for (const fn of interceptors.error._fns) { + if (fn) { + finalError = (await fn(error, response, request, opts)) as string; + } + } + + finalError = finalError || ({} as string); + + if (opts.throwOnError) { + throw finalError; + } + + // TODO: we probably want to return error and improve types + return opts.responseStyle === 'data' + ? undefined + : { + error: finalError, + ...result, + }; + }; + + const makeMethodFn = + (method: Uppercase) => (options: RequestOptions) => + request({ ...options, method }); + + const makeSseFn = + (method: Uppercase) => async (options: RequestOptions) => { + const { opts, url } = await beforeRequest(options); + return createSseClient({ + ...opts, + body: opts.body as BodyInit | null | undefined, + headers: opts.headers as unknown as Record, + method, + url, + }); + }; + + return { + buildUrl, + connect: makeMethodFn('CONNECT'), + delete: makeMethodFn('DELETE'), + get: makeMethodFn('GET'), + getConfig, + head: makeMethodFn('HEAD'), + interceptors, + options: makeMethodFn('OPTIONS'), + patch: makeMethodFn('PATCH'), + post: makeMethodFn('POST'), + put: makeMethodFn('PUT'), + request, + setConfig, + sse: { + connect: makeSseFn('CONNECT'), + delete: makeSseFn('DELETE'), + get: makeSseFn('GET'), + head: makeSseFn('HEAD'), + options: makeSseFn('OPTIONS'), + patch: makeSseFn('PATCH'), + post: makeSseFn('POST'), + put: makeSseFn('PUT'), + trace: makeSseFn('TRACE'), + }, + trace: makeMethodFn('TRACE'), + } as Client; +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/client/index.ts b/src/Umbraco.Web.UI.Login/src/api/client/index.ts new file mode 100644 index 0000000000..318a84b6a8 --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/client/index.ts @@ -0,0 +1,25 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type { Auth } from '../core/auth.gen'; +export type { QuerySerializerOptions } from '../core/bodySerializer.gen'; +export { + formDataBodySerializer, + jsonBodySerializer, + urlSearchParamsBodySerializer, +} from '../core/bodySerializer.gen'; +export { buildClientParams } from '../core/params.gen'; +export { createClient } from './client.gen'; +export type { + Client, + ClientOptions, + Config, + CreateClientConfig, + Options, + OptionsLegacyParser, + RequestOptions, + RequestResult, + ResolvedRequestOptions, + ResponseStyle, + TDataShape, +} from './types.gen'; +export { createConfig, mergeHeaders } from './utils.gen'; diff --git a/src/Umbraco.Web.UI.Login/src/api/client/types.gen.ts b/src/Umbraco.Web.UI.Login/src/api/client/types.gen.ts new file mode 100644 index 0000000000..5bde93851e --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/client/types.gen.ts @@ -0,0 +1,268 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Auth } from '../core/auth.gen'; +import type { + ServerSentEventsOptions, + ServerSentEventsResult, +} from '../core/serverSentEvents.gen'; +import type { + Client as CoreClient, + Config as CoreConfig, +} from '../core/types.gen'; +import type { Middleware } from './utils.gen'; + +export type ResponseStyle = 'data' | 'fields'; + +export interface Config + extends Omit, + CoreConfig { + /** + * Base URL for all requests made by this client. + */ + baseUrl?: T['baseUrl']; + /** + * Fetch API implementation. You can use this option to provide a custom + * fetch instance. + * + * @default globalThis.fetch + */ + fetch?: (request: Request) => ReturnType; + /** + * Please don't use the Fetch client for Next.js applications. The `next` + * options won't have any effect. + * + * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead. + */ + next?: never; + /** + * Return the response data parsed in a specified format. By default, `auto` + * will infer the appropriate method from the `Content-Type` response header. + * You can override this behavior with any of the {@link Body} methods. + * Select `stream` if you don't want to parse response data at all. + * + * @default 'auto' + */ + parseAs?: + | 'arrayBuffer' + | 'auto' + | 'blob' + | 'formData' + | 'json' + | 'stream' + | 'text'; + /** + * Should we return only data or multiple fields (data, error, response, etc.)? + * + * @default 'fields' + */ + responseStyle?: ResponseStyle; + /** + * Throw an error instead of returning it in the response? + * + * @default false + */ + throwOnError?: T['throwOnError']; +} + +export interface RequestOptions< + TData = unknown, + TResponseStyle extends ResponseStyle = 'fields', + ThrowOnError extends boolean = boolean, + Url extends string = string, +> extends Config<{ + responseStyle: TResponseStyle; + throwOnError: ThrowOnError; + }>, + Pick< + ServerSentEventsOptions, + | 'onSseError' + | 'onSseEvent' + | 'sseDefaultRetryDelay' + | 'sseMaxRetryAttempts' + | 'sseMaxRetryDelay' + > { + /** + * Any body that you want to add to your request. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} + */ + body?: unknown; + path?: Record; + query?: Record; + /** + * Security mechanism(s) to use for the request. + */ + security?: ReadonlyArray; + url: Url; +} + +export interface ResolvedRequestOptions< + TResponseStyle extends ResponseStyle = 'fields', + ThrowOnError extends boolean = boolean, + Url extends string = string, +> extends RequestOptions { + serializedBody?: string; +} + +export type RequestResult< + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = boolean, + TResponseStyle extends ResponseStyle = 'fields', +> = ThrowOnError extends true + ? Promise< + TResponseStyle extends 'data' + ? TData extends Record + ? TData[keyof TData] + : TData + : { + data: TData extends Record + ? TData[keyof TData] + : TData; + request: Request; + response: Response; + } + > + : Promise< + TResponseStyle extends 'data' + ? + | (TData extends Record + ? TData[keyof TData] + : TData) + | undefined + : ( + | { + data: TData extends Record + ? TData[keyof TData] + : TData; + error: undefined; + } + | { + data: undefined; + error: TError extends Record + ? TError[keyof TError] + : TError; + } + ) & { + request: Request; + response: Response; + } + >; + +export interface ClientOptions { + baseUrl?: string; + responseStyle?: ResponseStyle; + throwOnError?: boolean; +} + +type MethodFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'>, +) => RequestResult; + +type SseFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'>, +) => Promise>; + +type RequestFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'> & + Pick< + Required>, + 'method' + >, +) => RequestResult; + +type BuildUrlFn = < + TData extends { + body?: unknown; + path?: Record; + query?: Record; + url: string; + }, +>( + options: Pick & Options, +) => string; + +export type Client = CoreClient< + RequestFn, + Config, + MethodFn, + BuildUrlFn, + SseFn +> & { + interceptors: Middleware; +}; + +/** + * The `createClientConfig()` function will be called on client initialization + * and the returned object will become the client's initial configuration. + * + * You may want to initialize your client this way instead of calling + * `setConfig()`. This is useful for example if you're using Next.js + * to ensure your client always has the correct values. + */ +export type CreateClientConfig = ( + override?: Config, +) => Config & T>; + +export interface TDataShape { + body?: unknown; + headers?: unknown; + path?: unknown; + query?: unknown; + url: string; +} + +type OmitKeys = Pick>; + +export type Options< + TData extends TDataShape = TDataShape, + ThrowOnError extends boolean = boolean, + TResponse = unknown, + TResponseStyle extends ResponseStyle = 'fields', +> = OmitKeys< + RequestOptions, + 'body' | 'path' | 'query' | 'url' +> & + Omit; + +export type OptionsLegacyParser< + TData = unknown, + ThrowOnError extends boolean = boolean, + TResponseStyle extends ResponseStyle = 'fields', +> = TData extends { body?: any } + ? TData extends { headers?: any } + ? OmitKeys< + RequestOptions, + 'body' | 'headers' | 'url' + > & + TData + : OmitKeys< + RequestOptions, + 'body' | 'url' + > & + TData & + Pick, 'headers'> + : TData extends { headers?: any } + ? OmitKeys< + RequestOptions, + 'headers' | 'url' + > & + TData & + Pick, 'body'> + : OmitKeys, 'url'> & + TData; diff --git a/src/Umbraco.Web.UI.Login/src/api/client/utils.gen.ts b/src/Umbraco.Web.UI.Login/src/api/client/utils.gen.ts new file mode 100644 index 0000000000..a47509522b --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/client/utils.gen.ts @@ -0,0 +1,327 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { getAuthToken } from '../core/auth.gen'; +import type { QuerySerializerOptions } from '../core/bodySerializer.gen'; +import { jsonBodySerializer } from '../core/bodySerializer.gen'; +import { + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from '../core/pathSerializer.gen'; +import { getUrl } from '../core/utils.gen'; +import type { Client, ClientOptions, Config, RequestOptions } from './types.gen'; + +export const createQuerySerializer = ({ + allowReserved, + array, + object, +}: QuerySerializerOptions = {}) => { + const querySerializer = (queryParams: T) => { + const search: string[] = []; + if (queryParams && typeof queryParams === 'object') { + for (const name in queryParams) { + const value = queryParams[name]; + + if (value === undefined || value === null) { + continue; + } + + if (Array.isArray(value)) { + const serializedArray = serializeArrayParam({ + allowReserved, + explode: true, + name, + style: 'form', + value, + ...array, + }); + if (serializedArray) search.push(serializedArray); + } else if (typeof value === 'object') { + const serializedObject = serializeObjectParam({ + allowReserved, + explode: true, + name, + style: 'deepObject', + value: value as Record, + ...object, + }); + if (serializedObject) search.push(serializedObject); + } else { + const serializedPrimitive = serializePrimitiveParam({ + allowReserved, + name, + value: value as string, + }); + if (serializedPrimitive) search.push(serializedPrimitive); + } + } + } + return search.join('&'); + }; + return querySerializer; +}; + +/** + * Infers parseAs value from provided Content-Type header. + */ +export const getParseAs = ( + contentType: string | null, +): Exclude => { + if (!contentType) { + // If no Content-Type header is provided, the best we can do is return the raw response body, + // which is effectively the same as the 'stream' option. + return 'stream'; + } + + const cleanContent = contentType.split(';')[0]?.trim(); + + if (!cleanContent) { + return; + } + + if ( + cleanContent.startsWith('application/json') || + cleanContent.endsWith('+json') + ) { + return 'json'; + } + + if (cleanContent === 'multipart/form-data') { + return 'formData'; + } + + if ( + ['application/', 'audio/', 'image/', 'video/'].some((type) => + cleanContent.startsWith(type), + ) + ) { + return 'blob'; + } + + if (cleanContent.startsWith('text/')) { + return 'text'; + } + + return; +}; + +const checkForExistence = ( + options: Pick & { + headers: Headers; + }, + name?: string, +): boolean => { + if (!name) { + return false; + } + if ( + options.headers.has(name) || + options.query?.[name] || + options.headers.get('Cookie')?.includes(`${name}=`) + ) { + return true; + } + return false; +}; + +export const setAuthParams = async ({ + security, + ...options +}: Pick, 'security'> & + Pick & { + headers: Headers; + }) => { + for (const auth of security) { + if (checkForExistence(options, auth.name)) { + continue; + } + + const token = await getAuthToken(auth, options.auth); + + if (!token) { + continue; + } + + const name = auth.name ?? 'Authorization'; + + switch (auth.in) { + case 'query': + if (!options.query) { + options.query = {}; + } + options.query[name] = token; + break; + case 'cookie': + options.headers.append('Cookie', `${name}=${token}`); + break; + case 'header': + default: + options.headers.set(name, token); + break; + } + } +}; + +export const buildUrl: Client['buildUrl'] = (options) => + getUrl({ + baseUrl: options.baseUrl as string, + path: options.path, + query: options.query, + querySerializer: + typeof options.querySerializer === 'function' + ? options.querySerializer + : createQuerySerializer(options.querySerializer), + url: options.url, + }); + +export const mergeConfigs = (a: Config, b: Config): Config => { + const config = { ...a, ...b }; + if (config.baseUrl?.endsWith('/')) { + config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1); + } + config.headers = mergeHeaders(a.headers, b.headers); + return config; +}; + +export const mergeHeaders = ( + ...headers: Array['headers'] | undefined> +): Headers => { + const mergedHeaders = new Headers(); + for (const header of headers) { + if (!header || typeof header !== 'object') { + continue; + } + + const iterator = + header instanceof Headers ? header.entries() : Object.entries(header); + + for (const [key, value] of iterator) { + if (value === null) { + mergedHeaders.delete(key); + } else if (Array.isArray(value)) { + for (const v of value) { + mergedHeaders.append(key, v as string); + } + } else if (value !== undefined) { + // assume object headers are meant to be JSON stringified, i.e. their + // content value in OpenAPI specification is 'application/json' + mergedHeaders.set( + key, + typeof value === 'object' ? JSON.stringify(value) : (value as string), + ); + } + } + } + return mergedHeaders; +}; + +type ErrInterceptor = ( + error: Err, + response: Res, + request: Req, + options: Options, +) => Err | Promise; + +type ReqInterceptor = ( + request: Req, + options: Options, +) => Req | Promise; + +type ResInterceptor = ( + response: Res, + request: Req, + options: Options, +) => Res | Promise; + +class Interceptors { + _fns: (Interceptor | null)[]; + + constructor() { + this._fns = []; + } + + clear() { + this._fns = []; + } + + getInterceptorIndex(id: number | Interceptor): number { + if (typeof id === 'number') { + return this._fns[id] ? id : -1; + } else { + return this._fns.indexOf(id); + } + } + exists(id: number | Interceptor) { + const index = this.getInterceptorIndex(id); + return !!this._fns[index]; + } + + eject(id: number | Interceptor) { + const index = this.getInterceptorIndex(id); + if (this._fns[index]) { + this._fns[index] = null; + } + } + + update(id: number | Interceptor, fn: Interceptor) { + const index = this.getInterceptorIndex(id); + if (this._fns[index]) { + this._fns[index] = fn; + return id; + } else { + return false; + } + } + + use(fn: Interceptor) { + this._fns = [...this._fns, fn]; + return this._fns.length - 1; + } +} + +// `createInterceptors()` response, meant for external use as it does not +// expose internals +export interface Middleware { + error: Pick< + Interceptors>, + 'eject' | 'use' + >; + request: Pick>, 'eject' | 'use'>; + response: Pick< + Interceptors>, + 'eject' | 'use' + >; +} + +// do not add `Middleware` as return type so we can use _fns internally +export const createInterceptors = () => ({ + error: new Interceptors>(), + request: new Interceptors>(), + response: new Interceptors>(), +}); + +const defaultQuerySerializer = createQuerySerializer({ + allowReserved: false, + array: { + explode: true, + style: 'form', + }, + object: { + explode: true, + style: 'deepObject', + }, +}); + +const defaultHeaders = { + 'Content-Type': 'application/json', +}; + +export const createConfig = ( + override: Config & T> = {}, +): Config & T> => ({ + ...jsonBodySerializer, + headers: defaultHeaders, + parseAs: 'auto', + querySerializer: defaultQuerySerializer, + ...override, +}); diff --git a/src/Umbraco.Web.UI.Login/src/api/core/auth.gen.ts b/src/Umbraco.Web.UI.Login/src/api/core/auth.gen.ts new file mode 100644 index 0000000000..f8a73266f9 --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/core/auth.gen.ts @@ -0,0 +1,42 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type AuthToken = string | undefined; + +export interface Auth { + /** + * Which part of the request do we use to send the auth? + * + * @default 'header' + */ + in?: 'header' | 'query' | 'cookie'; + /** + * Header or query parameter name. + * + * @default 'Authorization' + */ + name?: string; + scheme?: 'basic' | 'bearer'; + type: 'apiKey' | 'http'; +} + +export const getAuthToken = async ( + auth: Auth, + callback: ((auth: Auth) => Promise | AuthToken) | AuthToken, +): Promise => { + const token = + typeof callback === 'function' ? await callback(auth) : callback; + + if (!token) { + return; + } + + if (auth.scheme === 'bearer') { + return `Bearer ${token}`; + } + + if (auth.scheme === 'basic') { + return `Basic ${btoa(token)}`; + } + + return token; +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/core/bodySerializer.gen.ts b/src/Umbraco.Web.UI.Login/src/api/core/bodySerializer.gen.ts new file mode 100644 index 0000000000..49cd8925e3 --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/core/bodySerializer.gen.ts @@ -0,0 +1,92 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { + ArrayStyle, + ObjectStyle, + SerializerOptions, +} from './pathSerializer.gen'; + +export type QuerySerializer = (query: Record) => string; + +export type BodySerializer = (body: any) => any; + +export interface QuerySerializerOptions { + allowReserved?: boolean; + array?: SerializerOptions; + object?: SerializerOptions; +} + +const serializeFormDataPair = ( + data: FormData, + key: string, + value: unknown, +): void => { + if (typeof value === 'string' || value instanceof Blob) { + data.append(key, value); + } else if (value instanceof Date) { + data.append(key, value.toISOString()); + } else { + data.append(key, JSON.stringify(value)); + } +}; + +const serializeUrlSearchParamsPair = ( + data: URLSearchParams, + key: string, + value: unknown, +): void => { + if (typeof value === 'string') { + data.append(key, value); + } else { + data.append(key, JSON.stringify(value)); + } +}; + +export const formDataBodySerializer = { + bodySerializer: | Array>>( + body: T, + ): FormData => { + const data = new FormData(); + + Object.entries(body).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => serializeFormDataPair(data, key, v)); + } else { + serializeFormDataPair(data, key, value); + } + }); + + return data; + }, +}; + +export const jsonBodySerializer = { + bodySerializer: (body: T): string => + JSON.stringify(body, (_key, value) => + typeof value === 'bigint' ? value.toString() : value, + ), +}; + +export const urlSearchParamsBodySerializer = { + bodySerializer: | Array>>( + body: T, + ): string => { + const data = new URLSearchParams(); + + Object.entries(body).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => serializeUrlSearchParamsPair(data, key, v)); + } else { + serializeUrlSearchParamsPair(data, key, value); + } + }); + + return data.toString(); + }, +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/core/params.gen.ts b/src/Umbraco.Web.UI.Login/src/api/core/params.gen.ts new file mode 100644 index 0000000000..71c88e852b --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/core/params.gen.ts @@ -0,0 +1,153 @@ +// This file is auto-generated by @hey-api/openapi-ts + +type Slot = 'body' | 'headers' | 'path' | 'query'; + +export type Field = + | { + in: Exclude; + /** + * Field name. This is the name we want the user to see and use. + */ + key: string; + /** + * Field mapped name. This is the name we want to use in the request. + * If omitted, we use the same value as `key`. + */ + map?: string; + } + | { + in: Extract; + /** + * Key isn't required for bodies. + */ + key?: string; + map?: string; + }; + +export interface Fields { + allowExtra?: Partial>; + args?: ReadonlyArray; +} + +export type FieldsConfig = ReadonlyArray; + +const extraPrefixesMap: Record = { + $body_: 'body', + $headers_: 'headers', + $path_: 'path', + $query_: 'query', +}; +const extraPrefixes = Object.entries(extraPrefixesMap); + +type KeyMap = Map< + string, + { + in: Slot; + map?: string; + } +>; + +const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { + if (!map) { + map = new Map(); + } + + for (const config of fields) { + if ('in' in config) { + if (config.key) { + map.set(config.key, { + in: config.in, + map: config.map, + }); + } + } else if (config.args) { + buildKeyMap(config.args, map); + } + } + + return map; +}; + +interface Params { + body: unknown; + headers: Record; + path: Record; + query: Record; +} + +const stripEmptySlots = (params: Params) => { + for (const [slot, value] of Object.entries(params)) { + if (value && typeof value === 'object' && !Object.keys(value).length) { + delete params[slot as Slot]; + } + } +}; + +export const buildClientParams = ( + args: ReadonlyArray, + fields: FieldsConfig, +) => { + const params: Params = { + body: {}, + headers: {}, + path: {}, + query: {}, + }; + + const map = buildKeyMap(fields); + + let config: FieldsConfig[number] | undefined; + + for (const [index, arg] of args.entries()) { + if (fields[index]) { + config = fields[index]; + } + + if (!config) { + continue; + } + + if ('in' in config) { + if (config.key) { + const field = map.get(config.key)!; + const name = field.map || config.key; + (params[field.in] as Record)[name] = arg; + } else { + params.body = arg; + } + } else { + for (const [key, value] of Object.entries(arg ?? {})) { + const field = map.get(key); + + if (field) { + const name = field.map || key; + (params[field.in] as Record)[name] = value; + } else { + const extra = extraPrefixes.find(([prefix]) => + key.startsWith(prefix), + ); + + if (extra) { + const [prefix, slot] = extra; + (params[slot] as Record)[ + key.slice(prefix.length) + ] = value; + } else { + for (const [slot, allowed] of Object.entries( + config.allowExtra ?? {}, + )) { + if (allowed) { + (params[slot as Slot] as Record)[key] = value; + break; + } + } + } + } + } + } + } + + stripEmptySlots(params); + + return params; +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/core/pathSerializer.gen.ts b/src/Umbraco.Web.UI.Login/src/api/core/pathSerializer.gen.ts new file mode 100644 index 0000000000..8d99931047 --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/core/pathSerializer.gen.ts @@ -0,0 +1,181 @@ +// This file is auto-generated by @hey-api/openapi-ts + +interface SerializeOptions + extends SerializePrimitiveOptions, + SerializerOptions {} + +interface SerializePrimitiveOptions { + allowReserved?: boolean; + name: string; +} + +export interface SerializerOptions { + /** + * @default true + */ + explode: boolean; + style: T; +} + +export type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited'; +export type ArraySeparatorStyle = ArrayStyle | MatrixStyle; +type MatrixStyle = 'label' | 'matrix' | 'simple'; +export type ObjectStyle = 'form' | 'deepObject'; +type ObjectSeparatorStyle = ObjectStyle | MatrixStyle; + +interface SerializePrimitiveParam extends SerializePrimitiveOptions { + value: string; +} + +export const separatorArrayExplode = (style: ArraySeparatorStyle) => { + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } +}; + +export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { + switch (style) { + case 'form': + return ','; + case 'pipeDelimited': + return '|'; + case 'spaceDelimited': + return '%20'; + default: + return ','; + } +}; + +export const separatorObjectExplode = (style: ObjectSeparatorStyle) => { + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } +}; + +export const serializeArrayParam = ({ + allowReserved, + explode, + name, + style, + value, +}: SerializeOptions & { + value: unknown[]; +}) => { + if (!explode) { + const joinedValues = ( + allowReserved ? value : value.map((v) => encodeURIComponent(v as string)) + ).join(separatorArrayNoExplode(style)); + switch (style) { + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + case 'simple': + return joinedValues; + default: + return `${name}=${joinedValues}`; + } + } + + const separator = separatorArrayExplode(style); + const joinedValues = value + .map((v) => { + if (style === 'label' || style === 'simple') { + return allowReserved ? v : encodeURIComponent(v as string); + } + + return serializePrimitiveParam({ + allowReserved, + name, + value: v as string, + }); + }) + .join(separator); + return style === 'label' || style === 'matrix' + ? separator + joinedValues + : joinedValues; +}; + +export const serializePrimitiveParam = ({ + allowReserved, + name, + value, +}: SerializePrimitiveParam) => { + if (value === undefined || value === null) { + return ''; + } + + if (typeof value === 'object') { + throw new Error( + 'Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.', + ); + } + + return `${name}=${allowReserved ? value : encodeURIComponent(value)}`; +}; + +export const serializeObjectParam = ({ + allowReserved, + explode, + name, + style, + value, + valueOnly, +}: SerializeOptions & { + value: Record | Date; + valueOnly?: boolean; +}) => { + if (value instanceof Date) { + return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`; + } + + if (style !== 'deepObject' && !explode) { + let values: string[] = []; + Object.entries(value).forEach(([key, v]) => { + values = [ + ...values, + key, + allowReserved ? (v as string) : encodeURIComponent(v as string), + ]; + }); + const joinedValues = values.join(','); + switch (style) { + case 'form': + return `${name}=${joinedValues}`; + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + default: + return joinedValues; + } + } + + const separator = separatorObjectExplode(style); + const joinedValues = Object.entries(value) + .map(([key, v]) => + serializePrimitiveParam({ + allowReserved, + name: style === 'deepObject' ? `${name}[${key}]` : key, + value: v as string, + }), + ) + .join(separator); + return style === 'label' || style === 'matrix' + ? separator + joinedValues + : joinedValues; +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/core/serverSentEvents.gen.ts b/src/Umbraco.Web.UI.Login/src/api/core/serverSentEvents.gen.ts new file mode 100644 index 0000000000..01b5818fdf --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/core/serverSentEvents.gen.ts @@ -0,0 +1,237 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Config } from './types.gen'; + +export type ServerSentEventsOptions = Omit< + RequestInit, + 'method' +> & + Pick & { + /** + * Callback invoked when a network or parsing error occurs during streaming. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param error The error that occurred. + */ + onSseError?: (error: unknown) => void; + /** + * Callback invoked when an event is streamed from the server. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param event Event streamed from the server. + * @returns Nothing (void). + */ + onSseEvent?: (event: StreamEvent) => void; + /** + * Default retry delay in milliseconds. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 3000 + */ + sseDefaultRetryDelay?: number; + /** + * Maximum number of retry attempts before giving up. + */ + sseMaxRetryAttempts?: number; + /** + * Maximum retry delay in milliseconds. + * + * Applies only when exponential backoff is used. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 30000 + */ + sseMaxRetryDelay?: number; + /** + * Optional sleep function for retry backoff. + * + * Defaults to using `setTimeout`. + */ + sseSleepFn?: (ms: number) => Promise; + url: string; + }; + +export interface StreamEvent { + data: TData; + event?: string; + id?: string; + retry?: number; +} + +export type ServerSentEventsResult< + TData = unknown, + TReturn = void, + TNext = unknown, +> = { + stream: AsyncGenerator< + TData extends Record ? TData[keyof TData] : TData, + TReturn, + TNext + >; +}; + +export const createSseClient = ({ + onSseError, + onSseEvent, + responseTransformer, + responseValidator, + sseDefaultRetryDelay, + sseMaxRetryAttempts, + sseMaxRetryDelay, + sseSleepFn, + url, + ...options +}: ServerSentEventsOptions): ServerSentEventsResult => { + let lastEventId: string | undefined; + + const sleep = + sseSleepFn ?? + ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))); + + const createStream = async function* () { + let retryDelay: number = sseDefaultRetryDelay ?? 3000; + let attempt = 0; + const signal = options.signal ?? new AbortController().signal; + + while (true) { + if (signal.aborted) break; + + attempt++; + + const headers = + options.headers instanceof Headers + ? options.headers + : new Headers(options.headers as Record | undefined); + + if (lastEventId !== undefined) { + headers.set('Last-Event-ID', lastEventId); + } + + try { + const response = await fetch(url, { ...options, headers, signal }); + + if (!response.ok) + throw new Error( + `SSE failed: ${response.status} ${response.statusText}`, + ); + + if (!response.body) throw new Error('No body in SSE response'); + + const reader = response.body + .pipeThrough(new TextDecoderStream()) + .getReader(); + + let buffer = ''; + + const abortHandler = () => { + try { + reader.cancel(); + } catch { + // noop + } + }; + + signal.addEventListener('abort', abortHandler); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + buffer += value; + + const chunks = buffer.split('\n\n'); + buffer = chunks.pop() ?? ''; + + for (const chunk of chunks) { + const lines = chunk.split('\n'); + const dataLines: Array = []; + let eventName: string | undefined; + + for (const line of lines) { + if (line.startsWith('data:')) { + dataLines.push(line.replace(/^data:\s*/, '')); + } else if (line.startsWith('event:')) { + eventName = line.replace(/^event:\s*/, ''); + } else if (line.startsWith('id:')) { + lastEventId = line.replace(/^id:\s*/, ''); + } else if (line.startsWith('retry:')) { + const parsed = Number.parseInt( + line.replace(/^retry:\s*/, ''), + 10, + ); + if (!Number.isNaN(parsed)) { + retryDelay = parsed; + } + } + } + + let data: unknown; + let parsedJson = false; + + if (dataLines.length) { + const rawData = dataLines.join('\n'); + try { + data = JSON.parse(rawData); + parsedJson = true; + } catch { + data = rawData; + } + } + + if (parsedJson) { + if (responseValidator) { + await responseValidator(data); + } + + if (responseTransformer) { + data = await responseTransformer(data); + } + } + + onSseEvent?.({ + data, + event: eventName, + id: lastEventId, + retry: retryDelay, + }); + + if (dataLines.length) { + yield data as any; + } + } + } + } finally { + signal.removeEventListener('abort', abortHandler); + reader.releaseLock(); + } + + break; // exit loop on normal completion + } catch (error) { + // connection failed or aborted; retry after delay + onSseError?.(error); + + if ( + sseMaxRetryAttempts !== undefined && + attempt >= sseMaxRetryAttempts + ) { + break; // stop after firing error + } + + // exponential backoff: double retry each attempt, cap at 30s + const backoff = Math.min( + retryDelay * 2 ** (attempt - 1), + sseMaxRetryDelay ?? 30000, + ); + await sleep(backoff); + } + } + }; + + const stream = createStream(); + + return { stream }; +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/core/types.gen.ts b/src/Umbraco.Web.UI.Login/src/api/core/types.gen.ts new file mode 100644 index 0000000000..643c070c9d --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/core/types.gen.ts @@ -0,0 +1,118 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Auth, AuthToken } from './auth.gen'; +import type { + BodySerializer, + QuerySerializer, + QuerySerializerOptions, +} from './bodySerializer.gen'; + +export type HttpMethod = + | 'connect' + | 'delete' + | 'get' + | 'head' + | 'options' + | 'patch' + | 'post' + | 'put' + | 'trace'; + +export type Client< + RequestFn = never, + Config = unknown, + MethodFn = never, + BuildUrlFn = never, + SseFn = never, +> = { + /** + * Returns the final request URL. + */ + buildUrl: BuildUrlFn; + getConfig: () => Config; + request: RequestFn; + setConfig: (config: Config) => Config; +} & { + [K in HttpMethod]: MethodFn; +} & ([SseFn] extends [never] + ? { sse?: never } + : { sse: { [K in HttpMethod]: SseFn } }); + +export interface Config { + /** + * Auth token or a function returning auth token. The resolved value will be + * added to the request payload as defined by its `security` array. + */ + auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken; + /** + * A function for serializing request body parameter. By default, + * {@link JSON.stringify()} will be used. + */ + bodySerializer?: BodySerializer | null; + /** + * An object containing any HTTP headers that you want to pre-populate your + * `Headers` object with. + * + * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} + */ + headers?: + | RequestInit['headers'] + | Record< + string, + | string + | number + | boolean + | (string | number | boolean)[] + | null + | undefined + | unknown + >; + /** + * The request method. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} + */ + method?: Uppercase; + /** + * A function for serializing request query parameters. By default, arrays + * will be exploded in form style, objects will be exploded in deepObject + * style, and reserved characters are percent-encoded. + * + * This method will have no effect if the native `paramsSerializer()` Axios + * API function is used. + * + * {@link https://swagger.io/docs/specification/serialization/#query View examples} + */ + querySerializer?: QuerySerializer | QuerySerializerOptions; + /** + * A function validating request data. This is useful if you want to ensure + * the request conforms to the desired shape, so it can be safely sent to + * the server. + */ + requestValidator?: (data: unknown) => Promise; + /** + * A function transforming response data before it's returned. This is useful + * for post-processing data, e.g. converting ISO strings into Date objects. + */ + responseTransformer?: (data: unknown) => Promise; + /** + * A function validating response data. This is useful if you want to ensure + * the response conforms to the desired shape, so it can be safely passed to + * the transformers and returned to the user. + */ + responseValidator?: (data: unknown) => Promise; +} + +type IsExactlyNeverOrNeverUndefined = [T] extends [never] + ? true + : [T] extends [never | undefined] + ? [undefined] extends [T] + ? false + : true + : false; + +export type OmitNever> = { + [K in keyof T as IsExactlyNeverOrNeverUndefined extends true + ? never + : K]: T[K]; +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/core/utils.gen.ts b/src/Umbraco.Web.UI.Login/src/api/core/utils.gen.ts new file mode 100644 index 0000000000..ac31396fea --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/core/utils.gen.ts @@ -0,0 +1,114 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { QuerySerializer } from './bodySerializer.gen'; +import { + type ArraySeparatorStyle, + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from './pathSerializer.gen'; + +export interface PathSerializer { + path: Record; + url: string; +} + +export const PATH_PARAM_RE = /\{[^{}]+\}/g; + +export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { + let url = _url; + const matches = _url.match(PATH_PARAM_RE); + if (matches) { + for (const match of matches) { + let explode = false; + let name = match.substring(1, match.length - 1); + let style: ArraySeparatorStyle = 'simple'; + + if (name.endsWith('*')) { + explode = true; + name = name.substring(0, name.length - 1); + } + + if (name.startsWith('.')) { + name = name.substring(1); + style = 'label'; + } else if (name.startsWith(';')) { + name = name.substring(1); + style = 'matrix'; + } + + const value = path[name]; + + if (value === undefined || value === null) { + continue; + } + + if (Array.isArray(value)) { + url = url.replace( + match, + serializeArrayParam({ explode, name, style, value }), + ); + continue; + } + + if (typeof value === 'object') { + url = url.replace( + match, + serializeObjectParam({ + explode, + name, + style, + value: value as Record, + valueOnly: true, + }), + ); + continue; + } + + if (style === 'matrix') { + url = url.replace( + match, + `;${serializePrimitiveParam({ + name, + value: value as string, + })}`, + ); + continue; + } + + const replaceValue = encodeURIComponent( + style === 'label' ? `.${value as string}` : (value as string), + ); + url = url.replace(match, replaceValue); + } + } + return url; +}; + +export const getUrl = ({ + baseUrl, + path, + query, + querySerializer, + url: _url, +}: { + baseUrl?: string; + path?: Record; + query?: Record; + querySerializer: QuerySerializer; + url: string; +}) => { + const pathUrl = _url.startsWith('/') ? _url : `/${_url}`; + let url = (baseUrl ?? '') + pathUrl; + if (path) { + url = defaultPathSerializer({ path, url }); + } + let search = query ? querySerializer(query) : ''; + if (search.startsWith('?')) { + search = search.substring(1); + } + if (search) { + url += `?${search}`; + } + return url; +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/sdk.gen.ts b/src/Umbraco.Web.UI.Login/src/api/sdk.gen.ts index c780cbdccb..a1f8a830f3 100644 --- a/src/Umbraco.Web.UI.Login/src/api/sdk.gen.ts +++ b/src/Umbraco.Web.UI.Login/src/api/sdk.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts -import type { Options as ClientOptions, TDataShape, Client } from '@hey-api/client-fetch'; -import type { GetSecurityConfigurationData, GetSecurityConfigurationResponse, PostSecurityForgotPasswordData, PostSecurityForgotPasswordError, PostSecurityForgotPasswordResetData, PostSecurityForgotPasswordResetResponse, PostSecurityForgotPasswordResetError, PostSecurityForgotPasswordVerifyData, PostSecurityForgotPasswordVerifyResponse, PostSecurityForgotPasswordVerifyError, PostUserInviteData, PostUserInviteError, PostUserInviteCreatePasswordData, PostUserInviteCreatePasswordError, PostUserInviteResendData, PostUserInviteResendError, PostUserInviteVerifyData, PostUserInviteVerifyResponse, PostUserInviteVerifyError } from './types.gen'; +import type { Options as ClientOptions, TDataShape, Client } from './client'; +import type { PostSecurityForgotPasswordData, PostSecurityForgotPasswordResponses, PostSecurityForgotPasswordErrors, PostSecurityForgotPasswordResetData, PostSecurityForgotPasswordResetResponses, PostSecurityForgotPasswordResetErrors, PostSecurityForgotPasswordVerifyData, PostSecurityForgotPasswordVerifyResponses, PostSecurityForgotPasswordVerifyErrors, PostUserInviteCreatePasswordData, PostUserInviteCreatePasswordResponses, PostUserInviteCreatePasswordErrors, PostUserInviteVerifyData, PostUserInviteVerifyResponses, PostUserInviteVerifyErrors } from './types.gen'; import { client as _heyApiClient } from './client.gen'; export type Options = ClientOptions & { @@ -18,21 +18,8 @@ export type Options; }; -export const getSecurityConfiguration = (options?: Options) => { - return (options?.client ?? _heyApiClient).get({ - security: [ - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/umbraco/management/api/v1/security/configuration', - ...options - }); -}; - export const postSecurityForgotPassword = (options?: Options) => { - return (options?.client ?? _heyApiClient).post({ + return (options?.client ?? _heyApiClient).post({ security: [ { scheme: 'bearer', @@ -49,7 +36,7 @@ export const postSecurityForgotPassword = }; export const postSecurityForgotPasswordReset = (options?: Options) => { - return (options?.client ?? _heyApiClient).post({ + return (options?.client ?? _heyApiClient).post({ security: [ { scheme: 'bearer', @@ -66,7 +53,7 @@ export const postSecurityForgotPasswordReset = (options?: Options) => { - return (options?.client ?? _heyApiClient).post({ + return (options?.client ?? _heyApiClient).post({ url: '/umbraco/management/api/v1/security/forgot-password/verify', ...options, headers: { @@ -76,25 +63,8 @@ export const postSecurityForgotPasswordVerify = (options?: Options) => { - return (options?.client ?? _heyApiClient).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/umbraco/management/api/v1/user/invite', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options?.headers - } - }); -}; - export const postUserInviteCreatePassword = (options?: Options) => { - return (options?.client ?? _heyApiClient).post({ + return (options?.client ?? _heyApiClient).post({ url: '/umbraco/management/api/v1/user/invite/create-password', ...options, headers: { @@ -104,25 +74,8 @@ export const postUserInviteCreatePassword = (options?: Options) => { - return (options?.client ?? _heyApiClient).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/umbraco/management/api/v1/user/invite/resend', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options?.headers - } - }); -}; - export const postUserInviteVerify = (options?: Options) => { - return (options?.client ?? _heyApiClient).post({ + return (options?.client ?? _heyApiClient).post({ url: '/umbraco/management/api/v1/user/invite/verify', ...options, headers: { diff --git a/src/Umbraco.Web.UI.Login/src/api/types.gen.ts b/src/Umbraco.Web.UI.Login/src/api/types.gen.ts index aad460ad8c..0171a9aa07 100644 --- a/src/Umbraco.Web.UI.Login/src/api/types.gen.ts +++ b/src/Umbraco.Web.UI.Login/src/api/types.gen.ts @@ -1,28 +1,16 @@ // This file is auto-generated by @hey-api/openapi-ts -export type CreateInitialPasswordUserRequestModel = { +export type VerifyResetPasswordTokenRequestModel = { user: ReferenceByIdModel; - token: string; - password: string; + resetCode: string; }; -export type InviteUserRequestModel = { - email: string; - userName: string; - name: string; - userGroupIds: Array; - id?: string | null; - message?: string | null; +export type ReferenceByIdModel = { + id: string; }; -export type PagedProblemDetailsModel = { - total: number; - items: Array; -}; - -export type PagedReferenceByIdModel = { - total: number; - items: Array; +export type VerifyResetPasswordResponseModel = { + passwordConfiguration: PasswordConfigurationResponseModel; }; export type PasswordConfigurationResponseModel = { @@ -33,6 +21,29 @@ export type PasswordConfigurationResponseModel = { requireUppercase: boolean; }; +export type VerifyInviteUserResponseModel = { + passwordConfiguration: PasswordConfigurationResponseModel; +}; + +export type VerifyInviteUserRequestModel = { + user: ReferenceByIdModel; + token: string; +}; + +export type ResetPasswordTokenRequestModel = { + user: ReferenceByIdModel; + resetCode: string; + password: string; +}; + +export type ResetPasswordRequestModel = { + email: string; +}; + +export type ProblemDetailsBuilderModel = { + [key: string]: never; +}; + export type ProblemDetails = { type?: string | null; title?: string | null; @@ -42,82 +53,26 @@ export type ProblemDetails = { [key: string]: unknown | (string | null) | (string | null) | (number | null) | (string | null) | (string | null) | undefined; }; -export type ProblemDetailsBuilderModel = { - [key: string]: never; +export type NotificationHeaderModel = { + message: string; + category: string; + type: EventMessageTypeModel; }; -export type ReferenceByIdModel = { - id: string; -}; +export enum EventMessageTypeModel { + DEFAULT = 'Default', + INFO = 'Info', + ERROR = 'Error', + SUCCESS = 'Success', + WARNING = 'Warning' +} -export type ResendInviteUserRequestModel = { - user: ReferenceByIdModel; - message?: string | null; -}; - -export type ResetPasswordRequestModel = { - email: string; -}; - -export type ResetPasswordTokenRequestModel = { - user: ReferenceByIdModel; - resetCode: string; - password: string; -}; - -export type ResetPasswordUserResponseModel = { - resetPassword?: string | null; -}; - -export type SecurityConfigurationResponseModel = { - passwordConfiguration: PasswordConfigurationResponseModel; -}; - -export type VerifyInviteUserRequestModel = { +export type CreateInitialPasswordUserRequestModel = { user: ReferenceByIdModel; token: string; + password: string; }; -export type VerifyInviteUserResponseModel = { - passwordConfiguration: PasswordConfigurationResponseModel; -}; - -export type VerifyResetPasswordResponseModel = { - passwordConfiguration: PasswordConfigurationResponseModel; -}; - -export type VerifyResetPasswordTokenRequestModel = { - user: ReferenceByIdModel; - resetCode: string; -}; - -export type GetSecurityConfigurationData = { - body?: never; - path?: never; - query?: never; - url: '/umbraco/management/api/v1/security/configuration'; -}; - -export type GetSecurityConfigurationErrors = { - /** - * The resource is protected and requires an authentication token - */ - 401: unknown; - /** - * The authenticated user does not have access to this resource - */ - 403: unknown; -}; - -export type GetSecurityConfigurationResponses = { - /** - * OK - */ - 200: SecurityConfigurationResponseModel; -}; - -export type GetSecurityConfigurationResponse = GetSecurityConfigurationResponses[keyof GetSecurityConfigurationResponses]; - export type PostSecurityForgotPasswordData = { body?: ResetPasswordRequestModel; path?: never; @@ -215,41 +170,6 @@ export type PostSecurityForgotPasswordVerifyResponses = { export type PostSecurityForgotPasswordVerifyResponse = PostSecurityForgotPasswordVerifyResponses[keyof PostSecurityForgotPasswordVerifyResponses]; -export type PostUserInviteData = { - body?: InviteUserRequestModel; - path?: never; - query?: never; - url: '/umbraco/management/api/v1/user/invite'; -}; - -export type PostUserInviteErrors = { - /** - * Bad Request - */ - 400: ProblemDetails; - /** - * The resource is protected and requires an authentication token - */ - 401: unknown; - /** - * The authenticated user does not have access to this resource - */ - 403: unknown; - /** - * Not Found - */ - 404: ProblemDetails; -}; - -export type PostUserInviteError = PostUserInviteErrors[keyof PostUserInviteErrors]; - -export type PostUserInviteResponses = { - /** - * Created - */ - 201: unknown; -}; - export type PostUserInviteCreatePasswordData = { body?: CreateInitialPasswordUserRequestModel; path?: never; @@ -281,41 +201,6 @@ export type PostUserInviteCreatePasswordResponses = { 200: unknown; }; -export type PostUserInviteResendData = { - body?: ResendInviteUserRequestModel; - path?: never; - query?: never; - url: '/umbraco/management/api/v1/user/invite/resend'; -}; - -export type PostUserInviteResendErrors = { - /** - * Bad Request - */ - 400: ProblemDetails; - /** - * The resource is protected and requires an authentication token - */ - 401: unknown; - /** - * The authenticated user does not have access to this resource - */ - 403: unknown; - /** - * Not Found - */ - 404: ProblemDetails; -}; - -export type PostUserInviteResendError = PostUserInviteResendErrors[keyof PostUserInviteResendErrors]; - -export type PostUserInviteResendResponses = { - /** - * OK - */ - 200: unknown; -}; - export type PostUserInviteVerifyData = { body?: VerifyInviteUserRequestModel; path?: never; diff --git a/src/Umbraco.Web.UI.Login/src/contexts/auth.repository.ts b/src/Umbraco.Web.UI.Login/src/contexts/auth.repository.ts index 202ab042fe..bce27e852f 100644 --- a/src/Umbraco.Web.UI.Login/src/contexts/auth.repository.ts +++ b/src/Umbraco.Web.UI.Login/src/contexts/auth.repository.ts @@ -14,9 +14,9 @@ import { postUserInviteCreatePassword, postUserInviteVerify, } from '../api/index.js'; -import { isProblemDetails } from '../utils/is-problem-details.function.js'; import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api'; +import { isProblemDetailsLike } from '@umbraco-cms/backoffice/resources'; export class UmbAuthRepository extends UmbRepositoryBase { #localize = new UmbLocalizationController(this); @@ -195,7 +195,7 @@ export class UmbAuthRepository extends UmbRepositoryBase { } #getApiErrorDetailText(error: unknown, fallbackText?: string): string | undefined { - if (isProblemDetails(error)) { + if (isProblemDetailsLike(error)) { return error.detail ?? error.title ?? undefined; } diff --git a/templates/UmbracoExtension/Client/package.json b/templates/UmbracoExtension/Client/package.json index 72f8ab4120..c5a5d53e2e 100644 --- a/templates/UmbracoExtension/Client/package.json +++ b/templates/UmbracoExtension/Client/package.json @@ -9,7 +9,7 @@ "generate-client": "node scripts/generate-openapi.js https://localhost:44339/umbraco/swagger/umbracoextension/swagger.json" }, "devDependencies": { - "@hey-api/openapi-ts": "^0.80.14", + "@hey-api/openapi-ts": "0.81.1", "@umbraco-cms/backoffice": "^UMBRACO_VERSION_FROM_TEMPLATE", "chalk": "^5.6.0", "cross-env": "^10.0.0", @@ -17,4 +17,4 @@ "typescript": "^5.9.2", "vite": "^7.1.3" } -} +} \ No newline at end of file diff --git a/templates/UmbracoExtension/Client/scripts/generate-openapi.js b/templates/UmbracoExtension/Client/scripts/generate-openapi.js index c54afa56f9..4df6ca1483 100644 --- a/templates/UmbracoExtension/Client/scripts/generate-openapi.js +++ b/templates/UmbracoExtension/Client/scripts/generate-openapi.js @@ -32,11 +32,11 @@ fetch(swaggerUrl).then(async (response) => { console.log(`Calling ${chalk.yellow('hey-api')} to generate TypeScript client`); await createClient({ - client: '@hey-api/client-fetch', input: swaggerUrl, output: 'src/api', plugins: [ ...defaultPlugins, + '@hey-api/client-fetch', { name: '@hey-api/sdk', asClass: true, diff --git a/templates/UmbracoExtension/Client/src/api/client/client.gen.ts b/templates/UmbracoExtension/Client/src/api/client/client.gen.ts index 0c606b81c6..0c60a9ab77 100644 --- a/templates/UmbracoExtension/Client/src/api/client/client.gen.ts +++ b/templates/UmbracoExtension/Client/src/api/client/client.gen.ts @@ -1,6 +1,13 @@ // This file is auto-generated by @hey-api/openapi-ts -import type { Client, Config, ResolvedRequestOptions } from './types.gen'; +import { createSseClient } from '../core/serverSentEvents.gen'; +import type { HttpMethod } from '../core/types.gen'; +import type { + Client, + Config, + RequestOptions, + ResolvedRequestOptions, +} from './types.gen'; import { buildUrl, createConfig, @@ -33,7 +40,7 @@ export const createClient = (config: Config = {}): Client => { ResolvedRequestOptions >(); - const request: Client['request'] = async (options) => { + const beforeRequest = async (options: RequestOptions) => { const opts = { ..._config, ...options, @@ -63,6 +70,13 @@ export const createClient = (config: Config = {}): Client => { } const url = buildUrl(opts); + + return { opts, url }; + }; + + const request: Client['request'] = async (options) => { + // @ts-expect-error + const { opts, url } = await beforeRequest(options); const requestInit: ReqInit = { redirect: 'follow', ...opts, @@ -180,20 +194,47 @@ export const createClient = (config: Config = {}): Client => { }; }; + const makeMethodFn = + (method: Uppercase) => (options: RequestOptions) => + request({ ...options, method }); + + const makeSseFn = + (method: Uppercase) => async (options: RequestOptions) => { + const { opts, url } = await beforeRequest(options); + return createSseClient({ + ...opts, + body: opts.body as BodyInit | null | undefined, + headers: opts.headers as unknown as Record, + method, + url, + }); + }; + return { buildUrl, - connect: (options) => request({ ...options, method: 'CONNECT' }), - delete: (options) => request({ ...options, method: 'DELETE' }), - get: (options) => request({ ...options, method: 'GET' }), + connect: makeMethodFn('CONNECT'), + delete: makeMethodFn('DELETE'), + get: makeMethodFn('GET'), getConfig, - head: (options) => request({ ...options, method: 'HEAD' }), + head: makeMethodFn('HEAD'), interceptors, - options: (options) => request({ ...options, method: 'OPTIONS' }), - patch: (options) => request({ ...options, method: 'PATCH' }), - post: (options) => request({ ...options, method: 'POST' }), - put: (options) => request({ ...options, method: 'PUT' }), + options: makeMethodFn('OPTIONS'), + patch: makeMethodFn('PATCH'), + post: makeMethodFn('POST'), + put: makeMethodFn('PUT'), request, setConfig, - trace: (options) => request({ ...options, method: 'TRACE' }), - }; + sse: { + connect: makeSseFn('CONNECT'), + delete: makeSseFn('DELETE'), + get: makeSseFn('GET'), + head: makeSseFn('HEAD'), + options: makeSseFn('OPTIONS'), + patch: makeSseFn('PATCH'), + post: makeSseFn('POST'), + put: makeSseFn('PUT'), + trace: makeSseFn('TRACE'), + }, + trace: makeMethodFn('TRACE'), + } as Client; }; diff --git a/templates/UmbracoExtension/Client/src/api/client/types.gen.ts b/templates/UmbracoExtension/Client/src/api/client/types.gen.ts index 2a123be9a1..5bde93851e 100644 --- a/templates/UmbracoExtension/Client/src/api/client/types.gen.ts +++ b/templates/UmbracoExtension/Client/src/api/client/types.gen.ts @@ -1,6 +1,10 @@ // This file is auto-generated by @hey-api/openapi-ts import type { Auth } from '../core/auth.gen'; +import type { + ServerSentEventsOptions, + ServerSentEventsResult, +} from '../core/serverSentEvents.gen'; import type { Client as CoreClient, Config as CoreConfig, @@ -61,13 +65,22 @@ export interface Config } export interface RequestOptions< + TData = unknown, TResponseStyle extends ResponseStyle = 'fields', ThrowOnError extends boolean = boolean, Url extends string = string, > extends Config<{ - responseStyle: TResponseStyle; - throwOnError: ThrowOnError; - }> { + responseStyle: TResponseStyle; + throwOnError: ThrowOnError; + }>, + Pick< + ServerSentEventsOptions, + | 'onSseError' + | 'onSseEvent' + | 'sseDefaultRetryDelay' + | 'sseMaxRetryAttempts' + | 'sseMaxRetryDelay' + > { /** * Any body that you want to add to your request. * @@ -87,7 +100,7 @@ export interface ResolvedRequestOptions< TResponseStyle extends ResponseStyle = 'fields', ThrowOnError extends boolean = boolean, Url extends string = string, -> extends RequestOptions { +> extends RequestOptions { serializedBody?: string; } @@ -148,17 +161,29 @@ type MethodFn = < ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields', >( - options: Omit, 'method'>, + options: Omit, 'method'>, ) => RequestResult; +type SseFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'>, +) => Promise>; + type RequestFn = < TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields', >( - options: Omit, 'method'> & - Pick>, 'method'>, + options: Omit, 'method'> & + Pick< + Required>, + 'method' + >, ) => RequestResult; type BuildUrlFn = < @@ -172,7 +197,13 @@ type BuildUrlFn = < options: Pick & Options, ) => string; -export type Client = CoreClient & { +export type Client = CoreClient< + RequestFn, + Config, + MethodFn, + BuildUrlFn, + SseFn +> & { interceptors: Middleware; }; @@ -201,9 +232,10 @@ type OmitKeys = Pick>; export type Options< TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, + TResponse = unknown, TResponseStyle extends ResponseStyle = 'fields', > = OmitKeys< - RequestOptions, + RequestOptions, 'body' | 'path' | 'query' | 'url' > & Omit; @@ -215,18 +247,22 @@ export type OptionsLegacyParser< > = TData extends { body?: any } ? TData extends { headers?: any } ? OmitKeys< - RequestOptions, + RequestOptions, 'body' | 'headers' | 'url' > & TData - : OmitKeys, 'body' | 'url'> & + : OmitKeys< + RequestOptions, + 'body' | 'url' + > & TData & - Pick, 'headers'> + Pick, 'headers'> : TData extends { headers?: any } ? OmitKeys< - RequestOptions, + RequestOptions, 'headers' | 'url' > & TData & - Pick, 'body'> - : OmitKeys, 'url'> & TData; + Pick, 'body'> + : OmitKeys, 'url'> & + TData; diff --git a/templates/UmbracoExtension/Client/src/api/client/utils.gen.ts b/templates/UmbracoExtension/Client/src/api/client/utils.gen.ts index 6d82364ef8..a47509522b 100644 --- a/templates/UmbracoExtension/Client/src/api/client/utils.gen.ts +++ b/templates/UmbracoExtension/Client/src/api/client/utils.gen.ts @@ -1,99 +1,16 @@ // This file is auto-generated by @hey-api/openapi-ts import { getAuthToken } from '../core/auth.gen'; -import type { - QuerySerializer, - QuerySerializerOptions, -} from '../core/bodySerializer.gen'; +import type { QuerySerializerOptions } from '../core/bodySerializer.gen'; import { jsonBodySerializer } from '../core/bodySerializer.gen'; import { serializeArrayParam, serializeObjectParam, serializePrimitiveParam, } from '../core/pathSerializer.gen'; +import { getUrl } from '../core/utils.gen'; import type { Client, ClientOptions, Config, RequestOptions } from './types.gen'; -interface PathSerializer { - path: Record; - url: string; -} - -const PATH_PARAM_RE = /\{[^{}]+\}/g; - -type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited'; -type MatrixStyle = 'label' | 'matrix' | 'simple'; -type ArraySeparatorStyle = ArrayStyle | MatrixStyle; - -const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { - let url = _url; - const matches = _url.match(PATH_PARAM_RE); - if (matches) { - for (const match of matches) { - let explode = false; - let name = match.substring(1, match.length - 1); - let style: ArraySeparatorStyle = 'simple'; - - if (name.endsWith('*')) { - explode = true; - name = name.substring(0, name.length - 1); - } - - if (name.startsWith('.')) { - name = name.substring(1); - style = 'label'; - } else if (name.startsWith(';')) { - name = name.substring(1); - style = 'matrix'; - } - - const value = path[name]; - - if (value === undefined || value === null) { - continue; - } - - if (Array.isArray(value)) { - url = url.replace( - match, - serializeArrayParam({ explode, name, style, value }), - ); - continue; - } - - if (typeof value === 'object') { - url = url.replace( - match, - serializeObjectParam({ - explode, - name, - style, - value: value as Record, - valueOnly: true, - }), - ); - continue; - } - - if (style === 'matrix') { - url = url.replace( - match, - `;${serializePrimitiveParam({ - name, - value: value as string, - })}`, - ); - continue; - } - - const replaceValue = encodeURIComponent( - style === 'label' ? `.${value as string}` : (value as string), - ); - url = url.replace(match, replaceValue); - } - } - return url; -}; - export const createQuerySerializer = ({ allowReserved, array, @@ -188,6 +105,25 @@ export const getParseAs = ( return; }; +const checkForExistence = ( + options: Pick & { + headers: Headers; + }, + name?: string, +): boolean => { + if (!name) { + return false; + } + if ( + options.headers.has(name) || + options.query?.[name] || + options.headers.get('Cookie')?.includes(`${name}=`) + ) { + return true; + } + return false; +}; + export const setAuthParams = async ({ security, ...options @@ -196,6 +132,10 @@ export const setAuthParams = async ({ headers: Headers; }) => { for (const auth of security) { + if (checkForExistence(options, auth.name)) { + continue; + } + const token = await getAuthToken(auth, options.auth); if (!token) { @@ -219,13 +159,11 @@ export const setAuthParams = async ({ options.headers.set(name, token); break; } - - return; } }; -export const buildUrl: Client['buildUrl'] = (options) => { - const url = getUrl({ +export const buildUrl: Client['buildUrl'] = (options) => + getUrl({ baseUrl: options.baseUrl as string, path: options.path, query: options.query, @@ -235,36 +173,6 @@ export const buildUrl: Client['buildUrl'] = (options) => { : createQuerySerializer(options.querySerializer), url: options.url, }); - return url; -}; - -export const getUrl = ({ - baseUrl, - path, - query, - querySerializer, - url: _url, -}: { - baseUrl?: string; - path?: Record; - query?: Record; - querySerializer: QuerySerializer; - url: string; -}) => { - const pathUrl = _url.startsWith('/') ? _url : `/${_url}`; - let url = (baseUrl ?? '') + pathUrl; - if (path) { - url = defaultPathSerializer({ path, url }); - } - let search = query ? querySerializer(query) : ''; - if (search.startsWith('?')) { - search = search.substring(1); - } - if (search) { - url += `?${search}`; - } - return url; -}; export const mergeConfigs = (a: Config, b: Config): Config => { const config = { ...a, ...b }; diff --git a/templates/UmbracoExtension/Client/src/api/core/serverSentEvents.gen.ts b/templates/UmbracoExtension/Client/src/api/core/serverSentEvents.gen.ts new file mode 100644 index 0000000000..01b5818fdf --- /dev/null +++ b/templates/UmbracoExtension/Client/src/api/core/serverSentEvents.gen.ts @@ -0,0 +1,237 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Config } from './types.gen'; + +export type ServerSentEventsOptions = Omit< + RequestInit, + 'method' +> & + Pick & { + /** + * Callback invoked when a network or parsing error occurs during streaming. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param error The error that occurred. + */ + onSseError?: (error: unknown) => void; + /** + * Callback invoked when an event is streamed from the server. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param event Event streamed from the server. + * @returns Nothing (void). + */ + onSseEvent?: (event: StreamEvent) => void; + /** + * Default retry delay in milliseconds. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 3000 + */ + sseDefaultRetryDelay?: number; + /** + * Maximum number of retry attempts before giving up. + */ + sseMaxRetryAttempts?: number; + /** + * Maximum retry delay in milliseconds. + * + * Applies only when exponential backoff is used. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 30000 + */ + sseMaxRetryDelay?: number; + /** + * Optional sleep function for retry backoff. + * + * Defaults to using `setTimeout`. + */ + sseSleepFn?: (ms: number) => Promise; + url: string; + }; + +export interface StreamEvent { + data: TData; + event?: string; + id?: string; + retry?: number; +} + +export type ServerSentEventsResult< + TData = unknown, + TReturn = void, + TNext = unknown, +> = { + stream: AsyncGenerator< + TData extends Record ? TData[keyof TData] : TData, + TReturn, + TNext + >; +}; + +export const createSseClient = ({ + onSseError, + onSseEvent, + responseTransformer, + responseValidator, + sseDefaultRetryDelay, + sseMaxRetryAttempts, + sseMaxRetryDelay, + sseSleepFn, + url, + ...options +}: ServerSentEventsOptions): ServerSentEventsResult => { + let lastEventId: string | undefined; + + const sleep = + sseSleepFn ?? + ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))); + + const createStream = async function* () { + let retryDelay: number = sseDefaultRetryDelay ?? 3000; + let attempt = 0; + const signal = options.signal ?? new AbortController().signal; + + while (true) { + if (signal.aborted) break; + + attempt++; + + const headers = + options.headers instanceof Headers + ? options.headers + : new Headers(options.headers as Record | undefined); + + if (lastEventId !== undefined) { + headers.set('Last-Event-ID', lastEventId); + } + + try { + const response = await fetch(url, { ...options, headers, signal }); + + if (!response.ok) + throw new Error( + `SSE failed: ${response.status} ${response.statusText}`, + ); + + if (!response.body) throw new Error('No body in SSE response'); + + const reader = response.body + .pipeThrough(new TextDecoderStream()) + .getReader(); + + let buffer = ''; + + const abortHandler = () => { + try { + reader.cancel(); + } catch { + // noop + } + }; + + signal.addEventListener('abort', abortHandler); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + buffer += value; + + const chunks = buffer.split('\n\n'); + buffer = chunks.pop() ?? ''; + + for (const chunk of chunks) { + const lines = chunk.split('\n'); + const dataLines: Array = []; + let eventName: string | undefined; + + for (const line of lines) { + if (line.startsWith('data:')) { + dataLines.push(line.replace(/^data:\s*/, '')); + } else if (line.startsWith('event:')) { + eventName = line.replace(/^event:\s*/, ''); + } else if (line.startsWith('id:')) { + lastEventId = line.replace(/^id:\s*/, ''); + } else if (line.startsWith('retry:')) { + const parsed = Number.parseInt( + line.replace(/^retry:\s*/, ''), + 10, + ); + if (!Number.isNaN(parsed)) { + retryDelay = parsed; + } + } + } + + let data: unknown; + let parsedJson = false; + + if (dataLines.length) { + const rawData = dataLines.join('\n'); + try { + data = JSON.parse(rawData); + parsedJson = true; + } catch { + data = rawData; + } + } + + if (parsedJson) { + if (responseValidator) { + await responseValidator(data); + } + + if (responseTransformer) { + data = await responseTransformer(data); + } + } + + onSseEvent?.({ + data, + event: eventName, + id: lastEventId, + retry: retryDelay, + }); + + if (dataLines.length) { + yield data as any; + } + } + } + } finally { + signal.removeEventListener('abort', abortHandler); + reader.releaseLock(); + } + + break; // exit loop on normal completion + } catch (error) { + // connection failed or aborted; retry after delay + onSseError?.(error); + + if ( + sseMaxRetryAttempts !== undefined && + attempt >= sseMaxRetryAttempts + ) { + break; // stop after firing error + } + + // exponential backoff: double retry each attempt, cap at 30s + const backoff = Math.min( + retryDelay * 2 ** (attempt - 1), + sseMaxRetryDelay ?? 30000, + ); + await sleep(backoff); + } + } + }; + + const stream = createStream(); + + return { stream }; +}; diff --git a/templates/UmbracoExtension/Client/src/api/core/types.gen.ts b/templates/UmbracoExtension/Client/src/api/core/types.gen.ts index 5bfae35c0a..643c070c9d 100644 --- a/templates/UmbracoExtension/Client/src/api/core/types.gen.ts +++ b/templates/UmbracoExtension/Client/src/api/core/types.gen.ts @@ -7,29 +7,36 @@ import type { QuerySerializerOptions, } from './bodySerializer.gen'; -export interface Client< +export type HttpMethod = + | 'connect' + | 'delete' + | 'get' + | 'head' + | 'options' + | 'patch' + | 'post' + | 'put' + | 'trace'; + +export type Client< RequestFn = never, Config = unknown, MethodFn = never, BuildUrlFn = never, -> { + SseFn = never, +> = { /** * Returns the final request URL. */ buildUrl: BuildUrlFn; - connect: MethodFn; - delete: MethodFn; - get: MethodFn; getConfig: () => Config; - head: MethodFn; - options: MethodFn; - patch: MethodFn; - post: MethodFn; - put: MethodFn; request: RequestFn; setConfig: (config: Config) => Config; - trace: MethodFn; -} +} & { + [K in HttpMethod]: MethodFn; +} & ([SseFn] extends [never] + ? { sse?: never } + : { sse: { [K in HttpMethod]: SseFn } }); export interface Config { /** @@ -65,16 +72,7 @@ export interface Config { * * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} */ - method?: - | 'CONNECT' - | 'DELETE' - | 'GET' - | 'HEAD' - | 'OPTIONS' - | 'PATCH' - | 'POST' - | 'PUT' - | 'TRACE'; + method?: Uppercase; /** * A function for serializing request query parameters. By default, arrays * will be exploded in form style, objects will be exploded in deepObject diff --git a/templates/UmbracoExtension/Client/src/api/core/utils.gen.ts b/templates/UmbracoExtension/Client/src/api/core/utils.gen.ts new file mode 100644 index 0000000000..ac31396fea --- /dev/null +++ b/templates/UmbracoExtension/Client/src/api/core/utils.gen.ts @@ -0,0 +1,114 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { QuerySerializer } from './bodySerializer.gen'; +import { + type ArraySeparatorStyle, + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from './pathSerializer.gen'; + +export interface PathSerializer { + path: Record; + url: string; +} + +export const PATH_PARAM_RE = /\{[^{}]+\}/g; + +export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { + let url = _url; + const matches = _url.match(PATH_PARAM_RE); + if (matches) { + for (const match of matches) { + let explode = false; + let name = match.substring(1, match.length - 1); + let style: ArraySeparatorStyle = 'simple'; + + if (name.endsWith('*')) { + explode = true; + name = name.substring(0, name.length - 1); + } + + if (name.startsWith('.')) { + name = name.substring(1); + style = 'label'; + } else if (name.startsWith(';')) { + name = name.substring(1); + style = 'matrix'; + } + + const value = path[name]; + + if (value === undefined || value === null) { + continue; + } + + if (Array.isArray(value)) { + url = url.replace( + match, + serializeArrayParam({ explode, name, style, value }), + ); + continue; + } + + if (typeof value === 'object') { + url = url.replace( + match, + serializeObjectParam({ + explode, + name, + style, + value: value as Record, + valueOnly: true, + }), + ); + continue; + } + + if (style === 'matrix') { + url = url.replace( + match, + `;${serializePrimitiveParam({ + name, + value: value as string, + })}`, + ); + continue; + } + + const replaceValue = encodeURIComponent( + style === 'label' ? `.${value as string}` : (value as string), + ); + url = url.replace(match, replaceValue); + } + } + return url; +}; + +export const getUrl = ({ + baseUrl, + path, + query, + querySerializer, + url: _url, +}: { + baseUrl?: string; + path?: Record; + query?: Record; + querySerializer: QuerySerializer; + url: string; +}) => { + const pathUrl = _url.startsWith('/') ? _url : `/${_url}`; + let url = (baseUrl ?? '') + pathUrl; + if (path) { + url = defaultPathSerializer({ path, url }); + } + let search = query ? querySerializer(query) : ''; + if (search.startsWith('?')) { + search = search.substring(1); + } + if (search) { + url += `?${search}`; + } + return url; +}; From ae8411ed7b388eb8f7d9d8d105202db41ad5ed96 Mon Sep 17 00:00:00 2001 From: NguyenThuyLan <116753400+NguyenThuyLan@users.noreply.github.com> Date: Tue, 26 Aug 2025 20:32:34 +0700 Subject: [PATCH 15/33] Tiptap RTE: Toolbar configuration sorter (#19901) * Fix issue dragging tiptap toolbar buttons * Moved the `.items` CSS rules to the group element * Refactored the toolbar-group element - Renamed "toolbar-item-click" event to "remove", to show intent - Reordered the method names alphabetically - Renamed `value` to `items`, to show intent - Removed `toolbarValue`, as not required - Added `data-mark` for menu/styleMenu buttons * Renamed/relocated "umb-tiptap-toolbar-group-configuration" element * Updated tag name --------- Co-authored-by: Lan Nguyen Thuy Co-authored-by: leekelleher --- ...ui-tiptap-toolbar-configuration.element.ts | 131 +++---------- ...tap-toolbar-group-configuration.element.ts | 177 ++++++++++++++++++ .../tiptap-toolbar-configuration.context.ts | 21 +++ 3 files changed, 225 insertions(+), 104 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/components/tiptap-toolbar-group-configuration.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/components/property-editor-ui-tiptap-toolbar-configuration.element.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/components/property-editor-ui-tiptap-toolbar-configuration.element.ts index 651f386b2f..111ea1a4a2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/components/property-editor-ui-tiptap-toolbar-configuration.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/components/property-editor-ui-tiptap-toolbar-configuration.element.ts @@ -5,12 +5,15 @@ import type { UmbTiptapToolbarRowViewModel, } from '../types.js'; import type { UmbTiptapToolbarValue } from '../../../components/types.js'; +import type { UmbTiptapToolbarGroupConfigurationElement } from './tiptap-toolbar-group-configuration.element.js'; import { customElement, css, html, property, repeat, state, when, nothing } from '@umbraco-cms/backoffice/external/lit'; import { debounce } from '@umbraco-cms/backoffice/utils'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/property-editor'; +import './tiptap-toolbar-group-configuration.element.js'; + @customElement('umb-property-editor-ui-tiptap-toolbar-configuration') export class UmbPropertyEditorUiTiptapToolbarConfigurationElement extends UmbLitElement @@ -74,7 +77,14 @@ export class UmbPropertyEditorUiTiptapToolbarConfigurationElement this.#initialized = true; } - #onClick(item: UmbTiptapToolbarExtension) { + #onChangeToolbarGroup(event: CustomEvent & { target: UmbTiptapToolbarGroupConfigurationElement }) { + event.stopPropagation(); + const element = event.target; + const aliases = element.items.map((item) => item.alias); + this.#context.updateToolbarItem(aliases, [element.rowIndex, element.groupIndex]); + } + + #onClickAvailableItem(item: UmbTiptapToolbarExtension) { const lastRow = (this.#value?.length ?? 1) - 1; const lastGroup = (this.#value?.[lastRow].length ?? 1) - 1; const lastItem = this.#value?.[lastRow][lastGroup].length ?? 0; @@ -128,6 +138,11 @@ export class UmbPropertyEditorUiTiptapToolbarConfigurationElement this.#debouncedFilter(query); } + #onRemoveToolbarItem(event: CustomEvent) { + const { groupIndex, index, rowIndex } = event.detail; + this.#context?.removeToolbarItem([rowIndex, groupIndex, index]); + } + override render() { return html`${this.#renderDesigner()} ${this.#renderAvailableItems()}`; } @@ -173,7 +188,7 @@ export class UmbPropertyEditorUiTiptapToolbarConfigurationElement label=${label} look=${forbidden ? 'placeholder' : 'outline'} ?disabled=${forbidden || inUse} - @click=${() => this.#onClick(item)} + @click=${() => this.#onClickAvailableItem(item)} @dragstart=${(e: DragEvent) => this.#onDragStart(e, item.alias)} @dragend=${this.#onDragEnd}>
@@ -242,19 +257,22 @@ export class UmbPropertyEditorUiTiptapToolbarConfigurationElement #renderGroup(group?: UmbTiptapToolbarGroupViewModel, rowIndex = 0, groupIndex = 0) { if (!group) return nothing; const showActionBar = this._toolbar[rowIndex].data.length > 1 && group.data.length === 0; + const items: UmbTiptapToolbarExtension[] = group!.data + .map((alias) => this.#context?.getExtensionByAlias(alias)) + .filter((item): item is UmbTiptapToolbarExtension => !!item); return html`
this.#onDrop(e, [rowIndex, groupIndex, group.data.length - 1])}> -
- ${when( - group?.data.length === 0, - () => html`Empty`, - () => html`${group!.data.map((alias, idx) => this.#renderItem(alias, rowIndex, groupIndex, idx))}`, - )} -
+ + ${when( showActionBar, () => html` @@ -276,62 +294,6 @@ export class UmbPropertyEditorUiTiptapToolbarConfigurationElement `; } - #renderItem(alias: string, rowIndex = 0, groupIndex = 0, itemIndex = 0) { - const item = this.#context?.getExtensionByAlias(alias); - if (!item) return nothing; - - const forbidden = !this.#context?.isExtensionEnabled(item.alias); - const label = this.localize.string(item.label); - - switch (item.kind) { - case 'styleMenu': - case 'menu': - return html` - this.#context.removeToolbarItem([rowIndex, groupIndex, itemIndex])} - @dragend=${this.#onDragEnd} - @dragstart=${(e: DragEvent) => this.#onDragStart(e, alias, [rowIndex, groupIndex, itemIndex])}> -
- ${label} -
- -
- `; - - case 'button': - default: - return html` - this.#context.removeToolbarItem([rowIndex, groupIndex, itemIndex])} - @dragend=${this.#onDragEnd} - @dragstart=${(e: DragEvent) => this.#onDragStart(e, alias, [rowIndex, groupIndex, itemIndex])}> -
- ${when( - item.icon, - () => html``, - () => html`${label}`, - )} -
-
- `; - } - } - static override readonly styles = [ css` :host { @@ -468,45 +430,6 @@ export class UmbPropertyEditorUiTiptapToolbarConfigurationElement opacity: 1; } } - - .items { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: var(--uui-size-1); - - uui-button { - --uui-button-font-weight: normal; - - &[draggable='true'], - &[draggable='true'] > .inner { - cursor: move; - } - - &[disabled], - &[disabled] > .inner { - cursor: not-allowed; - } - - &.forbidden { - --color: var(--uui-color-danger); - --color-standalone: var(--uui-color-danger-standalone); - --color-emphasis: var(--uui-color-danger-emphasis); - --color-contrast: var(--uui-color-danger); - --uui-button-contrast-disabled: var(--uui-color-danger); - --uui-button-border-color-disabled: var(--uui-color-danger); - } - - div { - display: flex; - gap: var(--uui-size-1); - } - - uui-symbol-expand { - margin-left: var(--uui-size-space-2); - } - } - } } } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/components/tiptap-toolbar-group-configuration.element.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/components/tiptap-toolbar-group-configuration.element.ts new file mode 100644 index 0000000000..0ec24d6fd6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/components/tiptap-toolbar-group-configuration.element.ts @@ -0,0 +1,177 @@ +import { UmbTiptapToolbarConfigurationContext } from '../contexts/tiptap-toolbar-configuration.context.js'; +import type { UmbTiptapToolbarExtension } from '../types.js'; +import { css, customElement, html, property, repeat, when } from '@umbraco-cms/backoffice/external/lit'; +import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbSorterController, UmbSorterResolvePlacementAsGrid } from '@umbraco-cms/backoffice/sorter'; + +@customElement('umb-tiptap-toolbar-group-configuration') +export class UmbTiptapToolbarGroupConfigurationElement< + TiptapToolbarItem extends UmbTiptapToolbarExtension = UmbTiptapToolbarExtension, +> extends UmbLitElement { + #sorter = new UmbSorterController(this, { + getUniqueOfElement: (element) => element.getAttribute('tiptap-toolbar-alias'), + getUniqueOfModel: (modelEntry) => modelEntry.alias!, + itemSelector: 'uui-button', + identifier: 'umb-tiptap-toolbar-sorter', + containerSelector: '.items', + resolvePlacement: UmbSorterResolvePlacementAsGrid, + onContainerChange: ({ item, model }) => { + this.dispatchEvent(new CustomEvent('container-change', { detail: { item, model } })); + }, + onChange: ({ model }) => { + this.#items = model; + this.requestUpdate(); + this.dispatchEvent(new UmbChangeEvent()); + }, + }); + + #context = new UmbTiptapToolbarConfigurationContext(this); + + @property({ type: Array, attribute: false }) + public set items(value: Array | undefined) { + this.#items = (value ?? []).filter((item, index, self) => self.findIndex((x) => x.alias === item.alias) === index); + this.#sorter.setModel(this.#items); + } + public get items(): Array { + return this.#items; + } + #items: Array = []; + + @property({ type: Number }) + rowIndex = 0; + + @property({ type: Number }) + groupIndex = 0; + + #onRequestRemove(item: TiptapToolbarItem, index = 0) { + this.items = this.items.filter((x) => x.alias !== item.alias); + const rowIndex = this.rowIndex; + const groupIndex = this.groupIndex; + this.dispatchEvent( + new CustomEvent('remove', { detail: { rowIndex, groupIndex, index }, bubbles: true, composed: true }), + ); + } + + override render() { + return html` +
+ ${when( + this.items?.length === 0, + () => html`Empty`, + () => + repeat( + this.items, + (item) => item.alias, + (item, index) => this.#renderItem(item, index), + ), + )} +
+ `; + } + + #renderItem(item: TiptapToolbarItem, index = 0) { + const label = this.localize.string(item.label); + const forbidden = !this.#context?.isExtensionEnabled(item.alias); + + switch (item.kind) { + case 'styleMenu': + case 'menu': + return html` + this.#onRequestRemove(item, index)}> +
+ ${label} +
+ +
+ `; + + case 'button': + default: + return html` + this.#onRequestRemove(item, index)}> +
+ ${when( + item.icon, + () => html``, + () => html`${label}`, + )} +
+
+ `; + } + } + + static override styles = [ + css` + .items { + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: var(--uui-size-1); + + uui-button { + --uui-button-font-weight: normal; + + &[draggable='true'], + &[draggable='true'] > .inner { + cursor: move; + } + + &[disabled], + &[disabled] > .inner { + cursor: not-allowed; + } + + &.forbidden { + --color: var(--uui-color-danger); + --color-standalone: var(--uui-color-danger-standalone); + --color-emphasis: var(--uui-color-danger-emphasis); + --color-contrast: var(--uui-color-danger); + --uui-button-contrast-disabled: var(--uui-color-danger); + --uui-button-border-color-disabled: var(--uui-color-danger); + } + + div { + display: flex; + gap: var(--uui-size-1); + } + + uui-symbol-expand { + margin-left: var(--uui-size-space-2); + } + } + } + + uui-button[look='outline'] { + --uui-button-background-color-hover: var(--uui-color-surface); + } + `, + ]; +} + +export default UmbTiptapToolbarGroupConfigurationElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-tiptap-toolbar-group-configuration': UmbTiptapToolbarGroupConfigurationElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/contexts/tiptap-toolbar-configuration.context.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/contexts/tiptap-toolbar-configuration.context.ts index 646c6c32d9..c758839d3d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/contexts/tiptap-toolbar-configuration.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/contexts/tiptap-toolbar-configuration.context.ts @@ -240,6 +240,27 @@ export class UmbTiptapToolbarConfigurationContext extends UmbContextBase { this.#toolbar.setValue(toolbar); } + public updateToolbarItem(aliases: Array, to: [number, number]) { + const toolbar = [...this.#toolbar.getValue()]; + const [rowIndex, groupIndex] = to; + + const newToolbar = toolbar.map((row, rIdx) => { + if (rIdx !== rowIndex) return row; + return { + ...row, + data: row.data.map((group, gIdx) => { + if (gIdx !== groupIndex) return group; + return { + ...group, + data: [...aliases], + }; + }), + }; + }); + + this.#toolbar.setValue(newToolbar); + } + public updateToolbarRow(rowIndex: number, groups: Array) { const toolbar = [...this.#toolbar.getValue()]; From b23906a6b6bd6c7c321da744ce9c7d995605e9ff Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 26 Aug 2025 16:48:46 +0200 Subject: [PATCH 16/33] V16: Unwarranted redirect after auth (#19935) * fix: uses isAuthorized to check if user is logged in before terminating the observer * feat: adds new function to redirect to stored path * fix: always redirect to stored path even on failure the user may have landed up on the page by mistake * Revert "fix: always redirect to stored path even on failure" This reverts commit 0c0cc0253c175ae8910e0cd26fc6df238374e6b2. * fix: sends back the result * fix: waits for the initial authorization request to come back before listening to the authorization signal (and then only listen once for it) also check if the request was null, which means we can safely redirect the user * docs: clarify what happens * chore: converts the promise code to async/await pattern * fix: tokenResponse should validate its internal object state * feat: allows function to force a window redirect * fix: checks if the user happens to already be authorized, because then we do not need a new code check * Update src/Umbraco.Web.UI.Client/src/packages/core/utils/path/stored-path.function.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../src/apps/app/app.element.ts | 49 ++++++++++++------- .../src/authorization_request_handler.ts | 3 +- .../src/packages/core/auth/auth-flow.ts | 2 +- .../core/utils/path/stored-path.function.ts | 17 +++++++ 4 files changed, 50 insertions(+), 21 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts b/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts index ff655336d5..7a17520579 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts @@ -19,7 +19,7 @@ import { umbExtensionsRegistry, } from '@umbraco-cms/backoffice/extension-registry'; import { filter, first, firstValueFrom } from '@umbraco-cms/backoffice/external/rxjs'; -import { hasOwnOpener, retrieveStoredPath } from '@umbraco-cms/backoffice/utils'; +import { hasOwnOpener, redirectToStoredPath } from '@umbraco-cms/backoffice/utils'; import { UmbApiInterceptorController } from '@umbraco-cms/backoffice/resources'; import { umbHttpClient } from '@umbraco-cms/backoffice/http-client'; @@ -61,7 +61,7 @@ export class UmbAppElement extends UmbLitElement { { path: 'oauth_complete', component: () => import('./app-oauth.element.js'), - setup: (component) => { + setup: async (component) => { if (!this.#authContext) { (component as UmbAppOauthElement).failure = true; console.error('[Fatal] Auth context is not available'); @@ -76,26 +76,37 @@ export class UmbAppElement extends UmbLitElement { return; } - // If we are in the main window (i.e. no opener), we should redirect to the root after the authorization request is completed. - // The authorization request will be completed in the active window (main or popup) and the authorization signal will be sent. - // If we are in a popup window, the storage event in UmbAuthContext will catch the signal and close the window. - // If we are in the main window, the signal will be caught right here and the user will be redirected to the root. - if (!hasOwnOpener(this.backofficePath)) { - this.observe(this.#authContext.authorizationSignal, () => { - // Redirect to the saved state or root - const url = retrieveStoredPath(); - const isBackofficePath = url?.pathname.startsWith(this.backofficePath) ?? true; - - if (isBackofficePath) { - history.replaceState(null, '', url?.toString() ?? ''); - } else { - window.location.href = url?.toString() ?? this.backofficePath; - } - }); + // Check that we are not already authorized + if (this.#authContext.getIsAuthorized()) { + redirectToStoredPath(this.backofficePath, true); + return; } // Complete the authorization request, which will send the authorization signal - this.#authContext.completeAuthorizationRequest().catch(() => undefined); + try { + const result = await this.#authContext.completeAuthorizationRequest(); + + if (result === null) { + // If the result is null, it could mean that no new token was required, so we can redirect the user + // This could happen if the user is already authorized or accidentally enters the oauth_complete url + redirectToStoredPath(this.backofficePath, true); + return; + } + + // If we are in the main window (i.e. no opener), we should redirect to the root after the authorization request is completed. + // The authorization request will be completed in the active window (main or popup) and the authorization signal will be sent. + // If we are in a popup window, the storage event in UmbAuthContext will catch the signal and close the window. + // If we are in the main window, the signal will be caught right here and the user will be redirected to their previous path (or root). + if (hasOwnOpener(this.backofficePath)) return; + + // Listen for the first authorization signal after the initial authorization request + await firstValueFrom(this.#authContext.authorizationSignal); + // When it hits, we should redirect the user to the backoffice + redirectToStoredPath(this.backofficePath); + } catch { + (component as UmbAppOauthElement).failure = true; + console.error('[Fatal] Authorization request failed'); + } }, }, { diff --git a/src/Umbraco.Web.UI.Client/src/external/openid/src/authorization_request_handler.ts b/src/Umbraco.Web.UI.Client/src/external/openid/src/authorization_request_handler.ts index 90eb72b171..d77d8a0e59 100644 --- a/src/Umbraco.Web.UI.Client/src/external/openid/src/authorization_request_handler.ts +++ b/src/Umbraco.Web.UI.Client/src/external/openid/src/authorization_request_handler.ts @@ -118,7 +118,7 @@ export abstract class AuthorizationRequestHandler { /** * Completes the authorization request if necessary & when possible. */ - completeAuthorizationRequestIfPossible(): Promise { + completeAuthorizationRequestIfPossible(): Promise { // call complete authorization if possible to see there might // be a response that needs to be delivered. log(`Checking to see if there is an authorization response to be delivered.`); @@ -133,6 +133,7 @@ export abstract class AuthorizationRequestHandler { if (result && this.notifier) { this.notifier.onAuthorizationComplete(result.request, result.response, result.error); } + return result; }); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth-flow.ts b/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth-flow.ts index 8c10231db6..0e02546423 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth-flow.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth-flow.ts @@ -236,7 +236,7 @@ export class UmbAuthFlow { * @returns true if the user is logged in, false otherwise. */ isAuthorized(): boolean { - return !!this.#tokenResponse; + return !!this.#tokenResponse.getValue(); } /** diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/stored-path.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/stored-path.function.ts index e9196ab324..24d280c861 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/stored-path.function.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/stored-path.function.ts @@ -30,3 +30,20 @@ export function setStoredPath(path: string): void { } sessionStorage.setItem(UMB_STORAGE_REDIRECT_URL, url.toString()); } + +/** + * Redirect the user to the stored path or the base path if not available. + * If the basePath matches the start of the stored path, the browser will replace the state instead of redirecting. + * @param {string} basePath - The base path to redirect to if no stored path is available. + * @param {boolean} [force=false] - If true, will redirect using Location + */ +export function redirectToStoredPath(basePath: string, force = false): void { + const url = retrieveStoredPath(); + const isBackofficePath = url?.pathname.startsWith(basePath) ?? false; + + if (isBackofficePath && !force) { + history.replaceState(null, '', url?.toString() ?? ''); + } else { + window.location.href = url?.toString() ?? basePath; + } +} From da7454e98713ef00336e09896a61101ba28fd2c7 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Tue, 26 Aug 2025 19:54:19 +0200 Subject: [PATCH 17/33] Ensure the directory exists before creating the SQLite database (#19980) Ensure the directory exists before creating the SQLite database. --- .../Services/SqliteDatabaseCreator.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Umbraco.Cms.Persistence.Sqlite/Services/SqliteDatabaseCreator.cs b/src/Umbraco.Cms.Persistence.Sqlite/Services/SqliteDatabaseCreator.cs index c666547c1d..348846d3b1 100644 --- a/src/Umbraco.Cms.Persistence.Sqlite/Services/SqliteDatabaseCreator.cs +++ b/src/Umbraco.Cms.Persistence.Sqlite/Services/SqliteDatabaseCreator.cs @@ -86,6 +86,7 @@ public class SqliteDatabaseCreator : IDatabaseCreator // Copy our blank(ish) wal mode sqlite database to its final location. try { + EnsureDatabaseDirectory(original.DataSource); File.Copy(tempFile, original.DataSource, true); } catch (Exception ex) @@ -104,4 +105,13 @@ public class SqliteDatabaseCreator : IDatabaseCreator _logger.LogWarning(ex, "Unable to cleanup temporary sqlite database file {path}", tempFile); } } + + private static void EnsureDatabaseDirectory(string dataSource) + { + var directoryPath = Path.GetDirectoryName(dataSource); + if (string.IsNullOrEmpty(directoryPath) is false && Directory.Exists(directoryPath) is false) + { + Directory.CreateDirectory(directoryPath); + } + } } From e82da17f2c54f878b0f96d08f77be90f8d8127db Mon Sep 17 00:00:00 2001 From: Andreas Zerbst <73799582+andr317c@users.noreply.github.com> Date: Wed, 27 Aug 2025 08:28:16 +0200 Subject: [PATCH 18/33] V16 QA added acceptance test for issue 10431 (#19999) * Added test * Bumped version --- .../package-lock.json | 16 +++++----- .../Umbraco.Tests.AcceptanceTest/package.json | 4 +-- .../Content/ContentWithMediaPicker.spec.ts | 32 +++++++++++++++++++ 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/tests/Umbraco.Tests.AcceptanceTest/package-lock.json b/tests/Umbraco.Tests.AcceptanceTest/package-lock.json index ca24b641de..bb1da8d0fc 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.37", - "@umbraco/playwright-testhelpers": "^16.0.39", + "@umbraco/playwright-testhelpers": "^16.0.41", "camelize": "^1.0.0", "dotenv": "^16.3.1", "node-fetch": "^2.6.7" @@ -58,21 +58,21 @@ } }, "node_modules/@umbraco/json-models-builders": { - "version": "2.0.37", - "resolved": "https://registry.npmjs.org/@umbraco/json-models-builders/-/json-models-builders-2.0.37.tgz", - "integrity": "sha512-97cRUrD+oeEno9I+qFjq7lWVS0+aDEK44lQQYWmVPAkCuAG1HMpBTEblS45CflrmLtgrDuZx68WIVVGpk9JzgQ==", + "version": "2.0.38", + "resolved": "https://registry.npmjs.org/@umbraco/json-models-builders/-/json-models-builders-2.0.38.tgz", + "integrity": "sha512-6nC1Y1xn+8zyqU3iqHubRo18L53TdZkhHIY4z68VSLcA6YoAzdxtjw+zx7yDIMV+epoQ4NCG2ooAa0gBhHqQgg==", "license": "MIT", "dependencies": { "camelize": "^1.0.1" } }, "node_modules/@umbraco/playwright-testhelpers": { - "version": "16.0.39", - "resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-16.0.39.tgz", - "integrity": "sha512-rZ/e3Kc9Dzkd7L+V5J3VyGlODnUNLye4kksnaKdRM4PKAsSW6U1f8t3402+lywtTo0oot7JNrVvooJuLwuwc+w==", + "version": "16.0.41", + "resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-16.0.41.tgz", + "integrity": "sha512-FmpL3ucj+3lZKxuL1JWyFJeU5DBL6nRsREejhQd/gUMtoJJpXhPUJ/jorqnWEwPYcvGWSBS/Inly0q+Akuf9Ow==", "license": "MIT", "dependencies": { - "@umbraco/json-models-builders": "2.0.37", + "@umbraco/json-models-builders": "2.0.38", "node-fetch": "^2.6.7" } }, diff --git a/tests/Umbraco.Tests.AcceptanceTest/package.json b/tests/Umbraco.Tests.AcceptanceTest/package.json index 82c0467e2e..43b8727f80 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/package.json +++ b/tests/Umbraco.Tests.AcceptanceTest/package.json @@ -22,9 +22,9 @@ }, "dependencies": { "@umbraco/json-models-builders": "^2.0.37", - "@umbraco/playwright-testhelpers": "^16.0.39", + "@umbraco/playwright-testhelpers": "^16.0.41", "camelize": "^1.0.0", "dotenv": "^16.3.1", "node-fetch": "^2.6.7" } -} \ No newline at end of file +} diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ContentWithMediaPicker.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ContentWithMediaPicker.spec.ts index 0e0b9e9510..8a88f7feeb 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ContentWithMediaPicker.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ContentWithMediaPicker.spec.ts @@ -158,3 +158,35 @@ test.fixme('can not publish a mandatory media picker with an empty value', async expect(contentData.values[0].value[0].focalPoint).toBeNull(); expect(contentData.values[0].value[0].crops).toEqual([]); }); + +// This is a test for the regression issue #10431 +test('can add a media image to a media picker in variant content, remove it and then add it again', async ({umbracoApi, umbracoUi}) => { + // Arrange + const dataTypeData = await umbracoApi.dataType.getByName(dataTypeName); + const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, dataTypeName, dataTypeData.id, 'Test Group', true, true, false); + await umbracoApi.document.createDefaultDocumentWithEnglishCulture(contentName, documentTypeId); + const mediaFileId = await umbracoApi.media.createDefaultMediaWithImage(mediaFileName); + await umbracoUi.goToBackOffice(); + await umbracoUi.content.goToSection(ConstantHelper.sections.content); + + // Act + await umbracoUi.content.goToContentWithName(contentName); + // Adds media item to a media picker + await umbracoUi.content.clickChooseButtonAndSelectMediaWithKey(mediaFileId); + await umbracoUi.content.clickChooseModalButton(); + await umbracoUi.content.clickSaveAndPublishButton(); + await umbracoUi.content.clickContainerSaveAndPublishButton(); + await umbracoUi.content.isSuccessStateVisibleForSaveAndPublishButton(); + // Removes media item from the media picker + await umbracoUi.content.removeMediaPickerByName(mediaFileName); + await umbracoUi.content.clickSaveAndPublishButton(); + await umbracoUi.content.clickContainerSaveAndPublishButton(); + await umbracoUi.content.isSuccessStateVisibleForSaveAndPublishButton(); + + // Adds media item to a media picker again + await umbracoUi.content.clickChooseButtonAndSelectMediaWithKey(mediaFileId); + await umbracoUi.content.clickChooseModalButton(); + + // Assert + await umbracoUi.content.isMediaNameVisible(mediaFileName); +}); From 019563b22600037f24c0d4c5b6aee8a43bb99190 Mon Sep 17 00:00:00 2001 From: Andrej Davidovic Date: Wed, 27 Aug 2025 10:46:27 +0300 Subject: [PATCH 19/33] Fix: custom block view rendering (#19962) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix: custom block view rendering * chore: formatting * chore: formatting * chore: marks render method as class property to bind it properly to the class so it can run private methods and does not lose its context see also #extensionSlotRenderMethod --------- Co-authored-by: Andrej Davidovič Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> --- .../block-grid-entry/block-grid-entry.element.ts | 9 ++++----- .../extension-slot/extension-slot.element.ts | 13 ++++++++++++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts index 931d195b59..e0b4528101 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts @@ -467,12 +467,11 @@ export class UmbBlockGridEntryElement extends UmbLitElement implements UmbProper ${this.#renderBuiltinBlockView()} + single> ${this.#renderActionBar()} ${!this._showContentEdit && this._contentInvalid ? html`!` @@ -494,7 +493,7 @@ export class UmbBlockGridEntryElement extends UmbLitElement implements UmbProper : nothing; } - #renderBuiltinBlockView() { + #renderBuiltinBlockView = () => { if (this._unsupported) { return this.#renderUnsupportedBlock(); } @@ -502,7 +501,7 @@ export class UmbBlockGridEntryElement extends UmbLitElement implements UmbProper return this.renderInlineBlock(); } return this.#renderRefBlock(); - } + }; #renderUnsupportedBlock() { return html` TemplateResult | TemplateResult<1> | HTMLElement | null | undefined | typeof nothing; + @property({ attribute: false }) + public defaultRenderMethod?: () => + | TemplateResult + | TemplateResult<1> + | HTMLElement + | null + | undefined + | typeof nothing; + override connectedCallback(): void { super.connectedCallback(); this.#attached = true; @@ -136,7 +145,9 @@ export class UmbExtensionSlotElement extends UmbLitElement { return this._permitted ? this._permitted.length > 0 ? repeat(this._permitted, (ext) => ext.alias, this.#renderExtension) - : html`` + : this.defaultRenderMethod + ? this.defaultRenderMethod() + : html`` : nothing; } From f0c5ecf086ba2d2c3e89cb37f18d72faeee25b69 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 27 Aug 2025 13:01:44 +0200 Subject: [PATCH 20/33] Add request caching around published content factory (#19990) * Add request caching around published content factory. * Fixed ordering of log message parameters. Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Invert if to reduce nesting --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: mole --- .../Factories/IPublishedContentFactory.cs | 15 +- .../Factories/PublishedContentFactory.cs | 112 +++++++++++-- .../Factories/PublishedContentFactoryTests.cs | 147 ++++++++++++++++++ 3 files changed, 259 insertions(+), 15 deletions(-) create mode 100644 tests/Umbraco.Tests.Integration/Umbraco.PublishedCache.HybridCache/Factories/PublishedContentFactoryTests.cs diff --git a/src/Umbraco.PublishedCache.HybridCache/Factories/IPublishedContentFactory.cs b/src/Umbraco.PublishedCache.HybridCache/Factories/IPublishedContentFactory.cs index c5bfe4fe9e..46cb65d5e4 100644 --- a/src/Umbraco.PublishedCache.HybridCache/Factories/IPublishedContentFactory.cs +++ b/src/Umbraco.PublishedCache.HybridCache/Factories/IPublishedContentFactory.cs @@ -1,12 +1,25 @@ -using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.PublishedContent; namespace Umbraco.Cms.Infrastructure.HybridCache.Factories; +/// +/// Defines a factory to create and from a or . +/// internal interface IPublishedContentFactory { + /// + /// Converts a to an if document type. + /// IPublishedContent? ToIPublishedContent(ContentCacheNode contentCacheNode, bool preview); + + /// + /// Converts a to an of media type. + /// IPublishedContent? ToIPublishedMedia(ContentCacheNode contentCacheNode); + /// + /// Converts a to an . + /// IPublishedMember ToPublishedMember(IMember member); } diff --git a/src/Umbraco.PublishedCache.HybridCache/Factories/PublishedContentFactory.cs b/src/Umbraco.PublishedCache.HybridCache/Factories/PublishedContentFactory.cs index 57863dc986..5f33705716 100644 --- a/src/Umbraco.PublishedCache.HybridCache/Factories/PublishedContentFactory.cs +++ b/src/Umbraco.PublishedCache.HybridCache/Factories/PublishedContentFactory.cs @@ -1,29 +1,61 @@ -using Umbraco.Cms.Core.Models; +using Microsoft.Extensions.Logging; +using Umbraco.Cms.Core.Cache; +using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.PublishedCache; +using Umbraco.Extensions; namespace Umbraco.Cms.Infrastructure.HybridCache.Factories; +/// +/// Defines a factory to create and from a or . +/// internal sealed class PublishedContentFactory : IPublishedContentFactory { private readonly IElementsCache _elementsCache; private readonly IVariationContextAccessor _variationContextAccessor; private readonly IPublishedContentTypeCache _publishedContentTypeCache; + private readonly ILogger _logger; + private readonly AppCaches _appCaches; - + /// + /// Initializes a new instance of the class. + /// public PublishedContentFactory( IElementsCache elementsCache, IVariationContextAccessor variationContextAccessor, - IPublishedContentTypeCache publishedContentTypeCache) + IPublishedContentTypeCache publishedContentTypeCache, + ILogger logger, + AppCaches appCaches) { _elementsCache = elementsCache; _variationContextAccessor = variationContextAccessor; _publishedContentTypeCache = publishedContentTypeCache; + _logger = logger; + _appCaches = appCaches; } + /// public IPublishedContent? ToIPublishedContent(ContentCacheNode contentCacheNode, bool preview) { - IPublishedContentType contentType = _publishedContentTypeCache.Get(PublishedItemType.Content, contentCacheNode.ContentTypeId); + var cacheKey = $"{nameof(PublishedContentFactory)}DocumentCache_{contentCacheNode.Id}_{preview}"; + IPublishedContent? publishedContent = _appCaches.RequestCache.GetCacheItem(cacheKey); + if (publishedContent is not null) + { + _logger.LogDebug( + "Using cached IPublishedContent for document {ContentCacheNodeName} ({ContentCacheNodeId}).", + contentCacheNode.Data?.Name ?? "No Name", + contentCacheNode.Id); + return publishedContent; + } + + _logger.LogDebug( + "Creating IPublishedContent for document {ContentCacheNodeName} ({ContentCacheNodeId}).", + contentCacheNode.Data?.Name ?? "No Name", + contentCacheNode.Id); + + IPublishedContentType contentType = + _publishedContentTypeCache.Get(PublishedItemType.Content, contentCacheNode.ContentTypeId); var contentNode = new ContentNode( contentCacheNode.Id, contentCacheNode.Key, @@ -34,19 +66,42 @@ internal sealed class PublishedContentFactory : IPublishedContentFactory preview ? contentCacheNode.Data : null, preview ? null : contentCacheNode.Data); - IPublishedContent? model = GetModel(contentNode, preview); + publishedContent = GetModel(contentNode, preview); if (preview) { - return model ?? GetPublishedContentAsDraft(model); + publishedContent ??= GetPublishedContentAsDraft(publishedContent); } - return model; + if (publishedContent is not null) + { + _appCaches.RequestCache.Set(cacheKey, publishedContent); + } + + return publishedContent; } + /// public IPublishedContent? ToIPublishedMedia(ContentCacheNode contentCacheNode) { - IPublishedContentType contentType = _publishedContentTypeCache.Get(PublishedItemType.Media, contentCacheNode.ContentTypeId); + var cacheKey = $"{nameof(PublishedContentFactory)}MediaCache_{contentCacheNode.Id}"; + IPublishedContent? publishedContent = _appCaches.RequestCache.GetCacheItem(cacheKey); + if (publishedContent is not null) + { + _logger.LogDebug( + "Using cached IPublishedContent for media {ContentCacheNodeName} ({ContentCacheNodeId}).", + contentCacheNode.Data?.Name ?? "No Name", + contentCacheNode.Id); + return publishedContent; + } + + _logger.LogDebug( + "Creating IPublishedContent for media {ContentCacheNodeName} ({ContentCacheNodeId}).", + contentCacheNode.Data?.Name ?? "No Name", + contentCacheNode.Id); + + IPublishedContentType contentType = + _publishedContentTypeCache.Get(PublishedItemType.Media, contentCacheNode.ContentTypeId); var contentNode = new ContentNode( contentCacheNode.Id, contentCacheNode.Key, @@ -57,14 +112,40 @@ internal sealed class PublishedContentFactory : IPublishedContentFactory null, contentCacheNode.Data); - return GetModel(contentNode, false); + publishedContent = GetModel(contentNode, false); + + if (publishedContent is not null) + { + _appCaches.RequestCache.Set(cacheKey, publishedContent); + } + + return publishedContent; } + /// public IPublishedMember ToPublishedMember(IMember member) { - IPublishedContentType contentType = _publishedContentTypeCache.Get(PublishedItemType.Member, member.ContentTypeId); + string cacheKey = $"{nameof(PublishedContentFactory)}MemberCache_{member.Id}"; + IPublishedMember? publishedMember = _appCaches.RequestCache.GetCacheItem(cacheKey); + if (publishedMember is not null) + { + _logger.LogDebug( + "Using cached IPublishedMember for member {MemberName} ({MemberId}).", + member.Username, + member.Id); - // Members are only "mapped" never cached, so these default values are a bit wierd, but they are not used. + return publishedMember; + } + + _logger.LogDebug( + "Creating IPublishedMember for member {MemberName} ({MemberId}).", + member.Username, + member.Id); + + IPublishedContentType contentType = + _publishedContentTypeCache.Get(PublishedItemType.Member, member.ContentTypeId); + + // Members are only "mapped" never cached, so these default values are a bit weird, but they are not used. var contentData = new ContentData( member.Name, null, @@ -85,7 +166,11 @@ internal sealed class PublishedContentFactory : IPublishedContentFactory contentType, null, contentData); - return new PublishedMember(member, contentNode, _elementsCache, _variationContextAccessor); + publishedMember = new PublishedMember(member, contentNode, _elementsCache, _variationContextAccessor); + + _appCaches.RequestCache.Set(cacheKey, publishedMember); + + return publishedMember; } private static Dictionary GetPropertyValues(IPublishedContentType contentType, IMember member) @@ -134,7 +219,6 @@ internal sealed class PublishedContentFactory : IPublishedContentFactory _variationContextAccessor); } - private static IPublishedContent? GetPublishedContentAsDraft(IPublishedContent? content) => content == null ? null : // an object in the cache is either an IPublishedContentOrMedia, @@ -149,7 +233,7 @@ internal sealed class PublishedContentFactory : IPublishedContentFactory content = wrapped.Unwrap(); } - if (!(content is PublishedContent inner)) + if (content is not PublishedContent inner) { throw new InvalidOperationException("Innermost content is not PublishedContent."); } diff --git a/tests/Umbraco.Tests.Integration/Umbraco.PublishedCache.HybridCache/Factories/PublishedContentFactoryTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.PublishedCache.HybridCache/Factories/PublishedContentFactoryTests.cs new file mode 100644 index 0000000000..3d7be44d69 --- /dev/null +++ b/tests/Umbraco.Tests.Integration/Umbraco.PublishedCache.HybridCache/Factories/PublishedContentFactoryTests.cs @@ -0,0 +1,147 @@ +using NUnit.Framework; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Cache; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Infrastructure.HybridCache; +using Umbraco.Cms.Infrastructure.HybridCache.Factories; +using Umbraco.Cms.Tests.Common.Builders; +using Umbraco.Cms.Tests.Common.Builders.Extensions; +using Umbraco.Cms.Tests.Common.Testing; +using Umbraco.Cms.Tests.Integration.Testing; + +namespace Umbraco.Cms.Tests.Integration.Umbraco.PublishedCache.HybridCache; + +[TestFixture] +[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] +internal sealed class PublishedContentFactoryTests : UmbracoIntegrationTestWithContent +{ + private IPublishedContentFactory PublishedContentFactory => GetRequiredService(); + + private IPublishedValueFallback PublishedValueFallback => GetRequiredService(); + + private IMediaService MediaService => GetRequiredService(); + + private IMediaTypeService MediaTypeService => GetRequiredService(); + + private IMemberService MemberService => GetRequiredService(); + + private IMemberTypeService MemberTypeService => GetRequiredService(); + + protected override void CustomTestSetup(IUmbracoBuilder builder) + { + var requestCache = new DictionaryAppCache(); + var appCaches = new AppCaches( + NoAppCache.Instance, + requestCache, + new IsolatedCaches(type => NoAppCache.Instance)); + builder.Services.AddUnique(appCaches); + } + + [Test] + public void Can_Create_Published_Content_For_Document() + { + var contentCacheNode = new ContentCacheNode + { + Id = Textpage.Id, + Key = Textpage.Key, + ContentTypeId = Textpage.ContentType.Id, + CreateDate = Textpage.CreateDate, + CreatorId = Textpage.CreatorId, + SortOrder = Textpage.SortOrder, + Data = new ContentData( + Textpage.Name, + "text-page", + Textpage.VersionId, + Textpage.UpdateDate, + Textpage.WriterId, + Textpage.TemplateId, + true, + new Dictionary + { + { + "title", new[] + { + new PropertyData + { + Value = "Test title", + Culture = string.Empty, + Segment = string.Empty, + }, + } + }, + }, + null), + }; + var result = PublishedContentFactory.ToIPublishedContent(contentCacheNode, false); + Assert.IsNotNull(result); + Assert.AreEqual(Textpage.Id, result.Id); + Assert.AreEqual(Textpage.Name, result.Name); + Assert.AreEqual("Test title", result.Properties.Single(x => x.Alias == "title").Value(PublishedValueFallback)); + + // Verify that requesting the same content again returns the same instance (from request cache). + var result2 = PublishedContentFactory.ToIPublishedContent(contentCacheNode, false); + Assert.AreSame(result, result2); + } + + [Test] + public async Task Can_Create_Published_Content_For_Media() + { + var mediaType = new MediaTypeBuilder().Build(); + mediaType.AllowedAsRoot = true; + await MediaTypeService.CreateAsync(mediaType, Constants.Security.SuperUserKey); + + var media = new MediaBuilder() + .WithMediaType(mediaType) + .WithName("Media 1") + .Build(); + MediaService.Save(media); + + var contentCacheNode = new ContentCacheNode + { + Id = media.Id, + Key = media.Key, + ContentTypeId = media.ContentType.Id, + Data = new ContentData( + media.Name, + null, + 0, + media.UpdateDate, + media.WriterId, + null, + false, + new Dictionary(), + null), + }; + var result = PublishedContentFactory.ToIPublishedMedia(contentCacheNode); + Assert.IsNotNull(result); + Assert.AreEqual(media.Id, result.Id); + Assert.AreEqual(media.Name, result.Name); + + // Verify that requesting the same content again returns the same instance (from request cache). + var result2 = PublishedContentFactory.ToIPublishedMedia(contentCacheNode); + Assert.AreSame(result, result2); + } + + [Test] + public async Task Can_Create_Published_Member_For_Member() + { + var memberType = new MemberTypeBuilder().Build(); + await MemberTypeService.CreateAsync(memberType, Constants.Security.SuperUserKey); + + var member = new MemberBuilder() + .WithMemberType(memberType) + .WithName("Member 1") + .Build(); + MemberService.Save(member); + + var result = PublishedContentFactory.ToPublishedMember(member); + Assert.IsNotNull(result); + Assert.AreEqual(member.Id, result.Id); + Assert.AreEqual(member.Name, result.Name); + + // Verify that requesting the same content again returns the same instance (from request cache). + var result2 = PublishedContentFactory.ToPublishedMember(member); + Assert.AreSame(result, result2); + } +} From 279409d6eee1f610500cd57d855bffc3d86bc4ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 27 Aug 2025 13:09:21 +0200 Subject: [PATCH 21/33] Fix: Workspace Editor slotted fallback content should be displayed when no routes (#20006) * fix + notes * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../workspace-editor.context.ts | 4 +- .../workspace-editor.element.ts | 42 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.context.ts index dd916b5a2e..e1c3724876 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.context.ts @@ -38,9 +38,9 @@ export class UmbWorkspaceEditorContext extends UmbContextBase { (view) => !workspaceViews.some((x) => x.manifest.alias === view.manifest.alias), ); - const diff = viewsToKeep.length !== workspaceViews.length; + const hasDiff = viewsToKeep.length !== workspaceViews.length; - if (diff) { + if (hasDiff) { const newViews = [...viewsToKeep]; // Add ones that are new: diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts index 499278f5d1..10866294c8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts @@ -136,26 +136,26 @@ export class UmbWorkspaceEditorElement extends UmbLitElement { } override render() { - return this._routes - ? html` - - ${this.#renderBackButton()} - - - ${this.#renderViews()} ${this.#renderRoutes()} - - ${when( - !this.enforceNoFooter, - () => html` - - - - - `, - )} - - ` - : nothing; + // Notice if no routes then fallback to use a slot. + // TODO: Deprecate the slot feature, to rely purely on routes, cause currently bringing an additional route would mean the slotted content would never be shown. [NL] + return html` + + ${this.#renderBackButton()} + + + ${this.#renderViews()} ${this.#renderRoutes()} + + ${when( + !this.enforceNoFooter, + () => html` + + + + + `, + )} + + `; } #renderViews() { @@ -213,7 +213,7 @@ export class UmbWorkspaceEditorElement extends UmbLitElement { } #renderRoutes() { - if (!this._routes || this._routes.length === 0) return nothing; + if (!this._routes || this._routes.length === 0 || !this._workspaceViews || this._workspaceViews.length === 0) return nothing; return html` Date: Wed, 27 Aug 2025 13:11:58 +0200 Subject: [PATCH 22/33] Fix: rename and implement fallbackRenderMethod (#20005) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * rename and implement fallbackRender * re introducing method as part of the name * rename impls --------- Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Co-authored-by: Andrej Davidovič --- .../block-grid-entry/block-grid-entry.element.ts | 2 +- .../block-list-entry/block-list-entry.element.ts | 9 ++++----- .../block-rte-entry/block-rte-entry.element.ts | 13 ++++++++++--- .../extension-slot/extension-slot.element.ts | 11 +++++++---- .../extension-with-api-slot.element.ts | 15 ++++++++++++++- 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts index e0b4528101..5fb10c3349 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts @@ -467,7 +467,7 @@ export class UmbBlockGridEntryElement extends UmbLitElement implements UmbProper `; } - #renderBuiltinBlockView() { + #renderBuiltinBlockView = () => { if (this._unsupported) { return this.#renderUnsupportedBlock(); } @@ -407,7 +407,7 @@ export class UmbBlockListEntryElement extends UmbLitElement implements UmbProper return this.#renderInlineBlock(); } return this.#renderRefBlock(); - } + }; #renderBlock() { return this.contentKey && (this._contentTypeAlias || this._unsupported) @@ -417,11 +417,10 @@ export class UmbBlockListEntryElement extends UmbLitElement implements UmbProper type="blockEditorCustomView" default-element=${this._inlineEditingMode ? 'umb-inline-list-block' : 'umb-ref-list-block'} .renderMethod=${this.#extensionSlotRenderMethod} + .fallbackRenderMethod=${this.#renderBuiltinBlockView} .props=${this._blockViewProps} .filter=${this.#extensionSlotFilterMethod} - single - >${this.#renderBuiltinBlockView()} + single> ${this.#renderActionBar()} ${!this._showContentEdit && this._contentInvalid ? html`!` diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/components/block-rte-entry/block-rte-entry.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/components/block-rte-entry/block-rte-entry.element.ts index 92129a97f2..63d79ac8f8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/components/block-rte-entry/block-rte-entry.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/components/block-rte-entry/block-rte-entry.element.ts @@ -277,11 +277,10 @@ export class UmbBlockRteEntryElement extends UmbLitElement implements UmbPropert type="blockEditorCustomView" default-element="umb-ref-rte-block" .renderMethod=${this.#extensionSlotRenderMethod} + .fallbackRenderMethod=${this.#renderBuiltinBlockView} .props=${this._blockViewProps} .filter=${this.#filterBlockCustomViews} - single> - ${this.#renderRefBlock()} - + single> ${this.#renderActionBar()} ${!this._showContentEdit && this._contentInvalid ? html`!` @@ -297,6 +296,14 @@ export class UmbBlockRteEntryElement extends UmbLitElement implements UmbPropert : nothing; } + #renderBuiltinBlockView = () => { + // TODO: Missing unsupported rendering [NL] + /*if (this._unsupported) { + return this.#renderUnsupportedBlock(); + }*/ + return this.#renderRefBlock(); + }; + #renderRefBlock() { return html` TemplateResult | TemplateResult<1> | HTMLElement | null | undefined | typeof nothing; @property({ attribute: false }) - public defaultRenderMethod?: () => + public fallbackRenderMethod?: () => | TemplateResult | TemplateResult<1> | HTMLElement @@ -142,15 +142,18 @@ export class UmbExtensionSlotElement extends UmbLitElement { } override render() { + // First renders something once _permitted is set, this is to avoid flickering. [NL] return this._permitted ? this._permitted.length > 0 ? repeat(this._permitted, (ext) => ext.alias, this.#renderExtension) - : this.defaultRenderMethod - ? this.defaultRenderMethod() - : html`` + : this.#renderNoting() : nothing; } + #renderNoting() { + return this.fallbackRenderMethod ? this.fallbackRenderMethod() : html``; + } + #renderExtension = (ext: UmbExtensionElementInitializer, i: number) => { return this.renderMethod ? this.renderMethod(ext, i) : ext.component; }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/components/extension-with-api-slot/extension-with-api-slot.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/components/extension-with-api-slot/extension-with-api-slot.element.ts index 9b299c1b9c..9f2e56413f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/components/extension-with-api-slot/extension-with-api-slot.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/components/extension-with-api-slot/extension-with-api-slot.element.ts @@ -143,6 +143,15 @@ export class UmbExtensionWithApiSlotElement extends UmbLitElement { index: number, ) => TemplateResult | TemplateResult<1> | HTMLElement | null | undefined | typeof nothing; + @property({ attribute: false }) + public fallbackRenderMethod?: () => + | TemplateResult + | TemplateResult<1> + | HTMLElement + | null + | undefined + | typeof nothing; + override connectedCallback(): void { super.connectedCallback(); this.#attached = true; @@ -185,10 +194,14 @@ export class UmbExtensionWithApiSlotElement extends UmbLitElement { return this._permitted ? this._permitted.length > 0 ? repeat(this._permitted, (ext) => ext.alias, this.#renderExtension) - : html`` + : this.#renderNoting() : nothing; } + #renderNoting() { + return this.fallbackRenderMethod ? this.fallbackRenderMethod() : html``; + } + #renderExtension = (ext: UmbExtensionElementAndApiInitializer, i: number) => { return this.renderMethod ? this.renderMethod(ext, i) : ext.component; }; From cef7bb935780fae504e30263f07ccd00fe3e8063 Mon Sep 17 00:00:00 2001 From: Lee Kelleher Date: Wed, 27 Aug 2025 12:12:26 +0100 Subject: [PATCH 23/33] Chore: JSDocs for RTE CSS Props (#20008) RTE base: added JSDocs for CSSProps --- .../src/packages/rte/components/rte-base.element.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts b/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts index ea01c96fd8..de1c417a04 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts @@ -21,6 +21,15 @@ import type { UmbPropertyEditorConfigCollection, } from '@umbraco-cms/backoffice/property-editor'; +/** + * The abstract base class that is used as a base for the rich-text-editor component. + * @cssprop --umb-rte-width - The width of the rich-text-editor (default: unset) + * @cssprop --umb-rte-min-width - The minimum width of the rich-text-editor (default: unset) + * @cssprop --umb-rte-max-width - The maximum width of the rich-text-editor (default: 100%) + * @cssprop --umb-rte-height - The height of the rich-text-editor (default: 100%) + * @cssprop --umb-rte-min-height - The minimum height of the rich-text-editor (default: 100%) + * @cssprop --umb-rte-max-height - The maximum height of the rich-text-editor (default: 100%) + */ export abstract class UmbPropertyEditorUiRteElementBase extends UmbFormControlMixin(UmbLitElement) implements UmbPropertyEditorUiElement From cbb1eaec280446e6e3f963fe819ea1fd3b215441 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 27 Aug 2025 13:38:28 +0200 Subject: [PATCH 24/33] Prevents the removal of all user groups from a user (#19995) * Prevents the removal of all user groups from a user. * Add additional user group when removing --------- Co-authored-by: mole --- .../User/UserOrCurrentUserControllerBase.cs | 2 +- src/Umbraco.Core/Services/UserService.cs | 9 ++++++++- .../tests/DefaultConfig/Users/User.spec.ts | 2 +- .../Services/UserServiceCrudTests.Update.cs | 14 ++++++++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/UserOrCurrentUserControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/UserOrCurrentUserControllerBase.cs index 43db8355b7..a6faf7ddbe 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/UserOrCurrentUserControllerBase.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/User/UserOrCurrentUserControllerBase.cs @@ -25,7 +25,7 @@ public abstract class UserOrCurrentUserControllerBase : ManagementApiControllerB .Build()), UserOperationStatus.NoUserGroup => BadRequest(problemDetailsBuilder .WithTitle("No User Group Specified") - .WithDetail("A user group must be specified to create a user") + .WithDetail("A user must be assigned to at least one group") .Build()), UserOperationStatus.UserNameIsNotEmail => BadRequest(problemDetailsBuilder .WithTitle("Invalid Username") diff --git a/src/Umbraco.Core/Services/UserService.cs b/src/Umbraco.Core/Services/UserService.cs index 718ef1eb69..612e32efde 100644 --- a/src/Umbraco.Core/Services/UserService.cs +++ b/src/Umbraco.Core/Services/UserService.cs @@ -883,7 +883,7 @@ internal partial class UserService : RepositoryService, IUserService return UserOperationStatus.DuplicateUserName; } - if(model.UserGroupKeys.Count == 0) + if (model.UserGroupKeys.Count == 0) { return UserOperationStatus.NoUserGroup; } @@ -912,6 +912,13 @@ internal partial class UserService : RepositoryService, IUserService return Attempt.FailWithStatus(UserOperationStatus.MissingUser, existingUser); } + // A user must remain assigned to at least one group. + if (model.UserGroupKeys.Count == 0) + { + scope.Complete(); + return Attempt.FailWithStatus(UserOperationStatus.NoUserGroup, existingUser); + } + // User names can only contain the configured allowed characters. This is validated by ASP.NET Identity on create // as the setting is applied to the BackOfficeIdentityOptions, but we need to check ourselves for updates. var allowedUserNameCharacters = _securitySettings.AllowedUserNameCharacters; diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/User.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/User.spec.ts index 3b8b6b34ec..0ede3be26b 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/User.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/User.spec.ts @@ -642,4 +642,4 @@ test.skip('cannot remove all user group from a user', {tag: '@release'}, async ( // Assert await umbracoUi.user.isErrorNotificationVisible(); -}); \ No newline at end of file +}); diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/UserServiceCrudTests.Update.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/UserServiceCrudTests.Update.cs index 4b5cc29fee..f2d8ab68b8 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/UserServiceCrudTests.Update.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/UserServiceCrudTests.Update.cs @@ -151,7 +151,21 @@ internal sealed partial class UserServiceCrudTests Assert.AreEqual(email, updatedUser.Email); Assert.AreEqual(name, updatedUser.Name); }); + } + [Test] + public async Task Cannot_Update_User_To_Have_No_Groups() + { + var userService = CreateUserService(securitySettings: new SecuritySettings { UsernameIsEmail = false }); + + var (updateModel, createdUser) = await CreateUserForUpdate(userService); + + updateModel.UserGroupKeys.Clear(); + + var updateAttempt = await userService.UpdateAsync(Constants.Security.SuperUserKey, updateModel); + + Assert.IsFalse(updateAttempt.Success); + Assert.AreEqual(UserOperationStatus.NoUserGroup, updateAttempt.Status); } [Test] From 7836770c68dba872566b4c2b77bd8349bcd53396 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Thu, 28 Aug 2025 07:24:47 +0200 Subject: [PATCH 25/33] build: enables workflow_dispatch --- .github/workflows/azure-backoffice.yml | 1 + .github/workflows/azure-storybook.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/azure-backoffice.yml b/.github/workflows/azure-backoffice.yml index 4c40540065..61c1d5e4c1 100644 --- a/.github/workflows/azure-backoffice.yml +++ b/.github/workflows/azure-backoffice.yml @@ -17,6 +17,7 @@ on: - main - v*/dev - v*/main + workflow_dispatch: jobs: build_and_deploy_job: diff --git a/.github/workflows/azure-storybook.yml b/.github/workflows/azure-storybook.yml index 586cd10d22..f0aa3c8a98 100644 --- a/.github/workflows/azure-storybook.yml +++ b/.github/workflows/azure-storybook.yml @@ -17,6 +17,7 @@ on: - main - v*/dev - v*/main + workflow_dispatch: env: NODE_OPTIONS: --max_old_space_size=16384 From e142a9c0d1d4083897b2e4e1c9c96753d3482e63 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Thu, 28 Aug 2025 10:01:44 +0200 Subject: [PATCH 26/33] fix: pins the UmbracoExtension `@hey-api/*` versions to that of the Backoffice client (#20016) fix: pins the @hey-api/* versions to that of the Backoffice client This is a quick fix to handle the NPM error that is currently there because the Backoffice NPM client has moved on to another version. There will be a more comprehensive fix for 16.3, however this PR aims to make the 16.2 UmbracoExtension usable without running custom commands. --- templates/UmbracoExtension/Client/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/UmbracoExtension/Client/package.json b/templates/UmbracoExtension/Client/package.json index 87514b0f7d..bbc4d8b7dd 100644 --- a/templates/UmbracoExtension/Client/package.json +++ b/templates/UmbracoExtension/Client/package.json @@ -9,8 +9,8 @@ "generate-client": "node scripts/generate-openapi.js https://localhost:44339/umbraco/swagger/umbracoextension/swagger.json" }, "devDependencies": { - "@hey-api/client-fetch": "^0.10.0", - "@hey-api/openapi-ts": "^0.66.7", + "@hey-api/client-fetch": "0.12.0", + "@hey-api/openapi-ts": "0.71.0", "@umbraco-cms/backoffice": "^UMBRACO_VERSION_FROM_TEMPLATE", "chalk": "^5.4.1", "cross-env": "^7.0.3", From e5f613401f8f523a7cb889914ae8c3ac448db1ed Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 28 Aug 2025 12:55:37 +0200 Subject: [PATCH 27/33] Section Sidebar Menu Expansion (#19810) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * wip section menu expansion * make section context local to each section * split kind manifest from element file * make generic entity expansion manager * wip menu context * add collapsed and expanded events * Export new expansion entity event modules * rename events * dispatch events * Set tree expansion changes in the menu context * expand menu from workspace * do not allow undefined * make menu item feature folder * Update menu-variant-tree-structure-workspace-context-base.ts * menu: pass expansion as prop to prevent dependency on the section sidebar * use correct event * Add event listener support to extension slot element Introduces an 'events' property to UmbExtensionSlotElement, allowing dynamic assignment and removal of event listeners on extension components. Event listeners are added when extensions are permitted and removed on disconnect, improving extensibility and event handling for extension slots. * Add entity expansion event handling to sidebar menu Introduces handlers for entity expansion and collapse events in the section sidebar menu. This change enables the menu to respond to expansion state changes by updating the context accordingly. * Optimize expansion state updates in menu components Introduces a local expansion state to both section sidebar and tree menu item components to prevent unnecessary updates and rerenders. This improves performance by ensuring state updates only occur when needed. * only check if we have a local state already * add bulk expand method * use bulk expand method * align naming * mute updates * lower threshold * add expansion model with target * add function to link entries * fix self import * export constants * update js docs for entity expansion manager * link entries * fix import * do not export from menu here * fix import * fix import * align how we register manifests * add specific managers for section sidebar menu * use structure items * dot not expand current item * Refactor section sidebar menu to use programmatic extension slot Replaces the template-based with a programmatically created UmbExtensionSlotElement for improved performance and UX. * add section context extension * register menu as section context instead of hardcoding * rename folder * align naming * export extension slot elements * fix typings * destroy extension slot element when host is disconnected * use entry model * move and rename * register global context to hold menu state across sections * temp observe section specific expansions * temp observe section specific expansions * add method to collapse multiple items * bind expansion to section * make entity expansion manager generic * add helper method * remove temp test data * include last item in target * remove unused * pass full entry to event * add type for menu item expansion * export types * add menuItem alias * Update types.ts * support menu item expansion entry * add const for menu item alias + use for breadcrumb and menu item * add data type menu item alias const + apply to breadcrumb * move to correct manifest * add menu item alias to expand entries * Update manifests.ts * add menu structure kind types * add kind to manifests * add menu item context * filter menu items * handle menu item expansion * clean up * fix order * add example dashboard and entity action * import types * align model type names * align naming * use ui component * add guard for menu item entry * use correct type * Update section-sidebar-menu.element.ts * Update entity-expansion.manager.ts * export constants * add menuItemAlias to manifest * add menuItemAlias to manifest * add menuItemAlias to manifest * add menuItemAlias to manifest * add menu item alias * add menuItemAlias to manifest * add menuItemAlias to manifest * add menuItemAlias to manifest * add alias * add kind * fix import path * do not expand menu from modal * collect all menu-item files in one folder * fix lint errors * Update content-detail-workspace-base.ts * clean up * rename to example * add button to collapse everything within a section * fix breadcrumb for non-variant structure * reload entity * destroy * remove self * Updated acceptance tests to check if a caret button is open before clicking * Bumped version of test helpers * use const --------- Co-authored-by: Andreas Zerbst Co-authored-by: Niels Lyngsø --- .../devops/module-dependencies/index.js | 2 +- .../collapse-menu-item.entity-action.ts | 11 ++ .../manifests.ts | 15 ++ .../section-sidebar-menu-expansion/index.ts | 4 + .../playground-dashboard/manifests.ts | 14 ++ ...section-sidebar-menu-playground.element.ts | 102 +++++++++++++ .../components/backoffice-main.element.ts | 1 + .../content-detail-workspace-base.ts | 13 +- .../extension-slot/extension-slot.element.ts | 44 ++++++ .../packages/core/extension-registry/index.ts | 2 + .../menu/components/menu-item/action/types.ts | 2 +- .../menu/components/menu-item/constants.ts | 1 + .../is-menu-item-expansion-entry.guard.ts | 16 ++ .../expansion/menu-item-expansion.manager.ts | 132 +++++++++++++++++ .../core/menu/components/menu-item/index.ts | 1 + .../menu-item/link/link-menu-item.element.ts | 2 +- .../menu/components/menu-item/link/types.ts | 2 +- .../menu-item/menu-item-default.element.ts | 4 +- .../menu-item}/menu-item-element.interface.ts | 0 .../menu-item/menu-item.context.token.ts | 4 + .../components/menu-item/menu-item.context.ts | 22 +++ .../menu-item}/menu-item.extension.ts | 0 .../core/menu/components/menu-item/types.ts | 2 + .../core/menu/components/menu/constants.ts | 1 + .../core/menu/components/menu/index.ts | 1 + .../components/menu/menu.context.token.ts | 4 + .../core/menu/components/menu/menu.context.ts | 13 ++ .../core/menu/components/menu/menu.element.ts | 21 ++- .../core/menu/components/menu/types.ts | 5 + .../packages/core/menu/components/types.ts | 1 + .../src/packages/core/menu/constants.ts | 1 + .../src/packages/core/menu/index.ts | 1 + .../src/packages/core/menu/manifests.ts | 6 +- .../core/menu/menu-structure/types.ts | 17 +++ ...u-tree-structure-workspace-context-base.ts | 87 ++++++++--- ...t-tree-structure-workspace-context-base.ts | 44 +++++- .../manifests.ts | 14 ++ ...idebar-menu-with-entity-actions.element.ts | 14 -- .../menu/section-sidebar-menu/constants.ts | 2 + .../global-context/constants.ts | 1 + ...tion-sidebar-menu-app-expansion.manager.ts | 23 +++ .../global-context/manifests.ts | 10 ++ ...ction-sidebar-menu.global-context.token.ts | 6 + .../section-sidebar-menu.global-context.ts | 14 ++ .../core/menu/section-sidebar-menu/index.ts | 1 + .../menu/section-sidebar-menu/manifests.ts | 18 +++ .../section-context/constants.ts | 1 + ...-sidebar-menu-section-expansion.manager.ts | 139 ++++++++++++++++++ .../section-context/manifests.ts | 10 ++ ...tion-sidebar-menu.section-context.token.ts | 8 + .../section-sidebar-menu.section-context.ts | 14 ++ .../section-sidebar-menu.element.ts | 92 +++++++++--- .../core/menu/section-sidebar-menu/types.ts | 5 + .../src/packages/core/menu/types.ts | 4 +- .../section-alias/section-alias.condition.ts | 4 +- .../default/default-section.context.ts | 8 + .../default-section.element.ts} | 26 +++- .../core/section/default/manifests.ts | 20 +++ .../packages/core/section/default/types.ts | 11 ++ .../extensions/section-context.extension.ts | 17 +++ .../section/extensions/section.extension.ts | 1 + .../packages/core/section/extensions/types.ts | 1 + .../src/packages/core/section/index.ts | 5 +- .../section-main/section-main.element.ts | 5 +- .../core/section/section.context.token.ts | 4 + .../packages/core/section/section.context.ts | 23 ++- .../tree-expansion-manager.ts | 21 ++- .../core/tree/expansion-manager/types.ts | 4 +- .../src/packages/core/tree/index.ts | 2 +- .../src/packages/core/tree/manifests.ts | 6 +- .../core/tree/tree-menu-item-default/index.ts | 1 - .../tree-menu-item-default.element.ts | 49 ------ .../core/tree/tree-menu-item/index.ts | 1 + .../core/tree/tree-menu-item/manifests.ts | 14 ++ .../tree-menu-item/tree-menu-item.element.ts | 87 +++++++++++ .../types.ts | 0 .../src/packages/core/tree/tree.element.ts | 7 + .../src/packages/core/tree/types.ts | 2 +- .../expansion/entity-expansion.manager.ts | 119 +++++++++++++++ .../events/expansion-change.event.ts | 8 + .../events/expansion-entry-collapsed.event.ts | 12 ++ .../events/expansion-entry-expanded.event.ts | 12 ++ .../core/utils/expansion/events/index.ts | 3 + .../packages/core/utils/expansion/index.ts | 4 + .../packages/core/utils/expansion/types.ts | 9 ++ .../core/utils/expansion/utils/index.ts | 1 + .../link-entity-expansion-entries.test.ts | 26 ++++ .../utils/link-entity-expansion-entries.ts | 22 +++ .../src/packages/core/utils/index.ts | 1 + .../workspace-menu-breadcrumb.element.ts | 33 ++++- .../entity-detail-workspace-base.ts | 13 +- .../src/packages/data-type/constants.ts | 1 + .../src/packages/data-type/menu/constants.ts | 1 + .../src/packages/data-type/menu/manifests.ts | 7 +- .../src/packages/dictionary/constants.ts | 1 + .../dictionary/menu-item/constants.ts | 1 + .../dictionary/menu-item/manifests.ts | 7 +- .../documents/document-types/constants.ts | 1 + .../document-types/menu/constants.ts | 1 + .../document-types/menu/manifests.ts | 7 +- .../packages/documents/documents/constants.ts | 1 + .../documents/documents/menu/constants.ts | 1 + .../documents/documents/menu/manifests.ts | 7 +- .../packages/media/media-types/constants.ts | 3 +- .../media/media-types/menu/constants.ts | 1 + .../media/media-types/menu/manifests.ts | 7 +- .../packages/media/media/menu/constants.ts | 1 + .../packages/media/media/menu/manifests.ts | 8 +- .../packages/members/member-type/constants.ts | 1 + .../members/member-type/menu/constants.ts | 1 + .../members/member-type/menu/manifests.ts | 8 +- .../templating/partial-views/constants.ts | 3 +- .../partial-views/menu/constants.ts | 1 + .../partial-views/menu/manifests.ts | 7 +- .../templating/scripts/menu/manifests.ts | 4 + .../templating/stylesheets/constants.ts | 1 + .../templating/stylesheets/menu/constants.ts | 1 + .../templating/stylesheets/menu/manifests.ts | 7 +- .../templating/templates/constants.ts | 1 + .../templating/templates/menu/constants.ts | 1 + .../templating/templates/menu/manifests.ts | 7 +- .../Content/ChildrenContent.spec.ts | 10 +- .../ContentWithAllowedChildNodes.spec.ts | 2 +- .../ContentWithListViewContent.spec.ts | 2 +- .../DataType/DataTypeFolder.spec.ts | 2 +- .../DefaultConfig/Media/ListViewMedia.spec.ts | 2 +- .../tests/DefaultConfig/Media/Media.spec.ts | 4 +- .../DocumentType/DocumentTypeFolder.spec.ts | 4 +- .../MediaType/MediaTypeFolder.spec.ts | 6 +- .../PartialView/PartialViewFolder.spec.ts | 11 +- .../Settings/Script/ScriptFolder.spec.ts | 12 +- .../Stylesheet/StylesheetFolder.spec.ts | 12 +- .../User/ContentStartNodes.spec.ts | 4 +- .../Permissions/User/MediaStartNodes.spec.ts | 4 +- .../UserGroup/ContentStartNodes.spec.ts | 4 +- .../DefaultPermissionsInContent.spec.ts | 8 +- .../GranularPermissionsInContent.spec.ts | 2 +- .../UserGroup/MediaStartNodes.spec.ts | 4 +- 138 files changed, 1521 insertions(+), 227 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/collapse-menu-item-entity-action/collapse-menu-item.entity-action.ts create mode 100644 src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/collapse-menu-item-entity-action/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/index.ts create mode 100644 src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/playground-dashboard/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/playground-dashboard/section-sidebar-menu-playground.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/expansion/is-menu-item-expansion-entry.guard.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/expansion/menu-item-expansion.manager.ts rename src/Umbraco.Web.UI.Client/src/packages/core/menu/{ => components/menu-item}/menu-item-element.interface.ts (100%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item.context.token.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item.context.ts rename src/Umbraco.Web.UI.Client/src/packages/core/menu/{ => components/menu-item}/menu-item.extension.ts (100%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/menu.context.token.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/menu.context.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/types.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-structure/types.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu-with-entity-actions/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/expansion/section-sidebar-menu-app-expansion.manager.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/section-sidebar-menu.global-context.token.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/section-sidebar-menu.global-context.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/expansion/section-sidebar-menu-section-expansion.manager.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/section-sidebar-menu.section-context.token.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/section-sidebar-menu.section-context.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/section/default/default-section.context.ts rename src/Umbraco.Web.UI.Client/src/packages/core/section/{section-default.element.ts => default/default-section.element.ts} (84%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/section/default/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/section/default/types.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/section/extensions/section-context.extension.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/section/section.context.token.ts delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item-default/index.ts delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item-default/tree-menu-item-default.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item/tree-menu-item.element.ts rename src/Umbraco.Web.UI.Client/src/packages/core/tree/{tree-menu-item-default => tree-menu-item}/types.ts (100%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/entity-expansion.manager.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/expansion-change.event.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/expansion-entry-collapsed.event.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/expansion-entry-expanded.event.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/types.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/utils/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/utils/link-entity-expansion-entries.test.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/utils/link-entity-expansion-entries.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/data-type/menu/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/dictionary/menu-item/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/document-types/menu/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/menu/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media-types/menu/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member-type/menu/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/menu/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/menu/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/templating/templates/menu/constants.ts diff --git a/src/Umbraco.Web.UI.Client/devops/module-dependencies/index.js b/src/Umbraco.Web.UI.Client/devops/module-dependencies/index.js index d6e5febf2e..39746504b5 100644 --- a/src/Umbraco.Web.UI.Client/devops/module-dependencies/index.js +++ b/src/Umbraco.Web.UI.Client/devops/module-dependencies/index.js @@ -4,7 +4,7 @@ import { createImportMap } from '../importmap/index.js'; const ILLEGAL_CORE_IMPORTS_THRESHOLD = 5; const SELF_IMPORTS_THRESHOLD = 0; -const BIDIRECTIONAL_IMPORTS_THRESHOLD = 18; +const BIDIRECTIONAL_IMPORTS_THRESHOLD = 16; const clientProjectRoot = path.resolve(import.meta.dirname, '../../'); const modulePrefix = '@umbraco-cms/backoffice/'; diff --git a/src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/collapse-menu-item-entity-action/collapse-menu-item.entity-action.ts b/src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/collapse-menu-item-entity-action/collapse-menu-item.entity-action.ts new file mode 100644 index 0000000000..7df5c2dc25 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/collapse-menu-item-entity-action/collapse-menu-item.entity-action.ts @@ -0,0 +1,11 @@ +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UMB_MENU_ITEM_CONTEXT } from '@umbraco-cms/backoffice/menu'; + +export class ExampleCollapseMenuItemEntityAction extends UmbEntityActionBase { + override async execute() { + const context = await this.getContext(UMB_MENU_ITEM_CONTEXT); + context?.expansion.collapseAll(); + } +} + +export { ExampleCollapseMenuItemEntityAction as api }; diff --git a/src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/collapse-menu-item-entity-action/manifests.ts b/src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/collapse-menu-item-entity-action/manifests.ts new file mode 100644 index 0000000000..69123c7f0c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/collapse-menu-item-entity-action/manifests.ts @@ -0,0 +1,15 @@ +export const manifests: Array = [ + { + type: 'entityAction', + kind: 'default', + alias: 'Umb.EntityAction.Document.MenuItem.Collapse', + name: 'Collapse Document Menu Item', + api: () => import('./collapse-menu-item.entity-action.js'), + forEntityTypes: ['document-type-root', 'media-type-root', 'member-type-root', 'data-type-root'], + weight: -10, + meta: { + label: 'Collapse Menu Item', + icon: 'icon-wand', + }, + }, +]; diff --git a/src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/index.ts b/src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/index.ts new file mode 100644 index 0000000000..c911275efd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/index.ts @@ -0,0 +1,4 @@ +import { manifests as playgroundDashboardManifests } from './playground-dashboard/manifests.js'; +import { manifests as collapseMenuItemManifests } from './collapse-menu-item-entity-action/manifests.js'; + +export const manifests: Array = [...playgroundDashboardManifests, ...collapseMenuItemManifests]; diff --git a/src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/playground-dashboard/manifests.ts b/src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/playground-dashboard/manifests.ts new file mode 100644 index 0000000000..d9d47be8b0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/playground-dashboard/manifests.ts @@ -0,0 +1,14 @@ +export const manifests: Array = [ + { + type: 'dashboard', + kind: 'default', + name: 'Example Section Sidebar Menu Playground Dashboard', + alias: 'Example.Dashboard.SectionSidebarMenuPlayground', + element: () => import('./section-sidebar-menu-playground.element.js'), + weight: 3000, + meta: { + label: 'Section Sidebar Menu Playground', + pathname: 'section-sidebar-menu-playground', + }, + }, +]; diff --git a/src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/playground-dashboard/section-sidebar-menu-playground.element.ts b/src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/playground-dashboard/section-sidebar-menu-playground.element.ts new file mode 100644 index 0000000000..5f82b4fc45 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/examples/section-sidebar-menu-expansion/playground-dashboard/section-sidebar-menu-playground.element.ts @@ -0,0 +1,102 @@ +import { html, customElement, LitElement, css, state, repeat } from '@umbraco-cms/backoffice/external/lit'; +import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; +import { + UMB_SECTION_SIDEBAR_MENU_GLOBAL_CONTEXT, + UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT, + type UmbSectionMenuItemExpansionEntryModel, +} from '@umbraco-cms/backoffice/menu'; + +@customElement('example-section-sidebar-menu-playground-dashboard') +export class ExampleSectionSidebarMenuPlaygroundDashboard extends UmbElementMixin(LitElement) { + #globalContext?: typeof UMB_SECTION_SIDEBAR_MENU_GLOBAL_CONTEXT.TYPE; + #sectionContext?: typeof UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT.TYPE; + + @state() + private _globalExpansion: Array = []; + + @state() + private _sectionExpansion: Array = []; + + constructor() { + super(); + + this.consumeContext(UMB_SECTION_SIDEBAR_MENU_GLOBAL_CONTEXT, (section) => { + this.#globalContext = section; + this.#observeGlobalExpansion(); + }); + + this.consumeContext(UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT, (section) => { + this.#sectionContext = section; + this.#observeSectionExpansion(); + }); + } + + #observeGlobalExpansion() { + this.observe(this.#globalContext?.expansion.expansion, (items) => { + this._globalExpansion = items || []; + }); + } + + #observeSectionExpansion() { + this.observe(this.#sectionContext?.expansion.expansion, (items) => { + this._sectionExpansion = items || []; + }); + } + + #onCloseItem(event: PointerEvent, item: UmbSectionMenuItemExpansionEntryModel) { + event.stopPropagation(); + this.#sectionContext?.expansion.collapseItem(item); + } + + #onCollapseSection() { + this.#sectionContext?.expansion.collapseAll(); + } + + override render() { + return html` + + + + Collapse All + ${repeat( + this._sectionExpansion, + (item) => item.entityType + item.unique, + (item) => this.#renderItem(item), + )} + + + ${repeat( + this._globalExpansion, + (item) => item.entityType + item.unique, + (item) => this.#renderItem(item), + )} + + `; + } + + #renderItem(item: UmbSectionMenuItemExpansionEntryModel) { + return html` + this.#onCloseItem(event, item)}>Close + `; + } + + static override styles = [ + css` + :host { + display: block; + padding: var(--uui-size-layout-1); + } + `, + ]; +} + +export { ExampleSectionSidebarMenuPlaygroundDashboard as element }; + +declare global { + interface HTMLElementTagNameMap { + 'example-section-sidebar-menu-playground-dashboard': ExampleSectionSidebarMenuPlaygroundDashboard; + } +} 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 0550e6c52c..70f1a9202b 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 @@ -78,6 +78,7 @@ export class UmbBackofficeMainElement extends UmbLitElement { this._routes = newRoutes; } + // TODO: v17. Remove this section context when we have api's as part of the section manifest. private _provideSectionContext(sectionManifest: ManifestSection) { if (!this._sectionContext) { this._sectionContext = new UmbSectionContext(this); diff --git a/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-detail-workspace-base.ts index e0d12dcd46..4459544348 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-detail-workspace-base.ts @@ -941,11 +941,20 @@ export abstract class UmbContentDetailWorkspaceContextBase< if (!eventContext) { throw new Error('Event context is missing'); } - const event = new UmbRequestReloadChildrenOfEntityEvent({ + + const reloadStructureEvent = new UmbRequestReloadStructureForEntityEvent({ entityType: parent.entityType, unique: parent.unique, }); - eventContext.dispatchEvent(event); + + eventContext.dispatchEvent(reloadStructureEvent); + + const reloadChildrenEvent = new UmbRequestReloadChildrenOfEntityEvent({ + entityType: parent.entityType, + unique: parent.unique, + }); + + eventContext.dispatchEvent(reloadChildrenEvent); } async #update(variantIds: Array, saveData: DetailModelType) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/components/extension-slot/extension-slot.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/components/extension-slot/extension-slot.element.ts index 4cbd31df80..28cdbc9897 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/components/extension-slot/extension-slot.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/components/extension-slot/extension-slot.element.ts @@ -88,6 +88,18 @@ export class UmbExtensionSlotElement extends UmbLitElement { } #props?: Record = {}; + @property({ type: Object, attribute: false }) + set events(newVal: Record void> | undefined) { + this.#events = newVal; + if (this.#extensionsController) { + this.#addEventListenersToExtensionElement(); + } + } + get events(): Record void> | undefined { + return this.#events; + } + #events?: Record void> = {}; + @property({ type: String, attribute: 'default-element' }) public defaultElement?: string; @@ -113,6 +125,7 @@ export class UmbExtensionSlotElement extends UmbLitElement { } override disconnectedCallback(): void { // _permitted is reset as the extensionsController fires a callback on destroy. + this.#removeEventListenersFromExtensionElement(); this.#attached = false; this.#extensionsController?.destroy(); this.#extensionsController = undefined; @@ -130,6 +143,7 @@ export class UmbExtensionSlotElement extends UmbLitElement { this.filter, (extensionControllers) => { this._permitted = extensionControllers; + this.#addEventListenersToExtensionElement(); }, undefined, // We can leave the alias undefined as we destroy this our selfs. this.defaultElement, @@ -158,6 +172,36 @@ export class UmbExtensionSlotElement extends UmbLitElement { return this.renderMethod ? this.renderMethod(ext, i) : ext.component; }; + #addEventListenersToExtensionElement() { + this._permitted?.forEach((initializer) => { + const component = initializer.component as HTMLElement; + if (!component) return; + + const events = this.#events; + if (!events) return; + + this.#removeEventListenersFromExtensionElement(); + + Object.entries(events).forEach(([eventName, handler]) => { + component.addEventListener(eventName, handler); + }); + }); + } + + #removeEventListenersFromExtensionElement() { + this._permitted?.forEach((initializer) => { + const component = initializer.component as HTMLElement; + if (!component) return; + + const events = this.#events; + if (!events) return; + + Object.entries(events).forEach(([eventName, handler]) => { + component.removeEventListener(eventName, handler); + }); + }); + } + static override styles = css` :host { display: contents; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/index.ts index c73d5980e7..77dbe4fc3e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/index.ts @@ -2,6 +2,8 @@ export * from './conditions/index.js'; export * from './initializers/index.js'; export * from './registry.js'; export * from './utils/index.js'; +export * from './components/index.js'; + export type * from './models/types.js'; export type * from './extensions/types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/action/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/action/types.ts index 6e60d0bfdd..1da233a9bd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/action/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/action/types.ts @@ -1,4 +1,4 @@ -import type { MetaMenuItem } from '../../../menu-item.extension.js'; +import type { MetaMenuItem } from '../menu-item.extension.js'; import type { ManifestElementAndApi, ManifestWithDynamicConditions } from '@umbraco-cms/backoffice/extension-api'; import type { UmbAction } from '@umbraco-cms/backoffice/action'; import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/constants.ts new file mode 100644 index 0000000000..a86e19fbb3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/constants.ts @@ -0,0 +1 @@ +export * from './menu-item.context.token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/expansion/is-menu-item-expansion-entry.guard.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/expansion/is-menu-item-expansion-entry.guard.ts new file mode 100644 index 0000000000..84c6d2441e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/expansion/is-menu-item-expansion-entry.guard.ts @@ -0,0 +1,16 @@ +import type { UmbMenuItemExpansionEntryModel } from '../../types.js'; + +/** + * Checks if the provided object is a Menu Item Expansion Entry. + * @param {object } object - The object to check. + * @returns {boolean } True if the object is a Menu Item Expansion Entry, false otherwise. + */ +export function isMenuItemExpansionEntry(object: unknown): object is UmbMenuItemExpansionEntryModel { + return ( + typeof object === 'object' && + object !== null && + 'entityType' in object && + 'unique' in object && + 'menuItemAlias' in object + ); +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/expansion/menu-item-expansion.manager.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/expansion/menu-item-expansion.manager.ts new file mode 100644 index 0000000000..b02938e46f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/expansion/menu-item-expansion.manager.ts @@ -0,0 +1,132 @@ +import type { UmbMenuItemExpansionEntryModel } from '../../menu/types.js'; +import { UMB_MENU_CONTEXT } from '../../menu/constants.js'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { + createObservablePart, + type UmbObserverController, + type Observable, +} from '@umbraco-cms/backoffice/observable-api'; +import { UmbEntityExpansionManager, type UmbEntityExpansionModel } from '@umbraco-cms/backoffice/utils'; + +/** + * Manages the expansion state of a menu item + * @exports + * @class UmbMenuItemExpansionManager + * @augments {UmbControllerBase} + */ +export class UmbMenuItemExpansionManager extends UmbControllerBase { + #manager = new UmbEntityExpansionManager(this); + public readonly expansion = this.#manager.expansion; + + #menuItemAlias?: string; + #menuContext?: typeof UMB_MENU_CONTEXT.TYPE; + #observerController?: UmbObserverController; + + constructor(host: UmbControllerHost) { + super(host); + + this.consumeContext(UMB_MENU_CONTEXT, (menuContext) => { + this.#menuContext = menuContext; + this.#observeMenuExpansion(); + }); + } + + #observeMenuExpansion() { + if (!this.#menuContext || !this.#menuItemAlias) { + this.#observerController?.destroy(); + return; + } + + this.#observerController = this.observe( + createObservablePart( + this.#menuContext.expansion.expansion, + (items: Array) => + items?.filter((item) => item.menuItemAlias === this.#menuItemAlias) || [], + ), + (itemsForMenuItem) => { + this.#manager.setExpansion(itemsForMenuItem); + }, + 'observeMenuExpension' + ); + } + + setMenuItemAlias(alias: string | undefined): void { + this.#menuItemAlias = alias; + this.#observeMenuExpansion(); + } + + /** + * Checks if an entry is expanded + * @param {UmbMenuItemExpansionEntryModel} entry The entry to check + * @returns {Observable} True if the entry is expanded + * @memberof UmbSectionSidebarMenuSectionExpansionManager + */ + isExpanded(entry: UmbMenuItemExpansionEntryModel): Observable { + return this.#manager.isExpanded(entry); + } + + /** + * Sets the expansion state + * @param {UmbEntityExpansionModel | undefined} expansion The expansion state + * @memberof UmbSectionSidebarMenuSectionExpansionManager + * @returns {void} + */ + setExpansion(expansion: UmbEntityExpansionModel): void { + this.#manager.setExpansion(expansion); + this.#menuContext?.expansion.setExpansion(expansion); + } + + /** + * Gets the expansion state + * @memberof UmbSectionSidebarMenuSectionExpansionManager + * @returns {UmbEntityExpansionModel} The expansion state + */ + getExpansion(): UmbEntityExpansionModel { + return this.#manager.getExpansion(); + } + + /** + * Opens a menu item + * @param {UmbMenuItemExpansionEntryModel} entry The item to open + * @memberof UmbSectionSidebarMenuSectionExpansionManager + * @returns {Promise} + */ + public async expandItem(entry: UmbMenuItemExpansionEntryModel): Promise { + this.#manager.expandItem(entry); + this.#menuContext?.expansion.expandItem(entry); + } + + /** + * Expands multiple entities + * @param {UmbEntityExpansionModel} entries The entities to open + * @memberof UmbEntityExpansionManager + * @returns {void} + */ + public expandItems(entries: UmbEntityExpansionModel): void { + this.#manager.expandItems(entries); + this.#menuContext?.expansion.expandItems(entries); + } + + /** + * Closes a menu item + * @param {UmbMenuItemExpansionEntryModel} entry The item to close + * @memberof UmbSectionSidebarMenuSectionExpansionManager + * @returns {Promise} + */ + public async collapseItem(entry: UmbMenuItemExpansionEntryModel): Promise { + this.#manager.collapseItem(entry); + this.#menuContext?.expansion.collapseItem(entry); + } + + /** + * Closes all menu items + * @memberof UmbSectionSidebarMenuSectionExpansionManager + * @returns {Promise} + */ + public async collapseAll(): Promise { + const localEntries = this.#manager.getExpansion(); + this.#manager.collapseAll(); + this.#menuContext?.expansion.collapseItems(localEntries); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/index.ts index 6b2eaef349..80ecd73a78 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/index.ts @@ -1,2 +1,3 @@ export * from './menu-item-default.element.js'; +export * from './constants.js'; export * from './action/action-menu-item.api.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/link/link-menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/link/link-menu-item.element.ts index b902cd18e2..0aeab0024f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/link/link-menu-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/link/link-menu-item.element.ts @@ -1,4 +1,4 @@ -import type { UmbMenuItemElement } from '../../../menu-item-element.interface.js'; +import type { UmbMenuItemElement } from '../menu-item-element.interface.js'; import type { ManifestMenuItemLinkKind } from './types.js'; import { customElement, html, property } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/link/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/link/types.ts index 2bc68ac163..f5be9cefbe 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/link/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/link/types.ts @@ -1,4 +1,4 @@ -import type { ManifestMenuItem, MetaMenuItem } from '../../../menu-item.extension.js'; +import type { ManifestMenuItem, MetaMenuItem } from '../menu-item.extension.js'; export interface ManifestMenuItemLinkKind extends ManifestMenuItem { type: 'menuItem'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item-default.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item-default.element.ts index 269133145c..035c5f972c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item-default.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item-default.element.ts @@ -1,5 +1,5 @@ -import type { UmbMenuItemElement } from '../../menu-item-element.interface.js'; -import type { ManifestMenuItem } from '../../menu-item.extension.js'; +import type { UmbMenuItemElement } from './menu-item-element.interface.js'; +import type { ManifestMenuItem } from './menu-item.extension.js'; import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UMB_SECTION_CONTEXT } from '@umbraco-cms/backoffice/section'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-item-element.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item-element.interface.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-item-element.interface.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item-element.interface.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item.context.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item.context.token.ts new file mode 100644 index 0000000000..f51e5f1042 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item.context.token.ts @@ -0,0 +1,4 @@ +import type { UmbDefaultMenuItemContext } from './menu-item.context.js'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; + +export const UMB_MENU_ITEM_CONTEXT = new UmbContextToken('UmbMenuItemContext'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item.context.ts new file mode 100644 index 0000000000..d20e137b1b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item.context.ts @@ -0,0 +1,22 @@ +import type { ManifestMenuItem } from '../../types.js'; +import { UmbMenuItemExpansionManager } from './expansion/menu-item-expansion.manager.js'; +import { UMB_MENU_ITEM_CONTEXT } from './menu-item.context.token.js'; +import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbDefaultMenuItemContext extends UmbContextBase { + public readonly expansion = new UmbMenuItemExpansionManager(this); + + #manifest?: ManifestMenuItem | undefined; + public get manifest(): ManifestMenuItem | undefined { + return this.#manifest; + } + public set manifest(value: ManifestMenuItem | undefined) { + this.#manifest = value; + this.expansion.setMenuItemAlias(value?.alias); + } + + constructor(host: UmbControllerHost) { + super(host, UMB_MENU_ITEM_CONTEXT); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-item.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item.extension.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-item.extension.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/menu-item.extension.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/types.ts index 1e39b8bf82..ed3511d796 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/types.ts @@ -1,2 +1,4 @@ export type * from './action/types.js'; export type * from './link/types.js'; +export type * from './menu-item-element.interface.js'; +export type * from './menu-item.extension.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/constants.ts new file mode 100644 index 0000000000..95d903ca23 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/constants.ts @@ -0,0 +1 @@ +export * from './menu.context.token.js'; 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 242a263f7a..be0be98f97 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 +1,2 @@ export * from './menu.element.js'; +export * from './constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/menu.context.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/menu.context.token.ts new file mode 100644 index 0000000000..6385f34578 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/menu.context.token.ts @@ -0,0 +1,4 @@ +import type { UmbDefaultMenuContext } from './menu.context.js'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; + +export const UMB_MENU_CONTEXT = new UmbContextToken('UmbMenuContext'); 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 new file mode 100644 index 0000000000..671373df7c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/menu.context.ts @@ -0,0 +1,13 @@ +import { UMB_MENU_CONTEXT } from './menu.context.token.js'; +import type { UmbMenuItemExpansionEntryModel } from './types.js'; +import { UmbEntityExpansionManager } from '@umbraco-cms/backoffice/utils'; +import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbDefaultMenuContext extends UmbContextBase { + public readonly expansion = new UmbEntityExpansionManager(this); + + constructor(host: UmbControllerHost) { + super(host, 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 7e051db0e0..9ed2c2d95d 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 @@ -1,7 +1,11 @@ import type { ManifestMenu } from '../../menu.extension.js'; -import type { ManifestMenuItem } from '../../menu-item.extension.js'; +import { UmbDefaultMenuItemContext } from '../menu-item/menu-item.context.js'; +import type { ManifestMenuItem } from '../menu-item/types.js'; +import { UmbDefaultMenuContext } from './menu.context.js'; +import type { UmbMenuItemExpansionEntryModel } from './types.js'; import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import type { UmbEntityExpansionModel } from '@umbraco-cms/backoffice/utils'; import '../menu-item/menu-item-default.element.js'; @@ -10,13 +14,24 @@ export class UmbMenuElement extends UmbLitElement { @property({ attribute: false }) manifest?: ManifestMenu; + public get expansion(): UmbEntityExpansionModel { + return this.#context.expansion.getExpansion(); + } + public set expansion(value: UmbEntityExpansionModel) { + this.#context.expansion.setExpansion(value); + } + + #context = new UmbDefaultMenuContext(this); + override render() { + //TODO: We should probably have resolved the MENU ITEM CONTEXT not by providing it not as an API, currently this work cause menu items does not have APIs as of their manifest. But if they do this, this would be a problem. [NL] return html` - items.meta.menus.includes(this.manifest!.alias)}> - + `; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/types.ts new file mode 100644 index 0000000000..dc3d827be2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu/types.ts @@ -0,0 +1,5 @@ +import type { UmbEntityExpansionEntryModel } from '@umbraco-cms/backoffice/utils'; + +export interface UmbMenuItemExpansionEntryModel extends UmbEntityExpansionEntryModel { + menuItemAlias: string; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/types.ts index c858b14791..e03ad31735 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/types.ts @@ -1 +1,2 @@ export type * from './menu-item/types.js'; +export type * from './menu/types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/constants.ts new file mode 100644 index 0000000000..fd7b96c0f8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/constants.ts @@ -0,0 +1 @@ +export * from './section-sidebar-menu/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/index.ts index c7d6c36f9e..cce4aa408e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/index.ts @@ -3,6 +3,7 @@ export * from './menu-tree-structure-workspace-context-base.js'; export * from './menu-structure-workspace-context.context-token.js'; export * from './menu-variant-structure-workspace-context.context-token.js'; export * from './menu-variant-tree-structure-workspace-context-base.js'; +export * from './constants.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/manifests.ts index a9d3417c61..350fea31bc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/manifests.ts @@ -1,8 +1,12 @@ -import { manifests as menuItemManifests } from './components/menu-item/manifests.js'; import { manifest as menuAliasConditionManifest } from './conditions/menu-alias.condition.js'; +import { manifests as menuItemManifests } from './components/menu-item/manifests.js'; +import { manifests as sectionSidebarMenuManifests } from './section-sidebar-menu/manifests.js'; +import { manifests as sectionSidebarMenuWithEntityActionsManifests } from './section-sidebar-menu-with-entity-actions/manifests.js'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; export const manifests: Array = [ ...menuItemManifests, + ...sectionSidebarMenuManifests, + ...sectionSidebarMenuWithEntityActionsManifests, menuAliasConditionManifest, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-structure/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-structure/types.ts new file mode 100644 index 0000000000..08be58ee57 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-structure/types.ts @@ -0,0 +1,17 @@ +import type { ManifestWorkspaceContext } from '@umbraco-cms/backoffice/workspace'; + +export interface ManifestWorkspaceContextMenuStructureKind extends ManifestWorkspaceContext { + type: 'workspaceContext'; + kind: 'menuStructure'; + meta: MetaWorkspaceContextMenuStructureKind; +} + +export interface MetaWorkspaceContextMenuStructureKind { + menuItemAlias: string; +} + +declare global { + interface UmbExtensionManifestMap { + umbManifestWorkspaceContextMenuStructureKind: ManifestWorkspaceContextMenuStructureKind; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-tree-structure-workspace-context-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-tree-structure-workspace-context-base.ts index 21df3dcb27..fabaaccd80 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-tree-structure-workspace-context-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-tree-structure-workspace-context-base.ts @@ -1,5 +1,6 @@ -import type { UmbStructureItemModel } from './types.js'; +import type { ManifestWorkspaceContextMenuStructureKind, UmbStructureItemModel } from './types.js'; import { UMB_MENU_STRUCTURE_WORKSPACE_CONTEXT } from './menu-structure-workspace-context.context-token.js'; +import { UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT } from './section-sidebar-menu/index.js'; import type { UmbTreeRepository, UmbTreeItemModel, UmbTreeRootModel } from '@umbraco-cms/backoffice/tree'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; @@ -7,6 +8,8 @@ import { UMB_SUBMITTABLE_TREE_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/back import { UmbArrayState, UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbAncestorsEntityContext, UmbParentEntityContext, type UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import { linkEntityExpansionEntries } from '@umbraco-cms/backoffice/utils'; +import { UMB_MODAL_CONTEXT } from '@umbraco-cms/backoffice/modal'; interface UmbMenuTreeStructureWorkspaceContextBaseArgs { treeRepositoryAlias: string; @@ -14,6 +17,8 @@ interface UmbMenuTreeStructureWorkspaceContextBaseArgs { // TODO: introduce base class for all menu structure workspaces to handle ancestors and parent export abstract class UmbMenuTreeStructureWorkspaceContextBase extends UmbContextBase { + manifest?: ManifestWorkspaceContextMenuStructureKind; + #workspaceContext?: typeof UMB_SUBMITTABLE_TREE_ENTITY_WORKSPACE_CONTEXT.TYPE; #args: UmbMenuTreeStructureWorkspaceContextBaseArgs; @@ -28,6 +33,8 @@ export abstract class UmbMenuTreeStructureWorkspaceContextBase extends UmbContex #parentContext = new UmbParentEntityContext(this); #ancestorContext = new UmbAncestorsEntityContext(this); + #sectionSidebarMenuContext?: typeof UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT.TYPE; + #isModalContext: boolean = false; constructor(host: UmbControllerHost, args: UmbMenuTreeStructureWorkspaceContextBaseArgs) { super(host, UMB_MENU_STRUCTURE_WORKSPACE_CONTEXT); @@ -35,18 +42,45 @@ export abstract class UmbMenuTreeStructureWorkspaceContextBase extends UmbContex this.provideContext('UmbMenuStructureWorkspaceContext', this); this.#args = args; + this.consumeContext(UMB_MODAL_CONTEXT, (modalContext) => { + this.#isModalContext = modalContext !== undefined; + }); + + this.consumeContext(UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT, (instance) => { + this.#sectionSidebarMenuContext = instance; + }); + this.consumeContext(UMB_SUBMITTABLE_TREE_ENTITY_WORKSPACE_CONTEXT, (instance) => { this.#workspaceContext = instance; this.observe(this.#workspaceContext?.unique, (value) => { if (!value) return; this.#requestStructure(); }); + + this.observe(this.#workspaceContext?.isNew, (value) => { + if (value === undefined) return; + this.#requestStructure(); + }); }); } async #requestStructure() { + const isNew = this.#workspaceContext?.getIsNew(); + const uniqueObservable = isNew + ? this.#workspaceContext?._internal_createUnderParentEntityUnique + : this.#workspaceContext?.unique; + const entityTypeObservable = isNew + ? this.#workspaceContext?._internal_createUnderParentEntityType + : this.#workspaceContext?.entityType; + let structureItems: Array = []; + const unique = (await this.observe(uniqueObservable, () => {})?.asPromise()) as string; + if (unique === undefined) throw new Error('Unique is not available'); + + const entityType = (await this.observe(entityTypeObservable, () => {})?.asPromise()) as string; + if (!entityType) throw new Error('Entity type is not available'); + const treeRepository = await createExtensionApiByAlias>( this, this.#args.treeRepositoryAlias, @@ -65,22 +99,10 @@ export abstract class UmbMenuTreeStructureWorkspaceContextBase extends UmbContex ]; } - const isNew = this.#workspaceContext?.getIsNew(); - - const entityTypeObservable = isNew - ? this.#workspaceContext?._internal_createUnderParentEntityType - : this.#workspaceContext?.entityType; - const entityType = (await this.observe(entityTypeObservable, () => {})?.asPromise()) as string; - if (!entityType) throw new Error('Entity type is not available'); + const isRoot = entityType === root?.entityType; // If the entity type is different from the root entity type, then we can request the ancestors. - if (entityType !== root?.entityType) { - const uniqueObservable = isNew - ? this.#workspaceContext?._internal_createUnderParentEntityUnique - : this.#workspaceContext?.unique; - const unique = (await this.observe(uniqueObservable, () => {})?.asPromise()) as string; - if (!unique) throw new Error('Unique is not available'); - + if (!isRoot) { const { data } = await treeRepository.requestTreeItemAncestors({ treeItem: { unique, entityType } }); if (data) { @@ -93,13 +115,19 @@ export abstract class UmbMenuTreeStructureWorkspaceContextBase extends UmbContex }; }); - structureItems.push(...ancestorItems); - - this.#structure.setValue(structureItems); - this.#setParentData(structureItems); this.#setAncestorData(data); + + structureItems.push(...ancestorItems); } } + + this.#structure.setValue(structureItems); + this.#setParentData(structureItems); + + const menuItemAlias = this.manifest?.meta?.menuItemAlias; + if (menuItemAlias && !this.#isModalContext) { + this.#expandSectionSidebarMenu(structureItems, menuItemAlias); + } } #setParentData(structureItems: Array) { @@ -139,4 +167,25 @@ export abstract class UmbMenuTreeStructureWorkspaceContextBase extends UmbContex this.#ancestorContext.setAncestors(ancestorEntities); } + + #expandSectionSidebarMenu(structureItems: Array, menuItemAlias: string) { + const linkedEntries = linkEntityExpansionEntries(structureItems); + // Filter out the current entity as we don't want to expand it + const expandableItems = linkedEntries.filter((item) => item.unique !== this.#workspaceContext?.getUnique()); + const expandableItemsWithMenuItem = expandableItems.map((item) => { + return { + ...item, + menuItemAlias, + }; + }); + this.#sectionSidebarMenuContext?.expansion.expandItems(expandableItemsWithMenuItem); + } + + override destroy(): void { + super.destroy(); + this.#structure.destroy(); + this.#parent.destroy(); + this.#parentContext.destroy(); + this.#ancestorContext.destroy(); + } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-variant-tree-structure-workspace-context-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-variant-tree-structure-workspace-context-base.ts index db207951b0..3ef07138e2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-variant-tree-structure-workspace-context-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/menu-variant-tree-structure-workspace-context-base.ts @@ -1,5 +1,6 @@ -import type { UmbVariantStructureItemModel } from './types.js'; +import type { ManifestWorkspaceContextMenuStructureKind, UmbVariantStructureItemModel } from './types.js'; import { UMB_MENU_VARIANT_STRUCTURE_WORKSPACE_CONTEXT } from './menu-variant-structure-workspace-context.context-token.js'; +import { UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT } from './section-sidebar-menu/section-context/section-sidebar-menu.section-context.token.js'; import type { UmbTreeItemModel, UmbTreeRepository, UmbTreeRootModel } from '@umbraco-cms/backoffice/tree'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; @@ -7,6 +8,8 @@ import { UmbArrayState, UmbObjectState } from '@umbraco-cms/backoffice/observabl import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbAncestorsEntityContext, UmbParentEntityContext, type UmbEntityModel } from '@umbraco-cms/backoffice/entity'; import { UMB_SUBMITTABLE_TREE_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace'; +import { linkEntityExpansionEntries } from '@umbraco-cms/backoffice/utils'; +import { UMB_MODAL_CONTEXT } from '@umbraco-cms/backoffice/modal'; interface UmbMenuVariantTreeStructureWorkspaceContextBaseArgs { treeRepositoryAlias: string; @@ -14,7 +17,8 @@ interface UmbMenuVariantTreeStructureWorkspaceContextBaseArgs { // TODO: introduce base class for all menu structure workspaces to handle ancestors and parent export abstract class UmbMenuVariantTreeStructureWorkspaceContextBase extends UmbContextBase { - // + manifest?: ManifestWorkspaceContextMenuStructureKind; + #workspaceContext?: typeof UMB_SUBMITTABLE_TREE_ENTITY_WORKSPACE_CONTEXT.TYPE; #args: UmbMenuVariantTreeStructureWorkspaceContextBaseArgs; @@ -29,6 +33,8 @@ export abstract class UmbMenuVariantTreeStructureWorkspaceContextBase extends Um #parentContext = new UmbParentEntityContext(this); #ancestorContext = new UmbAncestorsEntityContext(this); + #sectionSidebarMenuContext?: typeof UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT.TYPE; + #isModalContext: boolean = false; public readonly IS_MENU_VARIANT_STRUCTURE_WORKSPACE_CONTEXT = true; @@ -38,6 +44,14 @@ export abstract class UmbMenuVariantTreeStructureWorkspaceContextBase extends Um this.provideContext('UmbMenuStructureWorkspaceContext', this); this.#args = args; + this.consumeContext(UMB_MODAL_CONTEXT, (modalContext) => { + this.#isModalContext = modalContext !== undefined; + }); + + this.consumeContext(UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT, (instance) => { + this.#sectionSidebarMenuContext = instance; + }); + this.consumeContext(UMB_SUBMITTABLE_TREE_ENTITY_WORKSPACE_CONTEXT, (instance) => { this.#workspaceContext = instance; this.observe( @@ -108,6 +122,11 @@ export abstract class UmbMenuVariantTreeStructureWorkspaceContextBase extends Um this.#structure.setValue(structureItems); this.#setParentData(structureItems); this.#setAncestorData(data); + + const menuItemAlias = this.manifest?.meta?.menuItemAlias; + if (menuItemAlias && !this.#isModalContext) { + this.#expandSectionSidebarMenu(structureItems, menuItemAlias); + } } } @@ -148,4 +167,25 @@ export abstract class UmbMenuVariantTreeStructureWorkspaceContextBase extends Um this.#ancestorContext.setAncestors(ancestorEntities); } + + #expandSectionSidebarMenu(structureItems: Array, menuItemAlias: string) { + const linkedEntries = linkEntityExpansionEntries(structureItems); + // Filter out the current entity as we don't want to expand it + const expandableItems = linkedEntries.filter((item) => item.unique !== this.#workspaceContext?.getUnique()); + const expandableItemsWithMenuItem = expandableItems.map((item) => { + return { + ...item, + menuItemAlias, + }; + }); + this.#sectionSidebarMenuContext?.expansion.expandItems(expandableItemsWithMenuItem); + } + + override destroy(): void { + super.destroy(); + this.#structure.destroy(); + this.#parent.destroy(); + this.#parentContext.destroy(); + this.#ancestorContext.destroy(); + } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu-with-entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu-with-entity-actions/manifests.ts new file mode 100644 index 0000000000..4d7249e76c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu-with-entity-actions/manifests.ts @@ -0,0 +1,14 @@ +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + { + type: 'kind', + alias: 'Umb.Kind.SectionSidebarAppMenuWithEntityActions', + matchKind: 'menuWithEntityActions', + matchType: 'sectionSidebarApp', + manifest: { + type: 'sectionSidebarApp', + element: () => import('./section-sidebar-menu-with-entity-actions.element.js'), + }, + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu-with-entity-actions/section-sidebar-menu-with-entity-actions.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu-with-entity-actions/section-sidebar-menu-with-entity-actions.element.ts index adce591646..f7c885fc10 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu-with-entity-actions/section-sidebar-menu-with-entity-actions.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu-with-entity-actions/section-sidebar-menu-with-entity-actions.element.ts @@ -1,22 +1,8 @@ import { UmbSectionSidebarMenuElement } from '../section-sidebar-menu/section-sidebar-menu.element.js'; import type { ManifestSectionSidebarAppMenuWithEntityActionsKind } from '../section-sidebar-menu/types.js'; import { css, html, customElement, type PropertyValues, state } from '@umbraco-cms/backoffice/external/lit'; -import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; -import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { UmbParentEntityContext } from '@umbraco-cms/backoffice/entity'; -const manifestWithEntityActions: UmbExtensionManifestKind = { - type: 'kind', - alias: 'Umb.Kind.SectionSidebarAppMenuWithEntityActions', - matchKind: 'menuWithEntityActions', - matchType: 'sectionSidebarApp', - manifest: { - type: 'sectionSidebarApp', - elementName: 'umb-section-sidebar-menu-with-entity-actions', - }, -}; -umbExtensionsRegistry.register(manifestWithEntityActions); - @customElement('umb-section-sidebar-menu-with-entity-actions') export class UmbSectionSidebarMenuWithEntityActionsElement extends UmbSectionSidebarMenuElement { @state() diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/constants.ts new file mode 100644 index 0000000000..125299d13a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/constants.ts @@ -0,0 +1,2 @@ +export * from './global-context/constants.js'; +export * from './section-context/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/constants.ts new file mode 100644 index 0000000000..b559697700 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/constants.ts @@ -0,0 +1 @@ +export * from './section-sidebar-menu.global-context.token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/expansion/section-sidebar-menu-app-expansion.manager.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/expansion/section-sidebar-menu-app-expansion.manager.ts new file mode 100644 index 0000000000..9e58ecca59 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/expansion/section-sidebar-menu-app-expansion.manager.ts @@ -0,0 +1,23 @@ +import type { UmbSectionMenuItemExpansionEntryModel } from '../../types.js'; +import type { Observable } from '@umbraco-cms/backoffice/observable-api'; +import { UmbEntityExpansionManager } from '@umbraco-cms/backoffice/utils'; + +/** + * Manages the expansion state of a section sidebar menu. + * @exports + * @class UmbSectionSidebarMenuAppExpansionManager + * @augments {UmbControllerBase} + */ +export class UmbSectionSidebarMenuAppExpansionManager extends UmbEntityExpansionManager { + /** + * Returns an observable of the expansion state filtered by section alias. + * @param {string} sectionAlias The alias of the section to filter by. + * @returns {Observable} An observable of the expansion state for the specified section alias. + * @memberof UmbSectionSidebarMenuAppExpansionManager + */ + expansionBySectionAlias(sectionAlias: string): Observable { + return this._expansion.asObservablePart((entries) => + entries.filter((entry) => entry.sectionAlias === sectionAlias), + ); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/manifests.ts new file mode 100644 index 0000000000..1812e1d5f6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/manifests.ts @@ -0,0 +1,10 @@ +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + { + type: 'globalContext', + alias: 'Umb.GlobalContext.SectionSidebarMenu', + name: 'Section Sidebar Menu Global Context', + api: () => import('./section-sidebar-menu.global-context.js'), + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/section-sidebar-menu.global-context.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/section-sidebar-menu.global-context.token.ts new file mode 100644 index 0000000000..20c8eb36fa --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/section-sidebar-menu.global-context.token.ts @@ -0,0 +1,6 @@ +import type { UmbSectionSidebarMenuGlobalContext } from './section-sidebar-menu.global-context.js'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; + +export const UMB_SECTION_SIDEBAR_MENU_GLOBAL_CONTEXT = new UmbContextToken( + 'UmbSectionSidebarMenuGlobalContext', +); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/section-sidebar-menu.global-context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/section-sidebar-menu.global-context.ts new file mode 100644 index 0000000000..afcd007487 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/global-context/section-sidebar-menu.global-context.ts @@ -0,0 +1,14 @@ +import { UMB_SECTION_SIDEBAR_MENU_GLOBAL_CONTEXT } from './section-sidebar-menu.global-context.token.js'; +import { UmbSectionSidebarMenuAppExpansionManager } from './expansion/section-sidebar-menu-app-expansion.manager.js'; +import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbSectionSidebarMenuGlobalContext extends UmbContextBase { + public readonly expansion = new UmbSectionSidebarMenuAppExpansionManager(this); + + constructor(host: UmbControllerHost) { + super(host, UMB_SECTION_SIDEBAR_MENU_GLOBAL_CONTEXT); + } +} + +export { UmbSectionSidebarMenuGlobalContext as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/index.ts index 2d3149a8d4..0371f2072e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/index.ts @@ -1 +1,2 @@ export * from './section-sidebar-menu.element.js'; +export * from './constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/manifests.ts new file mode 100644 index 0000000000..b04a4c1661 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/manifests.ts @@ -0,0 +1,18 @@ +import { manifests as sectionContextManifests } from './section-context/manifests.js'; +import { manifests as globalContextManifests } from './global-context/manifests.js'; +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + { + type: 'kind', + alias: 'Umb.Kind.SectionSidebarAppMenu', + matchKind: 'menu', + matchType: 'sectionSidebarApp', + manifest: { + type: 'sectionSidebarApp', + element: () => import('./section-sidebar-menu.element.js'), + }, + }, + ...sectionContextManifests, + ...globalContextManifests, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/constants.ts new file mode 100644 index 0000000000..75f40d61ad --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/constants.ts @@ -0,0 +1 @@ +export * from './section-sidebar-menu.section-context.token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/expansion/section-sidebar-menu-section-expansion.manager.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/expansion/section-sidebar-menu-section-expansion.manager.ts new file mode 100644 index 0000000000..162861d5b8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/expansion/section-sidebar-menu-section-expansion.manager.ts @@ -0,0 +1,139 @@ +import { UMB_SECTION_SIDEBAR_MENU_GLOBAL_CONTEXT } from '../../global-context/section-sidebar-menu.global-context.token.js'; +import type { UmbSectionMenuItemExpansionEntryModel } from '../../types.js'; +import type { UmbMenuItemExpansionEntryModel } from '../../../components/menu/types.js'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import type { Observable } from '@umbraco-cms/backoffice/observable-api'; +import { UMB_SECTION_CONTEXT } from '@umbraco-cms/backoffice/section'; +import { UmbEntityExpansionManager, type UmbEntityExpansionModel } from '@umbraco-cms/backoffice/utils'; + +/** + * Manages the expansion state of a section sidebar menu. + * @exports + * @class UmbSectionSidebarMenuSectionExpansionManager + * @augments {UmbControllerBase} + */ +export class UmbSectionSidebarMenuSectionExpansionManager extends UmbControllerBase { + #manager = new UmbEntityExpansionManager(this); + public readonly expansion = this.#manager.expansion; + + #sectionContext?: typeof UMB_SECTION_CONTEXT.TYPE; + #globalContext?: typeof UMB_SECTION_SIDEBAR_MENU_GLOBAL_CONTEXT.TYPE; + #currentSectionAlias?: string; + + constructor(host: UmbControllerHost) { + super(host); + + this.consumeContext(UMB_SECTION_CONTEXT, (sectionContext) => { + this.#sectionContext = sectionContext; + this.#observeCurrentSectionAlias(); + }); + + this.consumeContext(UMB_SECTION_SIDEBAR_MENU_GLOBAL_CONTEXT, (globalContext) => { + this.#globalContext = globalContext; + this.#observeGlobalMenuExpansion(); + }); + } + + #observeCurrentSectionAlias() { + this.observe(this.#sectionContext?.alias, (alias) => { + if (!alias) return; + this.#currentSectionAlias = alias; + }); + } + + #observeGlobalMenuExpansion() { + if (!this.#globalContext || !this.#currentSectionAlias) return; + this.observe(this.#globalContext?.expansion.expansionBySectionAlias(this.#currentSectionAlias), (expansion) => { + this.#manager.setExpansion(expansion); + }); + } + + /** + * Checks if an entry is expanded + * @param {UmbMenuItemExpansionEntryModel} entry The entry to check + * @returns {Observable} True if the entry is expanded + * @memberof UmbSectionSidebarMenuSectionExpansionManager + */ + isExpanded(entry: UmbMenuItemExpansionEntryModel): Observable { + return this.#manager.isExpanded(entry); + } + + /** + * Sets the expansion state + * @param {UmbEntityExpansionModel | undefined} expansion The expansion state + * @memberof UmbSectionSidebarMenuSectionExpansionManager + * @returns {void} + */ + setExpansion(expansion: UmbEntityExpansionModel): void { + this.#manager.setExpansion(expansion); + const entries = this.#bindEntriesToSection(expansion); + this.#globalContext?.expansion.setExpansion(entries); + } + + /** + * Gets the expansion state + * @memberof UmbSectionSidebarMenuSectionExpansionManager + * @returns {UmbEntityExpansionModel} The expansion state + */ + getExpansion(): UmbEntityExpansionModel { + return this.#manager.getExpansion(); + } + + /** + * Opens a menu item + * @param {UmbMenuItemExpansionEntryModel} entry The item to open + * @memberof UmbSectionSidebarMenuSectionExpansionManager + * @returns {Promise} + */ + public async expandItem(entry: UmbMenuItemExpansionEntryModel): Promise { + this.#manager.expandItem(entry); + const entries = this.#bindEntriesToSection([entry]); + this.#globalContext?.expansion.expandItem(entries[0]); + } + + /** + * Expands multiple entities + * @param {UmbEntityExpansionModel} entries The entities to open + * @memberof UmbEntityExpansionManager + * @returns {void} + */ + public expandItems(entries: UmbEntityExpansionModel): void { + this.#manager.expandItems(entries); + const entriesWithSectionAlias = this.#bindEntriesToSection(entries); + this.#globalContext?.expansion.expandItems(entriesWithSectionAlias); + } + + /** + * Closes a menu item + * @param {UmbMenuItemExpansionEntryModel} entry The item to close + * @memberof UmbSectionSidebarMenuSectionExpansionManager + * @returns {Promise} + */ + public async collapseItem(entry: UmbMenuItemExpansionEntryModel): Promise { + this.#manager.collapseItem(entry); + const entries = this.#bindEntriesToSection([entry]); + this.#globalContext?.expansion.collapseItem(entries[0]); + } + + /** + * Closes all menu items + * @memberof UmbSectionSidebarMenuSectionExpansionManager + * @returns {Promise} + */ + public async collapseAll(): Promise { + // Collapse all items in the global context matching the current section + const entries = this.#bindEntriesToSection(this.#manager.getExpansion()); + this.#manager.collapseAll(); + this.#globalContext?.expansion.collapseItems(entries); + } + + #bindEntriesToSection( + expansion: UmbEntityExpansionModel, + ): UmbEntityExpansionModel { + return expansion.map((item) => ({ + ...item, + sectionAlias: this.#currentSectionAlias, + })); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/manifests.ts new file mode 100644 index 0000000000..19c4552e6d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/manifests.ts @@ -0,0 +1,10 @@ +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + { + type: 'sectionContext', + alias: 'Umb.SectionContext.SectionSidebarMenu', + name: 'Section Sidebar Menu Section Context', + api: () => import('./section-sidebar-menu.section-context.js'), + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/section-sidebar-menu.section-context.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/section-sidebar-menu.section-context.token.ts new file mode 100644 index 0000000000..bdab53e799 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/section-sidebar-menu.section-context.token.ts @@ -0,0 +1,8 @@ +import { UMB_SECTION_CONTEXT } from '@umbraco-cms/backoffice/section'; +import type { UmbSectionSidebarMenuSectionContext } from './section-sidebar-menu.section-context.js'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; + +export const UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT = new UmbContextToken( + UMB_SECTION_CONTEXT.contextAlias, + 'UmbSectionSidebarMenuSectionContext', +); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/section-sidebar-menu.section-context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/section-sidebar-menu.section-context.ts new file mode 100644 index 0000000000..e4cfe3861f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/section-sidebar-menu.section-context.ts @@ -0,0 +1,14 @@ +import { UmbSectionSidebarMenuSectionExpansionManager } from './expansion/section-sidebar-menu-section-expansion.manager.js'; +import { UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT } from './section-sidebar-menu.section-context.token.js'; +import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbSectionSidebarMenuSectionContext extends UmbContextBase { + public readonly expansion = new UmbSectionSidebarMenuSectionExpansionManager(this); + + constructor(host: UmbControllerHost) { + super(host, UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT); + } +} + +export { UmbSectionSidebarMenuSectionContext as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-sidebar-menu.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-sidebar-menu.element.ts index 51b8b8c34d..fc50249783 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-sidebar-menu.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-sidebar-menu.element.ts @@ -1,23 +1,12 @@ import type { ManifestMenu } from '../menu.extension.js'; +import { isMenuItemExpansionEntry } from '../components/menu-item/expansion/is-menu-item-expansion-entry.guard.js'; import type { ManifestSectionSidebarAppBaseMenu, ManifestSectionSidebarAppMenuKind } from './types.js'; +import { UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT } from './section-context/section-sidebar-menu.section-context.token.js'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { css, html, customElement, property } from '@umbraco-cms/backoffice/external/lit'; -import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; -import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; - -// TODO: Move to separate file: -const manifest: UmbExtensionManifestKind = { - type: 'kind', - alias: 'Umb.Kind.SectionSidebarAppMenu', - matchKind: 'menu', - matchType: 'sectionSidebarApp', - manifest: { - type: 'sectionSidebarApp', - elementName: 'umb-section-sidebar-menu', - }, -}; -umbExtensionsRegistry.register(manifest); +import { UmbExpansionEntryCollapsedEvent, UmbExpansionEntryExpandedEvent } from '@umbraco-cms/backoffice/utils'; +import { UmbExtensionSlotElement } from '@umbraco-cms/backoffice/extension-registry'; @customElement('umb-section-sidebar-menu') export class UmbSectionSidebarMenuElement< @@ -34,14 +23,73 @@ export class UmbSectionSidebarMenuElement< return html`

${this.localize.string(this.manifest?.meta?.label ?? '')}

`; } + #sectionSidebarMenuContext?: typeof UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT.TYPE; + + #extensionSlotElement = new UmbExtensionSlotElement(); + #muteStateUpdate = false; + + constructor() { + super(); + this.#initExtensionSlotElement(); + this.consumeContext(UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT, (context) => { + this.#sectionSidebarMenuContext = context; + this.#observeExpansion(); + }); + } + + #initExtensionSlotElement() { + /* For better performance and UX we prevent lit from doing unnecessary rerenders we programmatically create the element, + and manually update the props when needed. */ + + this.#extensionSlotElement.type = 'menu'; + this.#extensionSlotElement.filter = (menu: ManifestMenu) => menu.alias === this.manifest?.meta?.menu; + this.#extensionSlotElement.defaultElement = 'umb-menu'; + this.#extensionSlotElement.events = { + [UmbExpansionEntryExpandedEvent.TYPE]: this.#onExpansionChange.bind(this), + [UmbExpansionEntryCollapsedEvent.TYPE]: this.#onExpansionChange.bind(this), + }; + } + + #observeExpansion() { + this.observe(this.#sectionSidebarMenuContext?.expansion.expansion, (items) => { + if (this.#muteStateUpdate) return; + + this.#extensionSlotElement.props = { + expansion: items || [], + }; + }); + } + + #onExpansionChange(e: Event) { + const event = e as UmbExpansionEntryExpandedEvent | UmbExpansionEntryCollapsedEvent; + event.stopPropagation(); + const eventEntry = event.entry; + + if (!eventEntry) { + throw new Error('Entity is required to toggle expansion.'); + } + + // Only react to the event if it is a valid Menu Item Expansion Entry + if (isMenuItemExpansionEntry(eventEntry) === false) return; + + if (event.type === UmbExpansionEntryExpandedEvent.TYPE) { + this.#muteStateUpdate = true; + this.#sectionSidebarMenuContext?.expansion.expandItem(eventEntry); + this.#muteStateUpdate = false; + } else if (event.type === UmbExpansionEntryCollapsedEvent.TYPE) { + this.#muteStateUpdate = true; + this.#sectionSidebarMenuContext?.expansion.collapseItem(eventEntry); + this.#muteStateUpdate = false; + } + } + override render() { - return html` - ${this.renderHeader()} - - `; + return html` ${this.renderHeader()} ${this.#extensionSlotElement}`; + } + + override disconnectedCallback(): void { + super.disconnectedCallback(); + this.#extensionSlotElement.destroy(); } static override styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/types.ts index af00746daf..85a1cf64ab 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/types.ts @@ -1,3 +1,4 @@ +import type { UmbMenuItemExpansionEntryModel } from '../components/menu/types.js'; import type { ManifestSectionSidebarApp } from '@umbraco-cms/backoffice/section'; export interface MetaSectionSidebarAppMenuKind { @@ -24,3 +25,7 @@ export interface ManifestSectionSidebarAppMenuWithEntityActionsKind extends Mani export interface MetaSectionSidebarAppMenuWithEntityActionsKind extends MetaSectionSidebarAppMenuKind { entityType: string; } + +export interface UmbSectionMenuItemExpansionEntryModel extends UmbMenuItemExpansionEntryModel { + sectionAlias?: string; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/types.ts index 93dda2eb92..028299b81a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/types.ts @@ -2,9 +2,9 @@ import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; export type * from './components/types.js'; export type * from './conditions/types.js'; -export type * from './menu-item-element.interface.js'; -export type * from './menu-item.extension.js'; +export type * from './menu-structure/types.js'; export type * from './menu.extension.js'; +export type * from './section-sidebar-menu/types.js'; // eslint-disable-next-line @typescript-eslint/no-empty-object-type export interface UmbStructureItemModelBase extends UmbEntityModel {} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/conditions/section-alias/section-alias.condition.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/conditions/section-alias/section-alias.condition.ts index f18f3e75f6..91dc47b6bf 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/section/conditions/section-alias/section-alias.condition.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/conditions/section-alias/section-alias.condition.ts @@ -1,8 +1,8 @@ -import { UmbConditionBase } from '../../../extension-registry/conditions/condition-base.controller.js'; -import { UMB_SECTION_CONTEXT } from '../../section.context.js'; import type { SectionAliasConditionConfig } from '../types.js'; +import { UMB_SECTION_CONTEXT } from '../../section.context.token.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbConditionControllerArguments, UmbExtensionCondition } from '@umbraco-cms/backoffice/extension-api'; +import { UmbConditionBase } from '@umbraco-cms/backoffice/extension-registry'; export class UmbSectionAliasCondition extends UmbConditionBase diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/default/default-section.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/default/default-section.context.ts new file mode 100644 index 0000000000..26378d4914 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/default/default-section.context.ts @@ -0,0 +1,8 @@ +import { UmbSectionContext } from '../section.context.js'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbDefaultSectionContext extends UmbSectionContext { + constructor(host: UmbControllerHost) { + super(host); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/section-default.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/default/default-section.element.ts similarity index 84% rename from src/Umbraco.Web.UI.Client/src/packages/core/section/section-default.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/section/default/default-section.element.ts index 9b3d6fc293..aed2293213 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/section/section-default.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/default/default-section.element.ts @@ -1,6 +1,7 @@ -import type { ManifestSectionRoute } from './extensions/section-route.extension.js'; -import type { UmbSectionMainViewElement } from './section-main-views/section-main-views.element.js'; -import type { ManifestSection, UmbSectionElement } from './types.js'; +import type { ManifestSectionRoute } from '../extensions/section-route.extension.js'; +import type { UmbSectionMainViewElement } from '../section-main-views/section-main-views.element.js'; +import type { ManifestSection, UmbSectionElement } from '../types.js'; +import { UmbDefaultSectionContext } from './default-section.context.js'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { css, html, nothing, customElement, property, state, repeat } from '@umbraco-cms/backoffice/external/lit'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; @@ -21,7 +22,7 @@ import { UMB_MARK_ATTRIBUTE_NAME } from '@umbraco-cms/backoffice/const'; * @description - Element hosting sections and section navigation. */ @customElement('umb-section-default') -export class UmbSectionDefaultElement extends UmbLitElement implements UmbSectionElement { +export class UmbDefaultSectionElement extends UmbLitElement implements UmbSectionElement { private _manifest?: ManifestSection | undefined; @property({ type: Object, attribute: false }) @@ -32,7 +33,7 @@ export class UmbSectionDefaultElement extends UmbLitElement implements UmbSectio const oldValue = this._manifest; if (oldValue === value) return; this._manifest = value; - + this.#api.setManifest(value); this.requestUpdate('manifest', oldValue); } @@ -45,6 +46,9 @@ export class UmbSectionDefaultElement extends UmbLitElement implements UmbSectio @state() private _splitPanelPosition = '300px'; + // TODO: v17: Move this to a manifest api. It will have to wait for a major as it will be a breaking change. + #api = new UmbDefaultSectionContext(this); + constructor() { super(); @@ -111,7 +115,7 @@ export class UmbSectionDefaultElement extends UmbLitElement implements UmbSectio ...routes, { path: '**', - component: () => import('./section-main-views/section-main-views.element.js'), + component: () => import('../section-main-views/section-main-views.element.js'), setup: (element) => { (element as UmbSectionMainViewElement).sectionAlias = this.manifest?.alias; }, @@ -177,8 +181,16 @@ export class UmbSectionDefaultElement extends UmbLitElement implements UmbSectio ]; } +export { UmbDefaultSectionElement as element }; + declare global { interface HTMLElementTagNameMap { - 'umb-section-default': UmbSectionDefaultElement; + 'umb-section-default': UmbDefaultSectionElement; } } + +/** + * + * @deprecated Since 16. Use UmbDefaultSectionElement instead. UmbSectionDefaultElement will be removed in v18. + */ +export { UmbDefaultSectionElement as UmbSectionDefaultElement }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/default/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/default/manifests.ts new file mode 100644 index 0000000000..1802584f0f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/default/manifests.ts @@ -0,0 +1,20 @@ +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + { + type: 'kind', + alias: 'Umb.Kind.Section.Default', + matchKind: 'default', + matchType: 'section', + manifest: { + type: 'section', + kind: 'default', + weight: 1000, + element: () => import('./default-section.element.js'), + meta: { + label: '', + pathname: '', + }, + }, + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/default/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/default/types.ts new file mode 100644 index 0000000000..17eeb41ff0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/default/types.ts @@ -0,0 +1,11 @@ +import type { ManifestSection } from '../../section/extensions/index.js'; + +export interface ManifestSectionDefaultKind extends ManifestSection { + kind: 'default'; +} + +declare global { + interface UmbExtensionManifestMap { + umbDefaultSectionKind: ManifestSectionDefaultKind; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/extensions/section-context.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/extensions/section-context.extension.ts new file mode 100644 index 0000000000..25e0e114cc --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/extensions/section-context.extension.ts @@ -0,0 +1,17 @@ +import type { ManifestApi, ManifestWithDynamicConditions, UmbApi } from '@umbraco-cms/backoffice/extension-api'; + +export interface ManifestSectionContext + extends ManifestWithDynamicConditions, + ManifestApi { + type: 'sectionContext'; + meta: MetaType; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface MetaSectionContext {} + +declare global { + interface UmbExtensionManifestMap { + UmbManifestSectionContext: ManifestSectionContext; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/extensions/section.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/extensions/section.extension.ts index 63f363013b..b3d90397f5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/section/extensions/section.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/extensions/section.extension.ts @@ -2,6 +2,7 @@ import type { UmbSectionElement } from './section-element.interface.js'; import type { ManifestElement, ManifestWithDynamicConditions } from '@umbraco-cms/backoffice/extension-api'; export interface ManifestSection + // TODO: v17 change to extend Element and Api extends ManifestElement, ManifestWithDynamicConditions { type: 'section'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/extensions/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/extensions/types.ts index e4d5de7f8b..9e65c93996 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/section/extensions/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/extensions/types.ts @@ -1,3 +1,4 @@ +export type * from './section-context.extension.js'; export type * from './section-element.interface.js'; export type * from './section-sidebar-app-element.interface.js'; export type * from './section-view-element.interface.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/index.ts index 9ac642e834..03fa9cfd53 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/section/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/index.ts @@ -1,11 +1,10 @@ export * from './components/index.js'; export * from './constants.js'; -export * from './section-default.element.js'; +export * from './default/default-section.element.js'; export * from './section-main/index.js'; export * from './section-picker-modal/section-picker-modal.token.js'; export * from './section-sidebar-context-menu/index.js'; -export * from '../menu/section-sidebar-menu-with-entity-actions/index.js'; -export * from '../menu/section-sidebar-menu/index.js'; export * from './section-sidebar/index.js'; export * from './section.context.js'; +export * from './section.context.token.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/section-main/section-main.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/section-main/section-main.element.ts index 144a2b2704..ebae159f82 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/section/section-main/section-main.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/section-main/section-main.element.ts @@ -1,8 +1,9 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { css, html, LitElement, customElement } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @customElement('umb-section-main') -export class UmbSectionMainElement extends LitElement { +export class UmbSectionMainElement extends UmbLitElement { override render() { return html`
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/section.context.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/section.context.token.ts new file mode 100644 index 0000000000..b70b7b5ebf --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/section.context.token.ts @@ -0,0 +1,4 @@ +import type { UmbSectionContext } from './section.context.js'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; + +export const UMB_SECTION_CONTEXT = new UmbContextToken('UmbSectionContext'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/section.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/section.context.ts index fbb626897f..510697e146 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/section/section.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/section.context.ts @@ -1,8 +1,10 @@ import type { ManifestSection } from './extensions/section.extension.js'; +import { UMB_SECTION_CONTEXT } from './section.context.token.js'; import { UmbStringState } from '@umbraco-cms/backoffice/observable-api'; -import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; +import { UmbExtensionsApiInitializer } from '@umbraco-cms/backoffice/extension-api'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; export class UmbSectionContext extends UmbContextBase { #manifestAlias = new UmbStringState(undefined); @@ -12,8 +14,11 @@ export class UmbSectionContext extends UmbContextBase { public readonly pathname = this.#manifestPathname.asObservable(); public readonly label = this.#manifestLabel.asObservable(); + #sectionContextExtensionController?: UmbExtensionsApiInitializer; + constructor(host: UmbControllerHost) { super(host, UMB_SECTION_CONTEXT); + this.#createSectionContextExtensions(); } public setManifest(manifest?: ManifestSection) { @@ -25,6 +30,18 @@ export class UmbSectionContext extends UmbContextBase { getPathname() { return this.#manifestPathname.getValue(); } -} -export const UMB_SECTION_CONTEXT = new UmbContextToken('UmbSectionContext'); + #createSectionContextExtensions() { + if (this.#sectionContextExtensionController) { + this.#sectionContextExtensionController.destroy(); + } + + this.#sectionContextExtensionController = new UmbExtensionsApiInitializer( + this, + umbExtensionsRegistry, + 'sectionContext', + [], + undefined, + ); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/expansion-manager/tree-expansion-manager.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/expansion-manager/tree-expansion-manager.ts index a2144f8c1c..26f6bba57d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/expansion-manager/tree-expansion-manager.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/expansion-manager/tree-expansion-manager.ts @@ -1,7 +1,8 @@ import type { UmbTreeExpansionModel } from './types.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; -import { UmbArrayState, type Observable } from '@umbraco-cms/backoffice/observable-api'; +import type { Observable } from '@umbraco-cms/backoffice/observable-api'; +import { UmbEntityExpansionManager } from '@umbraco-cms/backoffice/utils'; /** * Manages the expansion state of a tree @@ -10,8 +11,8 @@ import { UmbArrayState, type Observable } from '@umbraco-cms/backoffice/observab * @augments {UmbControllerBase} */ export class UmbTreeExpansionManager extends UmbControllerBase { - #expansion = new UmbArrayState([], (x) => x.unique); - expansion = this.#expansion.asObservable(); + #manager = new UmbEntityExpansionManager(this); + expansion = this.#manager.expansion; /** * Checks if an entity is expanded @@ -22,9 +23,7 @@ export class UmbTreeExpansionManager extends UmbControllerBase { * @memberof UmbTreeExpansionManager */ isExpanded(entity: UmbEntityModel): Observable { - return this.#expansion.asObservablePart((entries) => - entries?.some((entry) => entry.entityType === entity.entityType && entry.unique === entity.unique), - ); + return this.#manager.isExpanded(entity); } /** @@ -34,7 +33,7 @@ export class UmbTreeExpansionManager extends UmbControllerBase { * @returns {void} */ setExpansion(expansion: UmbTreeExpansionModel): void { - this.#expansion.setValue(expansion); + this.#manager.setExpansion(expansion); } /** @@ -43,7 +42,7 @@ export class UmbTreeExpansionManager extends UmbControllerBase { * @returns {UmbTreeExpansionModel} The expansion state */ getExpansion(): UmbTreeExpansionModel { - return this.#expansion.getValue(); + return this.#manager.getExpansion(); } /** @@ -55,7 +54,7 @@ export class UmbTreeExpansionManager extends UmbControllerBase { * @returns {Promise} */ public async expandItem(entity: UmbEntityModel): Promise { - this.#expansion.appendOne(entity); + this.#manager.expandItem(entity); } /** @@ -67,7 +66,7 @@ export class UmbTreeExpansionManager extends UmbControllerBase { * @returns {Promise} */ public async collapseItem(entity: UmbEntityModel): Promise { - this.#expansion.filter((x) => x.entityType !== entity.entityType || x.unique !== entity.unique); + this.#manager.collapseItem(entity); } /** @@ -76,6 +75,6 @@ export class UmbTreeExpansionManager extends UmbControllerBase { * @returns {Promise} */ public async collapseAll(): Promise { - this.#expansion.setValue([]); + this.#manager.collapseAll(); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/expansion-manager/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/expansion-manager/types.ts index 7d5c050029..0585b8ed8c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/expansion-manager/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/expansion-manager/types.ts @@ -1,3 +1,3 @@ -import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import type { UmbEntityExpansionModel } from '@umbraco-cms/backoffice/utils'; -export type UmbTreeExpansionModel = Array; +export type UmbTreeExpansionModel = UmbEntityExpansionModel; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/index.ts index c947f5199f..daa67a8789 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/index.ts @@ -7,7 +7,7 @@ export * from './entity-actions/reload-tree-item-children/index.js'; export * from './entity-actions/sort-children-of/index.js'; export * from './folder/index.js'; export * from './tree-item/index.js'; -export * from './tree-menu-item-default/index.js'; +export * from './tree-menu-item/index.js'; export * from './tree.element.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/manifests.ts index e1972b17cc..ec8a28e85f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/manifests.ts @@ -1,8 +1,9 @@ -import { manifests as folderManifests } from './folder/manifests.js'; import { manifests as defaultTreeItemManifests } from './tree-item/tree-item-default/manifests.js'; import { manifests as defaultTreeManifests } from './default/manifests.js'; -import { manifests as treePickerManifests } from './tree-picker-modal/manifests.js'; import { manifests as entityActionManifests } from './entity-actions/manifests.js'; +import { manifests as folderManifests } from './folder/manifests.js'; +import { manifests as treeMenuItemManifests } from './tree-menu-item/manifests.js'; +import { manifests as treePickerManifests } from './tree-picker-modal/manifests.js'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; export const manifests: Array = [ @@ -10,5 +11,6 @@ export const manifests: Array = ...defaultTreeManifests, ...entityActionManifests, ...folderManifests, + ...treeMenuItemManifests, ...treePickerManifests, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item-default/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item-default/index.ts deleted file mode 100644 index af047cc2d4..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item-default/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './tree-menu-item-default.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item-default/tree-menu-item-default.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item-default/tree-menu-item-default.element.ts deleted file mode 100644 index 93ce54fa6d..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item-default/tree-menu-item-default.element.ts +++ /dev/null @@ -1,49 +0,0 @@ -import type { ManifestMenuItemTreeKind } from './types.js'; -import { html, nothing, customElement, property } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; -import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; -import type { UmbMenuItemElement } from '@umbraco-cms/backoffice/menu'; - -// TODO: Move to separate file: -const manifest: UmbExtensionManifestKind = { - type: 'kind', - alias: 'Umb.Kind.Tree', - matchKind: 'tree', - matchType: 'menuItem', - manifest: { - type: 'menuItem', - elementName: 'umb-menu-item-tree-default', - }, -}; -umbExtensionsRegistry.register(manifest); - -@customElement('umb-menu-item-tree-default') -export class UmbMenuItemTreeDefaultElement extends UmbLitElement implements UmbMenuItemElement { - @property({ type: Object }) - manifest?: ManifestMenuItemTreeKind; - - override render() { - return this.manifest - ? html` - - ` - : nothing; - } -} - -export default UmbMenuItemTreeDefaultElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-menu-item-tree-default': UmbMenuItemTreeDefaultElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item/index.ts new file mode 100644 index 0000000000..c4d5f8a3f0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item/index.ts @@ -0,0 +1 @@ +export * from './tree-menu-item.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item/manifests.ts new file mode 100644 index 0000000000..1ace3b635e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item/manifests.ts @@ -0,0 +1,14 @@ +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + { + type: 'kind', + alias: 'Umb.Kind.Tree', + matchKind: 'tree', + matchType: 'menuItem', + manifest: { + type: 'menuItem', + element: () => import('./tree-menu-item.element.js'), + }, + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item/tree-menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item/tree-menu-item.element.ts new file mode 100644 index 0000000000..62624dd3d5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item/tree-menu-item.element.ts @@ -0,0 +1,87 @@ +import type { ManifestMenuItemTreeKind } from './types.js'; +import { html, nothing, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UMB_MENU_ITEM_CONTEXT, type UmbMenuItemElement } from '@umbraco-cms/backoffice/menu'; +import { + UmbExpansionEntryCollapsedEvent, + UmbExpansionEntryExpandedEvent, + type UmbEntityExpansionModel, +} from '@umbraco-cms/backoffice/utils'; + +@customElement('umb-menu-item-tree-default') +export class UmbMenuItemTreeDefaultElement extends UmbLitElement implements UmbMenuItemElement { + @property({ type: Object }) + manifest?: ManifestMenuItemTreeKind; + + @state() + private _menuItemExpansion: UmbEntityExpansionModel = []; + + #menuItemContext?: typeof UMB_MENU_ITEM_CONTEXT.TYPE; + #muteStateUpdate = false; + + constructor() { + super(); + + this.consumeContext(UMB_MENU_ITEM_CONTEXT, (context) => { + this.#menuItemContext = context; + this.#observeExpansion(); + }); + } + + #observeExpansion() { + this.observe(this.#menuItemContext?.expansion.expansion, (items) => { + if (this.#muteStateUpdate) return; + this._menuItemExpansion = items || []; + }); + } + + #onExpansionChange(event: UmbExpansionEntryExpandedEvent | UmbExpansionEntryCollapsedEvent) { + event.stopPropagation(); + const eventEntry = event.entry; + + if (!eventEntry) { + throw new Error('Entry is required to toggle expansion.'); + } + + if (!this.manifest) { + throw new Error('Manifest is required to toggle expansion.'); + } + + if (event.type === UmbExpansionEntryExpandedEvent.TYPE) { + this.#muteStateUpdate = true; + this.#menuItemContext?.expansion.expandItem({ ...eventEntry, menuItemAlias: this.manifest.alias }); + this.#muteStateUpdate = false; + } else if (event.type === UmbExpansionEntryCollapsedEvent.TYPE) { + this.#muteStateUpdate = true; + this.#menuItemContext?.expansion.collapseItem({ ...eventEntry, menuItemAlias: this.manifest.alias }); + this.#muteStateUpdate = false; + } + } + + override render() { + return this.manifest + ? html` + + ` + : nothing; + } +} + +export default UmbMenuItemTreeDefaultElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-menu-item-tree-default': UmbMenuItemTreeDefaultElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item-default/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item/types.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item-default/types.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-menu-item/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree.element.ts index 889ab0849b..a091f5e732 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree.element.ts @@ -18,6 +18,13 @@ export class UmbTreeElement extends UmbExtensionElementAndApiSlotElementBase extends UmbControllerBase { + protected _expansion = new UmbArrayState([], (x) => x.entityType + x.unique); + expansion = this._expansion.asObservable(); + + /** + * Checks if an entity is expanded + * @param {EntryModelType} entity The entity to check + * @returns {Observable} True if the entity is expanded + * @memberof UmbEntityExpansionManager + */ + isExpanded(entity: EntryModelType): Observable { + return this._expansion.asObservablePart((entries) => + entries?.some((entry) => entry.entityType === entity.entityType && entry.unique === entity.unique), + ); + } + + /** + * Sets the expansion state + * @param {UmbEntityExpansionModel | undefined} expansion The expansion state + * @memberof UmbEntityExpansionManager + * @returns {void} + */ + setExpansion(expansion: UmbEntityExpansionModel): void { + this._expansion.setValue(expansion); + this.getHostElement()?.dispatchEvent(new UmbExpansionChangeEvent()); + } + + /** + * Gets the expansion state + * @memberof UmbEntityExpansionManager + * @returns {UmbEntityExpansionModel} The expansion state + */ + getExpansion(): UmbEntityExpansionModel { + return this._expansion.getValue(); + } + + /** + * Expands an entity + * @param {EntryModelType} entity The entity to open + * @memberof UmbEntityExpansionManager + * @returns {Promise} + */ + public async expandItem(entity: EntryModelType): Promise { + this._expansion.appendOne(entity); + this.getHostElement()?.dispatchEvent(new UmbExpansionEntryExpandedEvent(entity)); + this.getHostElement()?.dispatchEvent(new UmbExpansionChangeEvent()); + } + + /** + * Expands multiple entities + * @param {UmbEntityExpansionModel} entities The entities to open + * @memberof UmbEntityExpansionManager + * @returns {void} + */ + public expandItems(entities: UmbEntityExpansionModel): void { + if (!entities || entities.length === 0) return; + this._expansion.append(entities); + entities.forEach((entity) => { + this.getHostElement()?.dispatchEvent(new UmbExpansionEntryExpandedEvent(entity)); + }); + this.getHostElement()?.dispatchEvent(new UmbExpansionChangeEvent()); + } + + /** + * Collapses an entity + * @param {EntryModelType} entry The entity to open + * @memberof UmbEntityExpansionManager + * @returns {Promise} + */ + public async collapseItem(entry: EntryModelType): Promise { + this._expansion.filter((x) => x.entityType !== entry.entityType || x.unique !== entry.unique); + this.getHostElement()?.dispatchEvent(new UmbExpansionEntryCollapsedEvent(entry)); + this.getHostElement()?.dispatchEvent(new UmbExpansionChangeEvent()); + } + + /** + * Collapses multiple entities + * @param {UmbEntityExpansionModel} entries The entities to close + * @memberof UmbEntityExpansionManager + * @returns {void} + */ + public collapseItems(entries: UmbEntityExpansionModel): void { + if (!entries || entries.length === 0) return; + this._expansion.filter( + (x) => !entries.some((entry) => entry.entityType === x.entityType && entry.unique === x.unique), + ); + entries.forEach((entry) => { + this.getHostElement()?.dispatchEvent(new UmbExpansionEntryCollapsedEvent(entry)); + }); + this.getHostElement()?.dispatchEvent(new UmbExpansionChangeEvent()); + } + + /** + * Collapses all expanded entities + * @memberof UmbEntityExpansionManager + * @returns {Promise} + */ + public async collapseAll(): Promise { + this._expansion.setValue([]); + this.getHostElement()?.dispatchEvent(new UmbExpansionChangeEvent()); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/expansion-change.event.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/expansion-change.event.ts new file mode 100644 index 0000000000..bfc0374014 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/expansion-change.event.ts @@ -0,0 +1,8 @@ +export class UmbExpansionChangeEvent extends Event { + public static readonly TYPE = 'expansion-change'; + + public constructor() { + // mimics the native change event + super(UmbExpansionChangeEvent.TYPE, { bubbles: true, composed: false, cancelable: false }); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/expansion-entry-collapsed.event.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/expansion-entry-collapsed.event.ts new file mode 100644 index 0000000000..b946982ab9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/expansion-entry-collapsed.event.ts @@ -0,0 +1,12 @@ +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; + +export class UmbExpansionEntryCollapsedEvent extends Event { + public static readonly TYPE = 'expansion-entry-collapsed'; + entry: EntryModelType; + + public constructor(entry: EntryModelType) { + // mimics the native change event + super(UmbExpansionEntryCollapsedEvent.TYPE, { bubbles: true, composed: false, cancelable: false }); + this.entry = entry; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/expansion-entry-expanded.event.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/expansion-entry-expanded.event.ts new file mode 100644 index 0000000000..0831115d91 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/expansion-entry-expanded.event.ts @@ -0,0 +1,12 @@ +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; + +export class UmbExpansionEntryExpandedEvent extends Event { + public static readonly TYPE = 'expansion-entry-expanded'; + entry: EntryModelType; + + public constructor(entry: EntryModelType) { + // mimics the native change event + super(UmbExpansionEntryExpandedEvent.TYPE, { bubbles: true, composed: false, cancelable: false }); + this.entry = entry; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/index.ts new file mode 100644 index 0000000000..7a4b74e034 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/events/index.ts @@ -0,0 +1,3 @@ +export * from './expansion-change.event.js'; +export * from './expansion-entry-collapsed.event.js'; +export * from './expansion-entry-expanded.event.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/index.ts new file mode 100644 index 0000000000..ee4761b07d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/index.ts @@ -0,0 +1,4 @@ +export * from './entity-expansion.manager.js'; +export * from './events/index.js'; +export * from './utils/index.js'; +export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/types.ts new file mode 100644 index 0000000000..ada5d4b7dd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/types.ts @@ -0,0 +1,9 @@ +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; + +export type UmbEntityExpansionModel< + EntryModelType extends UmbEntityExpansionEntryModel = UmbEntityExpansionEntryModel, +> = Array; + +export interface UmbEntityExpansionEntryModel extends UmbEntityModel { + target?: UmbEntityModel; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/utils/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/utils/index.ts new file mode 100644 index 0000000000..510a193d39 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/utils/index.ts @@ -0,0 +1 @@ +export * from './link-entity-expansion-entries.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/utils/link-entity-expansion-entries.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/utils/link-entity-expansion-entries.test.ts new file mode 100644 index 0000000000..5c9ec73183 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/utils/link-entity-expansion-entries.test.ts @@ -0,0 +1,26 @@ +import { expect } from '@open-wc/testing'; +import { linkEntityExpansionEntries } from './link-entity-expansion-entries'; + +describe('LinkEntityExpansionEntries', () => { + const input = [ + { entityType: 'document', unique: '1' }, + { entityType: 'document', unique: '2' }, + { entityType: 'document', unique: '3' }, + ]; + + it('should return an array of expansion entries with target', () => { + const result = linkEntityExpansionEntries(input); + expect(result).to.be.an('array').that.has.lengthOf(3); + expect(result[0]).to.have.property('entityType', 'document'); + expect(result[0]).to.have.property('unique', '1'); + expect(result[0]).to.have.property('target').that.deep.equals({ entityType: 'document', unique: '2' }); + + expect(result[1]).to.have.property('entityType', 'document'); + expect(result[1]).to.have.property('unique', '2'); + expect(result[1]).to.have.property('target').that.deep.equals({ entityType: 'document', unique: '3' }); + + expect(result[2]).to.have.property('entityType', 'document'); + expect(result[2]).to.have.property('unique', '3'); + expect(result[2]).to.not.have.property('target'); + }); +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/utils/link-entity-expansion-entries.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/utils/link-entity-expansion-entries.ts new file mode 100644 index 0000000000..04759ec3a1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/expansion/utils/link-entity-expansion-entries.ts @@ -0,0 +1,22 @@ +import type { UmbEntityExpansionEntryModel, UmbEntityExpansionModel } from '../types.js'; +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; + +export const linkEntityExpansionEntries = (data: Array): UmbEntityExpansionModel => { + return data.map((item, index) => { + const result: UmbEntityExpansionEntryModel = { + entityType: item.entityType, + unique: item.unique, + }; + + const next = data[index + 1]; + + if (next) { + result.target = { + entityType: next.entityType, + unique: next.unique, + }; + } + + return result; + }); +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts index da5a0ec8c6..99bd098a02 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts @@ -5,6 +5,7 @@ export * from './deprecation/index.js'; export * from './diff/index.js'; export * from './direction/index.js'; export * from './download/blob-download.function.js'; +export * from './expansion/index.js'; export * from './get-guid-from-udi.function.js'; export * from './get-processed-image-url.function.js'; export * from './guard-manager/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-breadcrumb/workspace-menu-breadcrumb/workspace-menu-breadcrumb.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-breadcrumb/workspace-menu-breadcrumb/workspace-menu-breadcrumb.element.ts index c23a374acd..0fcb8deab4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-breadcrumb/workspace-menu-breadcrumb/workspace-menu-breadcrumb.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-breadcrumb/workspace-menu-breadcrumb/workspace-menu-breadcrumb.element.ts @@ -14,6 +14,9 @@ export class UmbWorkspaceBreadcrumbElement extends UmbLitElement { @state() private _structure: UmbStructureItemModel[] = []; + @state() + private _isNew: boolean = false; + // TODO: figure out the correct context type #workspaceContext?: any; #sectionContext?: typeof UMB_SECTION_CONTEXT.TYPE; @@ -28,6 +31,7 @@ export class UmbWorkspaceBreadcrumbElement extends UmbLitElement { this.consumeContext(UMB_WORKSPACE_CONTEXT, (instance) => { this.#workspaceContext = instance as any; + this.#observeIsNew(); this.#observeStructure(); this.#observeName(); }); @@ -38,16 +42,15 @@ export class UmbWorkspaceBreadcrumbElement extends UmbLitElement { }); } - #observeStructure() { - if (!this.#structureContext || !this.#workspaceContext) return; - const isNew = this.#workspaceContext.getIsNew(); - + #observeIsNew() { this.observe( - this.#structureContext.structure, + this.#workspaceContext?.isNew, (value) => { - this._structure = isNew ? value : value.slice(0, -1); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + this._isNew = value || false; }, - 'menuStructureObserver', + 'breadcrumbWorkspaceIsNewObserver', ); } @@ -61,16 +64,30 @@ export class UmbWorkspaceBreadcrumbElement extends UmbLitElement { ); } + #observeStructure() { + if (!this.#structureContext || !this.#workspaceContext) return; + + this.observe( + this.#structureContext.structure, + (value) => { + this._structure = value; + }, + 'menuStructureObserver', + ); + } + #getHref(structureItem: UmbStructureItemModel) { if (structureItem.isFolder) return undefined; return `section/${this.#sectionContext?.getPathname()}/workspace/${structureItem.entityType}/edit/${structureItem.unique}`; } override render() { + const structure = this._isNew ? this._structure : this._structure.slice(0, -1); + return html` ${map( - this._structure, + structure, (structureItem) => html`${this.localize.string(structureItem.name)} = [ { type: 'menuItem', kind: 'tree', - alias: 'Umb.MenuItem.DataTypes', + alias: UMB_DATA_TYPE_MENU_ITEM_ALIAS, name: 'Data Types Menu Item', weight: 600, meta: { @@ -16,9 +17,13 @@ export const manifests: Array = [ }, { type: 'workspaceContext', + kind: 'menuStructure', name: 'Data Type Menu Structure Workspace Context', alias: 'Umb.Context.DataType.Menu.Structure', api: () => import('./data-type-menu-structure.context.js'), + meta: { + menuItemAlias: UMB_DATA_TYPE_MENU_ITEM_ALIAS, + }, conditions: [ { alias: UMB_WORKSPACE_CONDITION_ALIAS, diff --git a/src/Umbraco.Web.UI.Client/src/packages/dictionary/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/dictionary/constants.ts index eb8dd5d7b1..8ed0d150bd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/dictionary/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/dictionary/constants.ts @@ -6,5 +6,6 @@ export * from './repository/constants.js'; export * from './search/constants.js'; export * from './tree/constants.js'; export * from './workspace/constants.js'; +export * from './menu-item/constants.js'; export { UMB_DICTIONARY_ROOT_ENTITY_TYPE, UMB_DICTIONARY_ENTITY_TYPE } from './entity.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/dictionary/menu-item/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/dictionary/menu-item/constants.ts new file mode 100644 index 0000000000..d2abd87122 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/dictionary/menu-item/constants.ts @@ -0,0 +1 @@ +export const UMB_DICTIONARY_MENU_ITEM_ALIAS = 'Umb.MenuItem.Dictionary'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/dictionary/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/dictionary/menu-item/manifests.ts index 03da8a1d40..109608104c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/dictionary/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/dictionary/menu-item/manifests.ts @@ -1,5 +1,6 @@ import { UMB_DICTIONARY_ENTITY_TYPE } from '../entity.js'; import { UMB_DICTIONARY_TREE_ALIAS } from '../tree/index.js'; +import { UMB_DICTIONARY_MENU_ITEM_ALIAS } from './constants.js'; import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_TRANSLATION_MENU_ALIAS } from '@umbraco-cms/backoffice/translation'; @@ -7,7 +8,7 @@ export const manifests: Array = [ { type: 'menuItem', kind: 'tree', - alias: 'Umb.MenuItem.Dictionary', + alias: UMB_DICTIONARY_MENU_ITEM_ALIAS, name: 'Dictionary Menu Item', weight: 400, meta: { @@ -21,9 +22,13 @@ export const manifests: Array = [ }, { type: 'workspaceContext', + kind: 'menuStructure', name: 'Dictionary Menu Structure Workspace Context', alias: 'Umb.Context.Dictionary.Menu.Structure', api: () => import('./dictionary-menu-structure.context.js'), + meta: { + menuItemAlias: UMB_DICTIONARY_MENU_ITEM_ALIAS, + }, conditions: [ { alias: UMB_WORKSPACE_CONDITION_ALIAS, diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/constants.ts index d07e60d102..c4577efe6e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/constants.ts @@ -5,5 +5,6 @@ export * from './repository/constants.js'; export * from './search/constants.js'; export * from './tree/constants.js'; export * from './workspace/constants.js'; +export * from './menu/constants.js'; export { UMB_DOCUMENT_TYPE_ENTITY_TYPE, UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE } from './entity.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/menu/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/menu/constants.ts new file mode 100644 index 0000000000..6f56101e30 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/menu/constants.ts @@ -0,0 +1 @@ +export const UMB_DOCUMENT_TYPE_MENU_ITEM_ALIAS = 'Umb.MenuItem.DocumentTypes'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/menu/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/menu/manifests.ts index 35ea56aca9..1e28f22619 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/menu/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/menu/manifests.ts @@ -1,11 +1,12 @@ import { UMB_DOCUMENT_TYPE_TREE_ALIAS } from '../tree/index.js'; +import { UMB_DOCUMENT_TYPE_MENU_ITEM_ALIAS } from './constants.js'; import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { type: 'menuItem', kind: 'tree', - alias: 'Umb.MenuItem.DocumentTypes', + alias: UMB_DOCUMENT_TYPE_MENU_ITEM_ALIAS, name: 'Document Types Menu Item', weight: 900, meta: { @@ -16,9 +17,13 @@ export const manifests: Array = [ }, { type: 'workspaceContext', + kind: 'menuStructure', name: 'Document Type Menu Structure Workspace Context', alias: 'Umb.Context.DocumentType.Menu.Structure', api: () => import('./document-type-menu-structure.context.js'), + meta: { + menuItemAlias: UMB_DOCUMENT_TYPE_MENU_ITEM_ALIAS, + }, conditions: [ { alias: UMB_WORKSPACE_CONDITION_ALIAS, diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/constants.ts index b0cd03a572..8b2ea67a99 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/constants.ts @@ -4,6 +4,7 @@ export * from './collection/constants.js'; export * from './entity-actions/constants.js'; export * from './entity-bulk-actions/constants.js'; export * from './item/constants.js'; +export * from './menu/constants.js'; export * from './modals/constants.js'; export * from './paths.js'; export * from './property-dataset-context/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/menu/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/menu/constants.ts new file mode 100644 index 0000000000..e2fd4065cc --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/menu/constants.ts @@ -0,0 +1 @@ +export const UMB_DOCUMENT_MENU_ITEM_ALIAS = 'Umb.MenuItem.Document'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/menu/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/menu/manifests.ts index dc76417093..f50b532911 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/menu/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/menu/manifests.ts @@ -1,4 +1,5 @@ import { UMB_DOCUMENT_TREE_ALIAS } from '../tree/index.js'; +import { UMB_DOCUMENT_MENU_ITEM_ALIAS } from './constants.js'; import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const UMB_CONTENT_MENU_ALIAS = 'Umb.Menu.Content'; @@ -12,7 +13,7 @@ export const manifests: Array = [ { type: 'menuItem', kind: 'tree', - alias: 'Umb.MenuItem.Document', + alias: UMB_DOCUMENT_MENU_ITEM_ALIAS, name: 'Document Menu Item', weight: 200, meta: { @@ -24,9 +25,13 @@ export const manifests: Array = [ }, { type: 'workspaceContext', + kind: 'menuStructure', name: 'Document Menu Structure Workspace Context', alias: 'Umb.Context.Document.Menu.Structure', api: () => import('./document-menu-structure.context.js'), + meta: { + menuItemAlias: UMB_DOCUMENT_MENU_ITEM_ALIAS, + }, conditions: [ { alias: UMB_WORKSPACE_CONDITION_ALIAS, diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/constants.ts index c80e3ac5e4..86c491dd00 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/constants.ts @@ -1,11 +1,12 @@ export * from './entity-actions/constants.js'; export * from './media-type-root/constants.js'; +export * from './menu/constants.js'; export * from './paths.js'; export * from './property-type/constants.js'; export * from './repository/constants.js'; +export * from './search/constants.js'; export * from './tree/constants.js'; export * from './workspace/constants.js'; -export * from './search/constants.js'; export { UMB_MEDIA_TYPE_ENTITY_TYPE, diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/menu/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/menu/constants.ts new file mode 100644 index 0000000000..462c1600e7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/menu/constants.ts @@ -0,0 +1 @@ +export const UMB_MEDIA_TYPE_MENU_ITEM_ALIAS = 'Umb.MenuItem.MediaTypes'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/menu/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/menu/manifests.ts index 65107a2596..9272a5fafd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/menu/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/menu/manifests.ts @@ -1,11 +1,12 @@ import { UMB_MEDIA_TYPE_TREE_ALIAS } from '../constants.js'; import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; +import { UMB_MEDIA_TYPE_MENU_ITEM_ALIAS } from './constants.js'; export const manifests: Array = [ { type: 'menuItem', kind: 'tree', - alias: 'Umb.MenuItem.MediaTypes', + alias: UMB_MEDIA_TYPE_MENU_ITEM_ALIAS, name: 'Media Types Menu Item', weight: 800, meta: { @@ -16,9 +17,13 @@ export const manifests: Array = [ }, { type: 'workspaceContext', + kind: 'menuStructure', name: 'Media Type Menu Structure Workspace Context', alias: 'Umb.Context.MediaType.Menu.Structure', api: () => import('./media-type-menu-structure.context.js'), + meta: { + menuItemAlias: UMB_MEDIA_TYPE_MENU_ITEM_ALIAS, + }, conditions: [ { alias: UMB_WORKSPACE_CONDITION_ALIAS, diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/menu/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/menu/constants.ts index 11ceb55bf0..34b70788f4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/menu/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/menu/constants.ts @@ -1 +1,2 @@ export const UMB_MEDIA_MENU_ALIAS = 'Umb.Menu.Media'; +export const UMB_MEDIA_MENU_ITEM_ALIAS = 'Umb.MenuItem.Media'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/menu/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/menu/manifests.ts index a4bd3d6b8a..93bb4b6b5b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/menu/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/menu/manifests.ts @@ -1,5 +1,5 @@ import { UMB_MEDIA_TREE_ALIAS } from '../constants.js'; -import { UMB_MEDIA_MENU_ALIAS } from './constants.js'; +import { UMB_MEDIA_MENU_ALIAS, UMB_MEDIA_MENU_ITEM_ALIAS } from './constants.js'; import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ @@ -11,7 +11,7 @@ export const manifests: Array = [ { type: 'menuItem', kind: 'tree', - alias: 'Umb.MenuItem.Media', + alias: UMB_MEDIA_MENU_ITEM_ALIAS, name: 'Media Menu Item', weight: 100, meta: { @@ -23,9 +23,13 @@ export const manifests: Array = [ }, { type: 'workspaceContext', + kind: 'menuStructure', name: 'Media Menu Structure Workspace Context', alias: 'Umb.Context.Media.Menu.Structure', api: () => import('./media-menu-structure.context.js'), + meta: { + menuItemAlias: UMB_MEDIA_MENU_ITEM_ALIAS, + }, conditions: [ { alias: UMB_WORKSPACE_CONDITION_ALIAS, diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/constants.ts index 5f144502c4..1c409bd6f9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/constants.ts @@ -1,5 +1,6 @@ export * from './entity-actions/constants.js'; export * from './member-type-root/constants.js'; +export * from './menu/constants.js'; export * from './paths.js'; export * from './property-type/constants.js'; export * from './repository/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/menu/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/menu/constants.ts new file mode 100644 index 0000000000..9f23bcf60c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/menu/constants.ts @@ -0,0 +1 @@ +export const UMB_MEMBER_TYPE_MENU_ITEM_ALIAS = 'Umb.MenuItem.MemberTypes'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/menu/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/menu/manifests.ts index 9c563c1bd2..b00f960418 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/menu/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/menu/manifests.ts @@ -1,11 +1,11 @@ -import { UMB_MEMBER_TYPE_TREE_ALIAS } from '../constants.js'; +import { UMB_MEMBER_TYPE_MENU_ITEM_ALIAS, UMB_MEMBER_TYPE_TREE_ALIAS } from '../constants.js'; import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { type: 'menuItem', kind: 'tree', - alias: 'Umb.MenuItem.MemberTypes', + alias: UMB_MEMBER_TYPE_MENU_ITEM_ALIAS, name: 'Member Type Menu Item', weight: 700, meta: { @@ -16,9 +16,13 @@ export const manifests: Array = [ }, { type: 'workspaceContext', + kind: 'menuStructure', name: 'Member Type Menu Structure Workspace Context', alias: 'Umb.Context.MemberType.Menu.Structure', api: () => import('./member-type-menu-structure.context.js'), + meta: { + menuItemAlias: UMB_MEMBER_TYPE_MENU_ITEM_ALIAS, + }, conditions: [ { alias: UMB_WORKSPACE_CONDITION_ALIAS, diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/constants.ts index 6afae28700..f582a679af 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/constants.ts @@ -1,5 +1,6 @@ export * from './entity-actions/constants.js'; +export * from './entity.js'; +export * from './menu/constants.js'; export * from './repository/constants.js'; export * from './tree/constants.js'; export * from './workspace/constants.js'; -export * from './entity.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/menu/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/menu/constants.ts new file mode 100644 index 0000000000..ad80a4635d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/menu/constants.ts @@ -0,0 +1 @@ +export const UMB_PARTIAL_VIEW_MENU_ITEM_ALIAS = 'Umb.MenuItem.PartialView'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/menu/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/menu/manifests.ts index 414875d9d6..7189714ccd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/menu/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/menu/manifests.ts @@ -1,11 +1,12 @@ import { UMB_PARTIAL_VIEW_TREE_ALIAS } from '../tree/index.js'; +import { UMB_PARTIAL_VIEW_MENU_ITEM_ALIAS } from './constants.js'; import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { type: 'menuItem', kind: 'tree', - alias: 'Umb.MenuItem.PartialView', + alias: UMB_PARTIAL_VIEW_MENU_ITEM_ALIAS, name: 'Partial View Menu Item', weight: 40, meta: { @@ -16,9 +17,13 @@ export const manifests: Array = [ }, { type: 'workspaceContext', + kind: 'menuStructure', name: 'Partial View Menu Structure Workspace Context', alias: 'Umb.Context.PartialView.Menu.Structure', api: () => import('./partial-view-menu-structure.context.js'), + meta: { + menuItemAlias: UMB_PARTIAL_VIEW_MENU_ITEM_ALIAS, + }, conditions: [ { alias: UMB_WORKSPACE_CONDITION_ALIAS, diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/menu/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/menu/manifests.ts index ae46cc2ec9..b7960bb90d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/menu/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/menu/manifests.ts @@ -17,9 +17,13 @@ export const manifests: Array = [ }, { type: 'workspaceContext', + kind: 'menuStructure', name: 'Script Menu Structure Workspace Context', alias: 'Umb.Context.Script.Menu.Structure', api: () => import('./script-menu-structure.context.js'), + meta: { + menuItemAlias: UMB_SCRIPT_MENU_ITEM_ALIAS, + }, conditions: [ { alias: UMB_WORKSPACE_CONDITION_ALIAS, diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/constants.ts index cb3c3c7348..1b0f9b850a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/constants.ts @@ -1,5 +1,6 @@ export * from './entity-actions/constants.js'; export * from './global-components/constants.js'; +export * from './menu/constants.js'; export * from './repository/constants.js'; export * from './tree/constants.js'; export * from './workspace/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/menu/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/menu/constants.ts new file mode 100644 index 0000000000..ac1784982e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/menu/constants.ts @@ -0,0 +1 @@ +export const UMB_STYLESHEET_MENU_ITEM_ALIAS = 'Umb.MenuItem.Stylesheets'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/menu/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/menu/manifests.ts index 6e69c74258..b14e048c3b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/menu/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/menu/manifests.ts @@ -1,11 +1,12 @@ import { UMB_STYLESHEET_TREE_ALIAS } from '../constants.js'; +import { UMB_STYLESHEET_MENU_ITEM_ALIAS } from './constants.js'; import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { type: 'menuItem', kind: 'tree', - alias: 'Umb.MenuItem.Stylesheets', + alias: UMB_STYLESHEET_MENU_ITEM_ALIAS, name: 'Stylesheets Menu Item', weight: 20, meta: { @@ -16,9 +17,13 @@ export const manifests: Array = [ }, { type: 'workspaceContext', + kind: 'menuStructure', name: 'Stylesheet Menu Structure Workspace Context', alias: 'Umb.Context.Stylesheet.Menu.Structure', api: () => import('./stylesheet-menu-structure.context.js'), + meta: { + menuItemAlias: UMB_STYLESHEET_MENU_ITEM_ALIAS, + }, conditions: [ { alias: UMB_WORKSPACE_CONDITION_ALIAS, diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/constants.ts index 9879ba5d2c..eac8bbbe48 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/constants.ts @@ -1,4 +1,5 @@ export * from './conditions/constants.js'; +export * from './menu/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/templating/templates/menu/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/menu/constants.ts new file mode 100644 index 0000000000..0b25774bd4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/menu/constants.ts @@ -0,0 +1 @@ +export const UMB_TEMPLATE_MENU_ITEM_ALIAS = 'Umb.MenuItem.Templates'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/menu/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/menu/manifests.ts index 3c63d3fe2b..02f0e9dd3d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/menu/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/menu/manifests.ts @@ -1,11 +1,12 @@ import { UMB_TEMPLATE_TREE_ALIAS } from '../tree/index.js'; +import { UMB_TEMPLATE_MENU_ITEM_ALIAS } from './constants.js'; import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { type: 'menuItem', kind: 'tree', - alias: 'Umb.MenuItem.Templates', + alias: UMB_TEMPLATE_MENU_ITEM_ALIAS, name: 'Templates Menu Item', weight: 40, meta: { @@ -17,9 +18,13 @@ export const manifests: Array = [ }, { type: 'workspaceContext', + kind: 'menuStructure', name: 'Template Menu Structure Workspace Context', alias: 'Umb.Context.Template.Menu.Structure', api: () => import('./template-menu-structure.context.js'), + meta: { + menuItemAlias: UMB_TEMPLATE_MENU_ITEM_ALIAS, + }, conditions: [ { alias: UMB_WORKSPACE_CONDITION_ALIAS, diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ChildrenContent.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ChildrenContent.spec.ts index 40e475199d..109ea86a0a 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ChildrenContent.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ChildrenContent.spec.ts @@ -41,10 +41,10 @@ test('can create child node', {tag: '@smoke'}, async ({umbracoApi, umbracoUi}) = expect(await umbracoApi.document.doesNameExist(childContentName)).toBeTruthy(); const childData = await umbracoApi.document.getChildren(contentId); expect(childData[0].variants[0].name).toBe(childContentName); - // verify that the child content displays in the tree after reloading children + // Verify that the child content displays in the tree after reloading children await umbracoUi.content.clickActionsMenuForContent(contentName); await umbracoUi.content.clickReloadChildrenActionMenuOption(); - await umbracoUi.content.clickCaretButtonForContentName(contentName); + await umbracoUi.content.openContentCaretButtonForName(contentName); await umbracoUi.content.doesContentTreeHaveName(childContentName); // Clean @@ -67,7 +67,7 @@ test('can create child node in child node', async ({umbracoApi, umbracoUi}) => { await umbracoUi.content.goToSection(ConstantHelper.sections.content); // Act - await umbracoUi.content.clickCaretButtonForContentName(contentName); + await umbracoUi.content.openContentCaretButtonForName(contentName); await umbracoUi.content.clickActionsMenuForContent(childContentName); await umbracoUi.content.clickCreateActionMenuOption(); await umbracoUi.content.chooseDocumentType(childOfChildDocumentTypeName); @@ -80,7 +80,7 @@ test('can create child node in child node', async ({umbracoApi, umbracoUi}) => { const childOfChildData = await umbracoApi.document.getChildren(childContentId); expect(childOfChildData[0].variants[0].name).toBe(childOfChildContentName); // verify that the child content displays in the tree - await umbracoUi.content.clickCaretButtonForContentName(childContentName); + await umbracoUi.content.openContentCaretButtonForName(childContentName); await umbracoUi.content.doesContentTreeHaveName(childOfChildContentName); // Clean @@ -98,7 +98,7 @@ test('cannot publish child if the parent is not published', async ({umbracoApi, await umbracoUi.content.goToSection(ConstantHelper.sections.content); // Act - await umbracoUi.content.clickCaretButtonForContentName(contentName); + await umbracoUi.content.openContentCaretButtonForName(contentName); await umbracoUi.content.clickActionsMenuForContent(childContentName); await umbracoUi.content.clickPublishActionMenuOption(); await umbracoUi.content.clickConfirmToPublishButton(); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ContentWithDocumentTypeProperties/ContentWithAllowedChildNodes.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ContentWithDocumentTypeProperties/ContentWithAllowedChildNodes.spec.ts index 86124bbebd..65437ebcac 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ContentWithDocumentTypeProperties/ContentWithAllowedChildNodes.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ContentWithDocumentTypeProperties/ContentWithAllowedChildNodes.spec.ts @@ -84,7 +84,7 @@ test('can create multiple child nodes with different document types', async ({um // verify that the child content displays in the tree after reloading children await umbracoUi.content.clickActionsMenuForContent(contentName); await umbracoUi.content.clickReloadChildrenActionMenuOption(); - await umbracoUi.content.clickCaretButtonForContentName(contentName); + await umbracoUi.content.openContentCaretButtonForName(contentName); await umbracoUi.content.doesContentTreeHaveName(firstChildContentName); await umbracoUi.content.doesContentTreeHaveName(secondChildContentName); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ContentWithListViewContent.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ContentWithListViewContent.spec.ts index 8d0af1b43b..6c509ff7bb 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ContentWithListViewContent.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Content/ContentWithListViewContent.spec.ts @@ -164,7 +164,7 @@ test.skip('child is removed from list after child content is deleted', async ({u expect(await umbracoApi.document.getChildrenAmount(documentId)).toEqual(1); // Act - await umbracoUi.content.clickCaretButtonForContentName(contentName); + await umbracoUi.content.openContentCaretButtonForName(contentName); await umbracoUi.content.clickActionsMenuForContent(childContentName); await umbracoUi.content.clickTrashActionMenuOption(); await umbracoUi.content.clickConfirmTrashButton(); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/DataTypeFolder.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/DataTypeFolder.spec.ts index 7429e8b2e1..0a274fdd1b 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/DataTypeFolder.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/DataType/DataTypeFolder.spec.ts @@ -114,7 +114,7 @@ test('can create a folder in a folder in a folder', async ({umbracoApi, umbracoU // Act await umbracoUi.dataType.clickRootFolderCaretButton(); - await umbracoUi.dataType.clickCaretButtonForName(dataTypeFolderName); + await umbracoUi.dataType.openCaretButtonForName(dataTypeFolderName); await umbracoUi.dataType.clickActionsMenuForDataType(childFolderName); await umbracoUi.dataType.createDataTypeFolder(childOfChildFolderName); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Media/ListViewMedia.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Media/ListViewMedia.spec.ts index 8861d71dcc..0e2560c55d 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Media/ListViewMedia.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Media/ListViewMedia.spec.ts @@ -126,7 +126,7 @@ test('can allow bulk move in the media section', async ({umbracoApi, umbracoUi}) await umbracoUi.media.selectMediaWithName(secondMediaFileName); await umbracoUi.waitForTimeout(200); await umbracoUi.media.clickBulkMoveToButton(); - await umbracoUi.media.clickCaretButtonForName('Media'); + await umbracoUi.media.openCaretButtonForName('Media'); await umbracoUi.media.clickModalTextByName(mediaFolderName); await umbracoUi.media.clickChooseModalButton(); await umbracoUi.waitForTimeout(500); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Media/Media.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Media/Media.spec.ts index 954ce88272..251f455072 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Media/Media.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Media/Media.spec.ts @@ -137,10 +137,8 @@ test('can create a folder in a folder', async ({umbracoApi, umbracoUi}) => { await umbracoUi.media.clickSaveButton(); // Assert - //await umbracoUi.media.waitForMediaItemToBeCreated(); // This is flaky, and Playwright seems to succeed even with its default timeout await umbracoUi.media.isMediaTreeItemVisible(parentFolderName); - await umbracoUi.media.isMediaTreeItemVisible(folderName, false); - await umbracoUi.media.clickMediaCaretButtonForName(parentFolderName); + await umbracoUi.media.openMediaCaretButtonForName(parentFolderName); await umbracoUi.media.isMediaTreeItemVisible(folderName, true); // Clean diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/DocumentType/DocumentTypeFolder.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/DocumentType/DocumentTypeFolder.spec.ts index 7ce674fea0..4c571df224 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/DocumentType/DocumentTypeFolder.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/DocumentType/DocumentTypeFolder.spec.ts @@ -25,7 +25,7 @@ test('can create a empty document type folder', {tag: '@smoke'}, async ({umbraco await umbracoUi.documentType.waitForDocumentTypeToBeCreated(); expect(await umbracoApi.documentType.doesNameExist(documentFolderName)).toBeTruthy(); // Checks if the folder is in the root - await umbracoUi.documentType.clickCaretButtonForName('Document Types'); + await umbracoUi.documentType.openCaretButtonForName('Document Types'); await umbracoUi.documentType.isDocumentTreeItemVisible(documentFolderName); }); @@ -105,7 +105,7 @@ test('can create a folder in a folder in a folder', {tag: '@smoke'}, async ({umb // Act await umbracoUi.documentType.goToSection(ConstantHelper.sections.settings); await umbracoUi.documentType.clickRootFolderCaretButton(); - await umbracoUi.documentType.clickCaretButtonForName(grandParentFolderName); + await umbracoUi.documentType.openCaretButtonForName(grandParentFolderName); await umbracoUi.documentType.clickActionsMenuForName(parentFolderName); await umbracoUi.documentType.clickCreateActionMenuOption(); await umbracoUi.documentType.clickCreateDocumentFolderButton(); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/MediaType/MediaTypeFolder.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/MediaType/MediaTypeFolder.spec.ts index f249e10f23..fa19f68f4d 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/MediaType/MediaTypeFolder.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/MediaType/MediaTypeFolder.spec.ts @@ -82,7 +82,7 @@ test('can create a media type folder in a folder', async ({umbracoApi, umbracoUi // Assert await umbracoUi.mediaType.waitForMediaTypeToBeCreated(); - await umbracoUi.mediaType.clickCaretButtonForName(mediaTypeFolderName); + await umbracoUi.mediaType.openCaretButtonForName(mediaTypeFolderName); await umbracoUi.mediaType.isTreeItemVisible(childFolderName, true); const parentFolderChildren = await umbracoApi.mediaType.getChildren(parentFolderId); expect(parentFolderChildren[0].name).toBe(childFolderName); @@ -102,7 +102,7 @@ test('can create a media type folder in a folder in a folder', async ({umbracoAp // Act await umbracoUi.mediaType.clickRootFolderCaretButton(); - await umbracoUi.mediaType.clickCaretButtonForName(grandparentFolderName); + await umbracoUi.mediaType.openCaretButtonForName(grandparentFolderName); await umbracoUi.mediaType.clickActionsMenuForName(mediaTypeFolderName); await umbracoUi.mediaType.clickCreateActionMenuOption(); await umbracoUi.mediaType.clickFolderButton(); @@ -111,7 +111,7 @@ test('can create a media type folder in a folder in a folder', async ({umbracoAp // Assert await umbracoUi.mediaType.waitForMediaTypeToBeCreated(); - await umbracoUi.mediaType.clickCaretButtonForName(mediaTypeFolderName); + await umbracoUi.mediaType.openCaretButtonForName(mediaTypeFolderName); await umbracoUi.mediaType.isTreeItemVisible(childFolderName, true); const grandParentFolderChildren = await umbracoApi.mediaType.getChildren(grandParentFolderId); expect(grandParentFolderChildren[0].name).toBe(mediaTypeFolderName); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/PartialView/PartialViewFolder.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/PartialView/PartialViewFolder.spec.ts index 3cd2806f9b..642cda5801 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/PartialView/PartialViewFolder.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/PartialView/PartialViewFolder.spec.ts @@ -69,8 +69,7 @@ test('can create a partial view in a folder', async ({umbracoApi, umbracoUi}) => const childrenData = await umbracoApi.partialView.getChildren(folderPath); expect(childrenData[0].name).toEqual(partialViewFileName); // Verify the partial view is displayed in the folder under the Partial Views section - await umbracoUi.partialView.isPartialViewRootTreeItemVisible(partialViewFileName, false, false); - await umbracoUi.partialView.clickCaretButtonForName(folderName); + await umbracoUi.partialView.openCaretButtonForName(folderName); await umbracoUi.partialView.isPartialViewRootTreeItemVisible(partialViewFileName, true, false); // Clean @@ -86,7 +85,7 @@ test('can create a partial view in a folder in a folder', async ({umbracoApi, um //Act await umbracoUi.partialView.reloadPartialViewTree(); - await umbracoUi.partialView.clickCaretButtonForName(folderName); + await umbracoUi.partialView.openCaretButtonForName(folderName); await umbracoUi.partialView.clickActionsMenuForPartialView(childFolderName); await umbracoUi.partialView.clickCreateOptionsActionMenuOption(); await umbracoUi.partialView.clickNewEmptyPartialViewButton(); @@ -118,7 +117,7 @@ test('can create a folder in a folder', async ({umbracoApi, umbracoUi}) => { expect(await umbracoApi.partialView.doesNameExist(childFolderName)).toBeTruthy(); const partialViewChildren = await umbracoApi.partialView.getChildren('/' + folderName); expect(partialViewChildren[0].path).toBe('/' + folderName + '/' + childFolderName); - await umbracoUi.partialView.clickCaretButtonForName(folderName); + await umbracoUi.partialView.openCaretButtonForName(folderName); await umbracoUi.partialView.isPartialViewRootTreeItemVisible(childFolderName, true, false); }); @@ -132,7 +131,7 @@ test('can create a folder in a folder in a folder', {tag: '@smoke'}, async ({umb // Act await umbracoUi.partialView.reloadPartialViewTree(); - await umbracoUi.partialView.clickCaretButtonForName(folderName); + await umbracoUi.partialView.openCaretButtonForName(folderName); await umbracoUi.partialView.clickActionsMenuForPartialView(childFolderName); await umbracoUi.partialView.createPartialViewFolder(childOfChildFolderName); @@ -141,7 +140,7 @@ test('can create a folder in a folder in a folder', {tag: '@smoke'}, async ({umb expect(await umbracoApi.partialView.doesNameExist(childOfChildFolderName)).toBeTruthy(); const partialViewChildren = await umbracoApi.partialView.getChildren('/' + folderName + '/' + childFolderName); expect(partialViewChildren[0].path).toBe('/' + folderName + '/' + childFolderName + '/' + childOfChildFolderName); - await umbracoUi.partialView.clickCaretButtonForName(childFolderName); + await umbracoUi.partialView.openCaretButtonForName(childFolderName); await umbracoUi.partialView.isPartialViewRootTreeItemVisible(childOfChildFolderName, true, false); }); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/Script/ScriptFolder.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/Script/ScriptFolder.spec.ts index 9698acb51f..88117c05b7 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/Script/ScriptFolder.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/Script/ScriptFolder.spec.ts @@ -65,7 +65,7 @@ test('can create a script in a folder', async ({umbracoApi, umbracoUi}) => { expect(scriptChildren[0].path).toBe('/' + scriptFolderName + '/' + scriptName); const scriptData = await umbracoApi.script.get(scriptChildren[0].path); expect(scriptData.content).toBe(scriptContent); - await umbracoUi.stylesheet.clickCaretButtonForName(scriptFolderName); + await umbracoUi.stylesheet.openCaretButtonForName(scriptFolderName); await umbracoUi.script.isScriptRootTreeItemVisible(scriptName, true, false); }); @@ -85,7 +85,7 @@ test('can create a folder in a folder', async ({umbracoApi, umbracoUi}) => { expect(await umbracoApi.script.doesNameExist(childFolderName)).toBeTruthy(); const scriptChildren = await umbracoApi.script.getChildren('/' + scriptFolderName); expect(scriptChildren[0].path).toBe('/' + scriptFolderName + '/' + childFolderName); - await umbracoUi.stylesheet.clickCaretButtonForName(scriptFolderName); + await umbracoUi.stylesheet.openCaretButtonForName(scriptFolderName); await umbracoUi.script.isScriptRootTreeItemVisible(childFolderName, true, false); }); @@ -99,7 +99,7 @@ test('can create a folder in a folder in a folder', {tag: '@smoke'}, async ({umb // Act await umbracoUi.script.reloadScriptTree(); - await umbracoUi.script.clickCaretButtonForName(scriptFolderName); + await umbracoUi.script.openCaretButtonForName(scriptFolderName); await umbracoUi.script.clickActionsMenuForScript(childFolderName); await umbracoUi.script.createScriptFolder(childOfChildFolderName); @@ -108,7 +108,7 @@ test('can create a folder in a folder in a folder', {tag: '@smoke'}, async ({umb expect(await umbracoApi.script.doesNameExist(childOfChildFolderName)).toBeTruthy(); const scriptChildren = await umbracoApi.script.getChildren('/' + scriptFolderName + '/' + childFolderName); expect(scriptChildren[0].path).toBe('/' + scriptFolderName + '/' + childFolderName + '/' + childOfChildFolderName); - await umbracoUi.stylesheet.clickCaretButtonForName(childFolderName); + await umbracoUi.stylesheet.openCaretButtonForName(childFolderName); await umbracoUi.script.isScriptRootTreeItemVisible(childOfChildFolderName, true, false); }); @@ -121,7 +121,7 @@ test('can create a script in a folder in a folder', async ({umbracoApi, umbracoU // Act await umbracoUi.script.reloadScriptTree(); - await umbracoUi.script.clickCaretButtonForName(scriptFolderName); + await umbracoUi.script.openCaretButtonForName(scriptFolderName); await umbracoUi.script.clickActionsMenuForScript(childFolderName); await umbracoUi.script.clickCreateOptionsActionMenuOption(); await umbracoUi.script.clickNewJavascriptFileButton(); @@ -133,7 +133,7 @@ test('can create a script in a folder in a folder', async ({umbracoApi, umbracoU expect(await umbracoApi.script.doesNameExist(scriptName)).toBeTruthy(); const scriptChildren = await umbracoApi.script.getChildren('/' + scriptFolderName + '/' + childFolderName); expect(scriptChildren[0].path).toBe('/' + scriptFolderName + '/' + childFolderName + '/' + scriptName); - await umbracoUi.stylesheet.clickCaretButtonForName(childFolderName); + await umbracoUi.stylesheet.openCaretButtonForName(childFolderName); await umbracoUi.script.isScriptRootTreeItemVisible(scriptName, true, false); }); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/Stylesheet/StylesheetFolder.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/Stylesheet/StylesheetFolder.spec.ts index 3c270b6d37..b2c9f04528 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/Stylesheet/StylesheetFolder.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Settings/Stylesheet/StylesheetFolder.spec.ts @@ -59,7 +59,7 @@ test('can create a folder in a folder', async ({umbracoApi, umbracoUi}) => { expect(await umbracoApi.stylesheet.doesNameExist(childFolderName)).toBeTruthy(); const styleChildren = await umbracoApi.stylesheet.getChildren('/' + stylesheetFolderName); expect(styleChildren[0].path).toBe('/' + stylesheetFolderName + '/' + childFolderName); - await umbracoUi.stylesheet.clickCaretButtonForName(stylesheetFolderName); + await umbracoUi.stylesheet.openCaretButtonForName(stylesheetFolderName); await umbracoUi.stylesheet.isStylesheetRootTreeItemVisible(childFolderName, true, false); }); @@ -73,7 +73,7 @@ test('can create a folder in a folder in a folder', {tag: '@smoke'}, async ({umb // Act await umbracoUi.stylesheet.reloadStylesheetTree(); - await umbracoUi.stylesheet.clickCaretButtonForName(stylesheetFolderName); + await umbracoUi.stylesheet.openCaretButtonForName(stylesheetFolderName); await umbracoUi.stylesheet.clickActionsMenuForStylesheet(childFolderName); await umbracoUi.stylesheet.createStylesheetFolder(childOfChildFolderName); @@ -82,7 +82,7 @@ test('can create a folder in a folder in a folder', {tag: '@smoke'}, async ({umb expect(await umbracoApi.stylesheet.doesNameExist(childOfChildFolderName)).toBeTruthy(); const styleChildren = await umbracoApi.stylesheet.getChildren('/' + stylesheetFolderName + '/' + childFolderName); expect(styleChildren[0].path).toBe('/' + stylesheetFolderName + '/' + childFolderName + '/' + childOfChildFolderName); - await umbracoUi.stylesheet.clickCaretButtonForName(childFolderName); + await umbracoUi.stylesheet.openCaretButtonForName(childFolderName); await umbracoUi.stylesheet.isStylesheetRootTreeItemVisible(childOfChildFolderName, true, false); }); @@ -108,7 +108,7 @@ test('can create a stylesheet in a folder', async ({umbracoApi, umbracoUi}) => { expect(stylesheetChildren[0].path).toBe('/' + stylesheetFolderName + '/' + stylesheetName); const stylesheetData = await umbracoApi.stylesheet.get(stylesheetChildren[0].path); expect(stylesheetData.content).toBe(stylesheetContent); - await umbracoUi.stylesheet.clickCaretButtonForName(stylesheetFolderName); + await umbracoUi.stylesheet.openCaretButtonForName(stylesheetFolderName); await umbracoUi.stylesheet.isStylesheetRootTreeItemVisible(stylesheetName, true, false); }); @@ -122,7 +122,7 @@ test('can create a stylesheet in a folder in a folder', async ({umbracoApi, umbr //Act await umbracoUi.stylesheet.reloadStylesheetTree(); - await umbracoUi.stylesheet.clickCaretButtonForName(stylesheetFolderName); + await umbracoUi.stylesheet.openCaretButtonForName(stylesheetFolderName); await umbracoUi.stylesheet.clickActionsMenuForStylesheet(childFolderName); await umbracoUi.stylesheet.clickCreateActionMenuOption(); await umbracoUi.stylesheet.clickNewStylesheetButton(); @@ -137,7 +137,7 @@ test('can create a stylesheet in a folder in a folder', async ({umbracoApi, umbr expect(stylesheetChildren[0].path).toBe('/' + stylesheetFolderName + '/' + childFolderName + '/' + stylesheetName); const stylesheetData = await umbracoApi.stylesheet.get(stylesheetChildren[0].path); expect(stylesheetData.content).toBe(stylesheetContent); - await umbracoUi.stylesheet.clickCaretButtonForName(childFolderName); + await umbracoUi.stylesheet.openCaretButtonForName(childFolderName); await umbracoUi.stylesheet.isStylesheetRootTreeItemVisible(stylesheetName, true, false); }); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/User/ContentStartNodes.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/User/ContentStartNodes.spec.ts index ea84ad5161..b2445d4588 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/User/ContentStartNodes.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/User/ContentStartNodes.spec.ts @@ -52,7 +52,7 @@ test('can see root start node and children', async ({umbracoApi, umbracoUi}) => // Assert await umbracoUi.content.isContentInTreeVisible(rootDocumentName); - await umbracoUi.content.clickCaretButtonForContentName(rootDocumentName); + await umbracoUi.content.openContentCaretButtonForName(rootDocumentName); await umbracoUi.content.isChildContentInTreeVisible(rootDocumentName, childDocumentOneName); await umbracoUi.content.isChildContentInTreeVisible(rootDocumentName, childDocumentTwoName); }); @@ -70,7 +70,7 @@ test('can see parent of start node but not access it', async ({umbracoApi, umbra await umbracoUi.content.isContentInTreeVisible(rootDocumentName); await umbracoUi.content.goToContentWithName(rootDocumentName); await umbracoUi.content.doesDocumentWorkspaceHaveText('Access denied'); - await umbracoUi.content.clickCaretButtonForContentName(rootDocumentName); + await umbracoUi.content.openContentCaretButtonForName(rootDocumentName); await umbracoUi.content.isChildContentInTreeVisible(rootDocumentName, childDocumentOneName); await umbracoUi.content.isChildContentInTreeVisible(rootDocumentName, childDocumentTwoName, false); }); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/User/MediaStartNodes.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/User/MediaStartNodes.spec.ts index c8720a7a41..f16608353b 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/User/MediaStartNodes.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/User/MediaStartNodes.spec.ts @@ -45,7 +45,7 @@ test('can see root media start node and children', async ({umbracoApi, umbracoUi // Assert await umbracoUi.media.isMediaTreeItemVisible(rootFolderName); - await umbracoUi.media.clickCaretButtonForMediaName(rootFolderName); + await umbracoUi.media.openMediaCaretButtonForName(rootFolderName); await umbracoUi.media.isChildMediaVisible(rootFolderName, childFolderOneName); await umbracoUi.media.isChildMediaVisible(rootFolderName, childFolderTwoName); }); @@ -63,7 +63,7 @@ test('can see parent of start node but not access it', async ({umbracoApi, umbra await umbracoUi.media.isMediaTreeItemVisible(rootFolderName); await umbracoUi.media.goToMediaWithName(rootFolderName); await umbracoUi.media.doesMediaWorkspaceHaveText('Access denied'); - await umbracoUi.media.clickCaretButtonForMediaName(rootFolderName); + await umbracoUi.media.openMediaCaretButtonForName(rootFolderName); await umbracoUi.media.isChildMediaVisible(rootFolderName, childFolderOneName); await umbracoUi.media.isChildMediaVisible(rootFolderName, childFolderTwoName, false); }); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/ContentStartNodes.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/ContentStartNodes.spec.ts index 1648b0e6ff..82178e73fc 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/ContentStartNodes.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/ContentStartNodes.spec.ts @@ -53,7 +53,7 @@ test('can see root start node and children', async ({umbracoApi, umbracoUi}) => // Assert await umbracoUi.content.isContentInTreeVisible(rootDocumentName); - await umbracoUi.content.clickCaretButtonForContentName(rootDocumentName); + await umbracoUi.content.openContentCaretButtonForName(rootDocumentName); await umbracoUi.content.isChildContentInTreeVisible(rootDocumentName, childDocumentOneName); await umbracoUi.content.isChildContentInTreeVisible(rootDocumentName, childDocumentTwoName); }); @@ -72,7 +72,7 @@ test('can see parent of start node but not access it', async ({umbracoApi, umbra await umbracoUi.content.isContentInTreeVisible(rootDocumentName); await umbracoUi.content.goToContentWithName(rootDocumentName); await umbracoUi.content.doesDocumentWorkspaceHaveText('Access denied'); - await umbracoUi.content.clickCaretButtonForContentName(rootDocumentName); + await umbracoUi.content.openContentCaretButtonForName(rootDocumentName); await umbracoUi.content.isChildContentInTreeVisible(rootDocumentName, childDocumentOneName); await umbracoUi.content.isChildContentInTreeVisible(rootDocumentName, childDocumentTwoName, false); }); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/DefaultPermissionsInContent.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/DefaultPermissionsInContent.spec.ts index 2960ad27fa..32837242d1 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/DefaultPermissionsInContent.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/DefaultPermissionsInContent.spec.ts @@ -435,7 +435,7 @@ test.fixme('can move content with move to permission enabled', {tag: '@release'} await umbracoUi.content.goToSection(ConstantHelper.sections.content, false); // Act - await umbracoUi.content.clickCaretButtonForContentName(rootDocumentName); + await umbracoUi.content.openContentCaretButtonForName(rootDocumentName); await umbracoUi.content.clickActionsMenuForContent(childDocumentOneName); await umbracoUi.content.clickMoveToActionMenuOption(); await umbracoUi.content.moveToContentWithName([], moveToDocumentName); @@ -444,7 +444,7 @@ test.fixme('can move content with move to permission enabled', {tag: '@release'} await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.moved); await umbracoUi.content.reloadContentTree(); await umbracoUi.content.isCaretButtonVisibleForContentName(moveToDocumentName, true); - await umbracoUi.content.clickCaretButtonForContentName(moveToDocumentName); + await umbracoUi.content.openContentCaretButtonForName(moveToDocumentName); await umbracoUi.content.isChildContentInTreeVisible(moveToDocumentName, childDocumentOneName, true); await umbracoUi.content.isCaretButtonVisibleForContentName(rootDocumentName, false); expect(await umbracoApi.document.getChildrenAmount(rootDocumentId)).toEqual(0); @@ -489,7 +489,7 @@ test.fixme('can sort children with sort children permission enabled', {tag: '@re // Assert // TODO: uncomment when it is not flaky - await umbracoUi.content.clickCaretButtonForContentName(rootDocumentName); + await umbracoUi.content.openContentCaretButtonForName(rootDocumentName); await umbracoUi.content.doesIndexDocumentInTreeContainName(rootDocumentName, childDocumentTwoName, 0); await umbracoUi.content.doesIndexDocumentInTreeContainName(rootDocumentName, childDocumentOneName, 1); }); @@ -669,4 +669,4 @@ test('can create and update content with permission enabled', {tag: '@release'}, // Cleanup await umbracoApi.document.ensureNameNotExists(updatedDocumentName); -}); +}); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/GranularPermissionsInContent.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/GranularPermissionsInContent.spec.ts index e2cb5eedef..bd5b2f94d1 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/GranularPermissionsInContent.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/GranularPermissionsInContent.spec.ts @@ -223,7 +223,7 @@ test('can move a specific content with move to permission enabled', async ({umbr await umbracoUi.content.goToSection(ConstantHelper.sections.content, false); // Act - await umbracoUi.content.clickCaretButtonForContentName(firstDocumentName); + await umbracoUi.content.openContentCaretButtonForName(firstDocumentName); await umbracoUi.content.clickActionsMenuForContent(childDocumentName); await umbracoUi.content.clickMoveToActionMenuOption(); await umbracoUi.content.moveToContentWithName([], moveToDocumentName); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/MediaStartNodes.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/MediaStartNodes.spec.ts index 7c71bb01fc..be8b531d44 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/MediaStartNodes.spec.ts +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Users/Permissions/UserGroup/MediaStartNodes.spec.ts @@ -45,7 +45,7 @@ test('can see root media start node and children', {tag: '@release'}, async ({um // Assert await umbracoUi.media.isMediaTreeItemVisible(rootFolderName); - await umbracoUi.media.clickCaretButtonForMediaName(rootFolderName); + await umbracoUi.media.openMediaCaretButtonForName(rootFolderName); await umbracoUi.media.isChildMediaVisible(rootFolderName, childFolderOneName); await umbracoUi.media.isChildMediaVisible(rootFolderName, childFolderTwoName); }); @@ -64,7 +64,7 @@ test('can see parent of start node but not access it', async ({umbracoApi, umbra await umbracoUi.media.isMediaTreeItemVisible(rootFolderName); await umbracoUi.media.goToMediaWithName(rootFolderName); await umbracoUi.media.doesMediaWorkspaceHaveText('Access denied'); - await umbracoUi.media.clickCaretButtonForMediaName(rootFolderName); + await umbracoUi.media.openMediaCaretButtonForName(rootFolderName); await umbracoUi.media.isChildMediaVisible(rootFolderName, childFolderOneName); await umbracoUi.media.isChildMediaVisible(rootFolderName, childFolderTwoName, false); }); From 7f720ddf7c55e19d853414fb12b5b22b5110aa97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 29 Aug 2025 10:12:57 +0200 Subject: [PATCH 28/33] Implement root property validation for member workspace (#19972) * todos * navigation context * replace raw manifests with view context * Array State has method * rename to hint and much more * Notes for later * correcting one word * more notes * update JS Docs * update tests for getHasOne * fix context api usage * update code for v.16 * correct test * export UMB_WORKSPACE_VIEW_CONTEXT * minor corrections * rename to _hintMap * refactor part 1 * update version number in comment * clear method for array states * declare hint import map * mega refactor * final corrections for working POC * clean up path logic * implement scaffold * propagation and inheritance from view to workspace * separate types from classes * refactor to view context * rename editor navigation context to editor context * propagate removals * clean up notes * Hints for Content Tabs * use const path * handle gone parent * added comments on something to be looked at * hints context types * contentTypeMergedContainers * lint fixes * public contentTypeMergedContainers * refactor property structure helper class * a few notes for Presets * set variant ID instead of parsing it to the constructor * do not inject root to the path * adjust structure manager logic * UmbPropertyTypeContainerMergedModel type update * correct mergedContainersOfParentIdAndType * fix lint errors * fix missing import * Update src/Umbraco.Web.UI.Client/src/packages/core/hint/context/hints.controller.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-validation-to-hints.manager.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-validation-to-hints.manager.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * clean up * remove console.log * fix validation context initialization * add member workspace view consts * setup validation badges for member workspace root fields * declare new exports of core * Update src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/value-validator/valueValidator.controller.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * add comment * fix example * fix comment * fix member workspace failed request * remove console log * enable server side validation * fix circlular dependency * fix lint errors * export conts * fix import * clean up * fix type * fix password validation case * chore(eslint): reorders imports and cleans unused variables --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> --- .../hint-workspace-view.ts | 2 +- .../workspace/block-workspace.context.ts | 2 +- .../content-type-structure-manager.class.ts | 2 + .../content-validation-to-hints.manager.ts | 2 +- .../src/packages/core/property/index.ts | 1 + .../index.ts | 1 + ...y-dataset-property-validator.controller.ts | 28 +++++ .../core/utils/path/stored-path.function.ts | 2 +- .../core/validation/controllers/index.ts | 1 + .../controllers/value-validator/index.ts | 1 + .../value-validator.controller.ts | 112 ++++++++++++++++++ .../core/view/context/view.context.ts | 1 + .../workspace-editor.element.ts | 3 +- .../member-validation.server.data-source.ts | 9 +- .../member/workspace/member/constants.ts | 5 +- .../member/workspace/member/manifests.ts | 11 +- .../member/member-workspace.context.ts | 97 ++++++++++++++- ...mber-workspace-view-member-info.element.ts | 19 +-- .../member-workspace-view-member.element.ts | 11 +- .../repository/sources/package.server.data.ts | 2 +- 20 files changed, 282 insertions(+), 30 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/property/property-dataset-property-validator/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/property/property-dataset-property-validator/property-dataset-property-validator.controller.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/value-validator/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/value-validator/value-validator.controller.ts diff --git a/src/Umbraco.Web.UI.Client/examples/workspace-view-hint/hint-workspace-view.ts b/src/Umbraco.Web.UI.Client/examples/workspace-view-hint/hint-workspace-view.ts index 24a4d2ce03..8678114981 100644 --- a/src/Umbraco.Web.UI.Client/examples/workspace-view-hint/hint-workspace-view.ts +++ b/src/Umbraco.Web.UI.Client/examples/workspace-view-hint/hint-workspace-view.ts @@ -46,7 +46,7 @@ export class ExampleHintWorkspaceView extends UmbElementMixin(LitElement) { } else { workspace.hints.addOne({ unique: 'exampleHintFromToggleAction', - path: ['Umb.WorkspaceView.Document.Edit', 'root'], + path: ['Umb.WorkspaceView.Document.Edit'], text: 'Hi', color: 'invalid', weight: 100, diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-workspace.context.ts index 29cb77d489..7be599c5a2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-workspace.context.ts @@ -3,6 +3,7 @@ import { UMB_BLOCK_ENTRIES_CONTEXT, UMB_BLOCK_ENTRY_CONTEXT, UMB_BLOCK_MANAGER_C import { UmbBlockWorkspaceEditorElement } from './block-workspace-editor.element.js'; import { UmbBlockElementManager } from './block-element-manager.js'; import type { UmbBlockWorkspaceOriginData } from './block-workspace.modal-token.js'; +import { UMB_BLOCK_WORKSPACE_VIEW_CONTENT, UMB_BLOCK_WORKSPACE_VIEW_SETTINGS } from './constants.js'; import { UmbSubmittableWorkspaceContextBase, type UmbRoutableWorkspaceContext, @@ -23,7 +24,6 @@ import { decodeFilePath, UmbReadOnlyVariantGuardManager } from '@umbraco-cms/bac import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import type { UUIModalSidebarSize } from '@umbraco-cms/backoffice/external/uui'; -import { UMB_BLOCK_WORKSPACE_VIEW_CONTENT, UMB_BLOCK_WORKSPACE_VIEW_SETTINGS } from './constants.js'; export type UmbBlockWorkspaceElementManagerNames = 'content' | 'settings'; export class UmbBlockWorkspaceContext diff --git a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-structure-manager.class.ts b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-structure-manager.class.ts index 192a36204a..ffb224e144 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-structure-manager.class.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-structure-manager.class.ts @@ -953,6 +953,7 @@ export class UmbContentTypeStructureManager< * Find merged containers that match the provided container ids. * Notice if you can provide one or more ids matching the same container and it will still only return return the matching container once. * @param containerIds - An array of container ids to find merged containers for. + * @param id * @returns {UmbPropertyTypeContainerMergedModel | undefined} - The merged containers that match the provided container ids. */ getMergedContainerById(id: string): UmbPropertyTypeContainerMergedModel | undefined { @@ -964,6 +965,7 @@ export class UmbContentTypeStructureManager< * Find merged child containers that are children of the provided parent container ids. * Notice this will find matching containers and include their child containers in this. * @param containerIds - An array of container ids to find merged child containers for. + * @param searchId * @param type - The type of the containers to find. * @returns {Observable} - An observable that emits the merged child containers that match the provided container ids. */ diff --git a/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-validation-to-hints.manager.ts b/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-validation-to-hints.manager.ts index 2811bebfa7..4dad30c592 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-validation-to-hints.manager.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-validation-to-hints.manager.ts @@ -21,7 +21,7 @@ export class UmbContentValidationToHintsManager< > extends UmbControllerBase { /*workspace.hints.addOne({ unique: 'exampleHintFromToggleAction', - path: ['Umb.WorkspaceView.Document.Edit', 'root'], + path: ['Umb.WorkspaceView.Document.Edit'], text: 'Hi', color: 'invalid', weight: 100, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/index.ts index dc09da0afb..84193ff39d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/index.ts @@ -1,5 +1,6 @@ export * from './components/index.js'; export * from './conditions/index.js'; +export * from './property-dataset-property-validator/index.js'; export * from './property-dataset/index.js'; export * from './property-guard-manager/index.js'; export * from './property-value-cloner/property-value-clone.controller.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-dataset-property-validator/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-dataset-property-validator/index.ts new file mode 100644 index 0000000000..101f710e39 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-dataset-property-validator/index.ts @@ -0,0 +1 @@ +export * from './property-dataset-property-validator.controller.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-dataset-property-validator/property-dataset-property-validator.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-dataset-property-validator/property-dataset-property-validator.controller.ts new file mode 100644 index 0000000000..be18b6cb79 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-dataset-property-validator/property-dataset-property-validator.controller.ts @@ -0,0 +1,28 @@ +import { UMB_PROPERTY_DATASET_CONTEXT } from '../property-dataset/property-dataset-context.token.js'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbValueValidator, type UmbValueValidatorArgs } from '@umbraco-cms/backoffice/validation'; + +export interface UmbPropertyDatasetPropertyValidatorArgs extends UmbValueValidatorArgs { + propertyAlias: string; +} + +// The Example Workspace Context Controller: +export class UmbPropertyDatasetPropertyValidator extends UmbValueValidator { + // + #propertyAlias: string; + + constructor(host: UmbControllerHost, args: UmbPropertyDatasetPropertyValidatorArgs) { + super(host, args); + this.#propertyAlias = args.propertyAlias; + + this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, async (context) => { + this.observe( + await context?.propertyValueByAlias(this.#propertyAlias), + (value) => { + this.value = value; + }, + 'observeDatasetValue', + ); + }); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/stored-path.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/stored-path.function.ts index 24d280c861..e143ee3920 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/stored-path.function.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/stored-path.function.ts @@ -35,7 +35,7 @@ export function setStoredPath(path: string): void { * Redirect the user to the stored path or the base path if not available. * If the basePath matches the start of the stored path, the browser will replace the state instead of redirecting. * @param {string} basePath - The base path to redirect to if no stored path is available. - * @param {boolean} [force=false] - If true, will redirect using Location + * @param {boolean} [force] - If true, will redirect using Location */ export function redirectToStoredPath(basePath: string, force = false): void { const url = retrieveStoredPath(); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/index.ts index 99f8c0d35a..08f66aede1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/index.ts @@ -3,3 +3,4 @@ export * from './form-control-validator.controller.js'; export * from './observe-validation-state.controller.js'; export * from './validation-path-translation/index.js'; export * from './validation.controller.js'; +export * from './value-validator/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/value-validator/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/value-validator/index.ts new file mode 100644 index 0000000000..4e9b121518 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/value-validator/index.ts @@ -0,0 +1 @@ +export * from './value-validator.controller.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/value-validator/value-validator.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/value-validator/value-validator.controller.ts new file mode 100644 index 0000000000..dd7c1cf99c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/value-validator/value-validator.controller.ts @@ -0,0 +1,112 @@ +import { UMB_VALIDATION_CONTEXT } from '../../context/validation.context-token.js'; +import type { UmbValidator } from '../../interfaces/validator.interface.js'; +import { UMB_VALIDATION_EMPTY_LOCALIZATION_KEY } from '../../const.js'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; + +export interface UmbValueValidatorArgs { + dataPath?: string; + check?: (value: ValueType) => boolean; + message?: () => string; + navigateToError?: () => void; +} + +/** + * UmbValueValidator is a controller that implements the UmbValidator interface. + * It validates a value based on a provided check function, manages validation state, + * and communicates validation messages to the validation context. + * It can also handle navigation to the first invalid element if needed. + */ +export class UmbValueValidator extends UmbControllerBase implements UmbValidator { + // + #validationContext?: typeof UMB_VALIDATION_CONTEXT.TYPE; + #validationMode: boolean = false; + + #dataPath: undefined | string; + #check: (value: ValueType) => boolean; + #message: () => string; + #navigateToError?: () => void; + + #isValid: boolean = false; + #value?: ValueType; + + set value(value: ValueType | undefined) { + this.#value = value; + this.runCheck(); + } + get value(): ValueType | undefined { + return this.#value; + } + + constructor(host: UmbControllerHost, args: UmbValueValidatorArgs) { + super(host); + this.#dataPath = args.dataPath; + this.#check = + args.check ?? + ((value: ValueType) => { + return value === undefined || value === null || value === ''; + }); + this.#message = args.message ?? (() => UMB_VALIDATION_EMPTY_LOCALIZATION_KEY); + this.#navigateToError = args.navigateToError; + + this.consumeContext(UMB_VALIDATION_CONTEXT, (context) => { + if (this.#validationContext !== context) { + this.#validationContext?.removeValidator(this); + this.#validationContext = context; + this.#validationContext?.addValidator(this); + this.runCheck(); + } + }); + } + + runCheck() { + if (!this.#validationMode) return; + // Check validation: + this.#isValid = !this.#check(this.#value as ValueType); + + // Update validation message: + if (this.#validationContext) { + if (this.#dataPath) { + if (this.#isValid) { + this.#validationContext.messages.removeMessagesByTypeAndPath('custom', this.#dataPath); + } else { + this.#validationContext.messages.addMessage('custom', this.#dataPath, this.#message()); + } + } + } + } + + async validate(): Promise { + this.#validationMode = true; + // Validate is called when the validation state of this validator is asked to be fully resolved. Like when user clicks Save & Publish. + // If you need to ask the server then it could be done here, instead of asking the server each time the value changes. + // In this particular example we do not need to do anything, because our validation is represented via a message that we always set no matter the user interaction. + // If we did not like to only to check the Validation State when absolute needed then this method must be implemented. + return this.runCheck(); + } + + get isValid(): boolean { + return this.#isValid; + } + + reset(): void { + this.#isValid = false; + this.#validationMode = false; + } + + /** + * Focus the first invalid element. + */ + focusFirstInvalidElement(): void { + this.#navigateToError?.(); + } + + override destroy(): void { + if (!this.#isValid && this.#dataPath) { + this.#validationContext?.messages.removeMessagesByTypeAndPath('custom', this.#dataPath); + } + this.#validationContext = undefined; + this.#value = undefined; + super.destroy(); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/view/context/view.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/view/context/view.context.ts index fdd124adca..6930c4fa94 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/view/context/view.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/view/context/view.context.ts @@ -33,6 +33,7 @@ export class UmbViewContext extends UmbControllerBase { viewAlias: viewAlias, }); this.firstHintOfVariant = mergeObservables([this.variantId, this.hints.hints], ([variantId, hints]) => { + // Notice, because we in UI have invariant fields on Variants, then we will accept invariant hints on variants. if (variantId) { return hints.find((hint) => hint.variantId ? hint.variantId.equal(variantId!) || hint.variantId.isInvariant() : true, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts index 10866294c8..da8ecccf87 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts @@ -213,7 +213,8 @@ export class UmbWorkspaceEditorElement extends UmbLitElement { } #renderRoutes() { - if (!this._routes || this._routes.length === 0 || !this._workspaceViews || this._workspaceViews.length === 0) return nothing; + if (!this._routes || this._routes.length === 0 || !this._workspaceViews || this._workspaceViews.length === 0) + return nothing; return html` > { if (!model) throw new Error('Member is missing'); if (!model.unique) throw new Error('Member unique is missing'); - if (!model.newPassword) throw new Error('Member newPassword is missing'); + //if (!model.newPassword) throw new Error('Member newPassword is missing'); if (parentUnique === undefined) throw new Error('Parent unique is missing'); - // TODO: make data mapper to prevent errors - const body: CreateMemberRequestModel = { + const body: PostMemberValidateData['body'] = { email: model.email, username: model.username, - password: model.newPassword, + password: model.newPassword ?? '', isApproved: model.isApproved, id: model.unique, memberType: { id: model.memberType.unique }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/constants.ts index 697ec98e91..465892c416 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/constants.ts @@ -9,4 +9,7 @@ export const UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD: UmbMemberVariantModel = { } as const; export { UMB_MEMBER_WORKSPACE_CONTEXT } from './member-workspace.context-token.js'; -export { UMB_MEMBER_WORKSPACE_ALIAS } from './manifests.js'; + +export const UMB_MEMBER_WORKSPACE_ALIAS = 'Umb.Workspace.Member'; +export const UMB_MEMBER_WORKSPACE_VIEW_CONTENT_ALIAS = 'Umb.WorkspaceView.Member.Content'; +export const UMB_MEMBER_WORKSPACE_VIEW_MEMBER_ALIAS = 'Umb.WorkspaceView.Member.Member'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/manifests.ts index aac2a61278..7b72163b99 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/manifests.ts @@ -6,8 +6,11 @@ import type { } from '@umbraco-cms/backoffice/workspace'; import { UmbSubmitWorkspaceAction, UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_CONTENT_HAS_PROPERTIES_WORKSPACE_CONDITION } from '@umbraco-cms/backoffice/content'; - -export const UMB_MEMBER_WORKSPACE_ALIAS = 'Umb.Workspace.Member'; +import { + UMB_MEMBER_WORKSPACE_ALIAS, + UMB_MEMBER_WORKSPACE_VIEW_CONTENT_ALIAS, + UMB_MEMBER_WORKSPACE_VIEW_MEMBER_ALIAS, +} from './constants.js'; const workspace: ManifestWorkspaces = { type: 'workspace', @@ -45,7 +48,7 @@ export const workspaceViews: Array = [ { type: 'workspaceView', kind: 'contentEditor', - alias: 'Umb.WorkspaceView.Member.Content', + alias: UMB_MEMBER_WORKSPACE_VIEW_CONTENT_ALIAS, name: 'Member Workspace Content View', weight: 1000, meta: { @@ -65,7 +68,7 @@ export const workspaceViews: Array = [ }, { type: 'workspaceView', - alias: 'Umb.WorkspaceView.Member.Member', + alias: UMB_MEMBER_WORKSPACE_VIEW_MEMBER_ALIAS, name: 'Member Workspace Member View', js: () => import('./views/member/member-workspace-view-member.element.js'), weight: 500, diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/member-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/member-workspace.context.ts index ee4233573a..1ea4c9e97d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/member-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/member-workspace.context.ts @@ -1,11 +1,14 @@ -import type { UmbMemberDetailRepository } from '../../repository/index.js'; +import { UmbMemberValidationRepository, type UmbMemberDetailRepository } from '../../repository/index.js'; import type { UmbMemberDetailModel, UmbMemberVariantModel } from '../../types.js'; import { UmbMemberPropertyDatasetContext } from '../../property-dataset-context/member-property-dataset.context.js'; import { UMB_MEMBER_ENTITY_TYPE, UMB_MEMBER_ROOT_ENTITY_TYPE } from '../../entity.js'; import { UMB_MEMBER_DETAIL_REPOSITORY_ALIAS } from '../../repository/detail/manifests.js'; -import { UMB_MEMBER_WORKSPACE_ALIAS } from './manifests.js'; +import { + UMB_MEMBER_WORKSPACE_ALIAS, + UMB_MEMBER_WORKSPACE_VIEW_MEMBER_ALIAS, + UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD, +} from './constants.js'; import { UmbMemberWorkspaceEditorElement } from './member-workspace-editor.element.js'; -import { UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD } from './constants.js'; import { UmbMemberTypeDetailRepository, type UmbMemberTypeDetailModel } from '@umbraco-cms/backoffice/member-type'; import { UmbWorkspaceIsNewRedirectController, @@ -14,6 +17,9 @@ import { import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import { UmbContentDetailWorkspaceContextBase, type UmbContentWorkspaceContext } from '@umbraco-cms/backoffice/content'; +import { ensurePathEndsWithSlash } from '@umbraco-cms/backoffice/utils'; +import { UmbValueValidator } from '@umbraco-cms/backoffice/validation'; +import type { UmbValueValidatorArgs } from '@umbraco-cms/backoffice/validation'; type ContentModel = UmbMemberDetailModel; type ContentTypeModel = UmbMemberTypeDetailModel; @@ -39,8 +45,7 @@ export class UmbMemberWorkspaceContext workspaceAlias: UMB_MEMBER_WORKSPACE_ALIAS, detailRepositoryAlias: UMB_MEMBER_DETAIL_REPOSITORY_ALIAS, contentTypeDetailRepository: UmbMemberTypeDetailRepository, - // TODO: Enable Validation Repository when we have UI for showing validation issues on other tabs. [NL] - //contentValidationRepository: UmbMemberValidationRepository, + contentValidationRepository: UmbMemberValidationRepository, contentVariantScaffold: UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD, contentTypePropertyName: 'memberType', }); @@ -83,6 +88,84 @@ export class UmbMemberWorkspaceContext }, }, ]); + + this.#setupValidationCheckForRootProperty('username'); + this.#setupValidationCheckForRootProperty('email'); + const passwordValidator = this.#setupValidationCheckForRootProperty( + 'newPassword', + (value: string | null | undefined) => { + // Only when in create mode. + return this.getIsNew() === true && (value === undefined || value === null || value === ''); + }, + ); + + this.observe( + this.isNew, + () => { + passwordValidator.runCheck(); + }, + null, + ); + } + + #hintedMsgs: Set = new Set(); + + // A simple observation function to check for validation issues of a root property and map the validation message to a hint. + #setupValidationCheckForRootProperty( + propertyName: string, + checkMethod?: UmbValueValidatorArgs['check'], + ) { + const dataPath = `$.${propertyName}`; + const validator = new UmbValueValidator(this, { + dataPath, + navigateToError: () => { + const router = this.getHostElement().shadowRoot!.querySelector('umb-router-slot')!; + const routerPath = router.absoluteActiveViewPath; + if (routerPath) { + const newPath: string = ensurePathEndsWithSlash(routerPath) + 'invariant/view/info'; + // Check that we are still part of the DOM and thereby relevant: + window.history.replaceState(null, '', newPath); + } + }, + check: checkMethod, + }); + this.observe( + this._data.createObservablePartOfCurrent((data) => { + return data?.[propertyName as unknown as keyof ContentModel] as ValueType; + }), + (value) => { + validator.value = value; + }, + `validateObserverFor_${propertyName}`, + ); + + // Observe Validation and turn it into hint: + this.observe( + this.validationContext.messages.messagesOfPathAndDescendant(dataPath), + (messages) => { + messages.forEach((message) => { + if (this.#hintedMsgs.has(message.key)) return; + + this.hints.addOne({ + unique: message.key, + path: [UMB_MEMBER_WORKSPACE_VIEW_MEMBER_ALIAS], + text: '!', + color: 'invalid', + weight: 1000, + }); + this.#hintedMsgs.add(message.key); + }); + this.#hintedMsgs.forEach((key) => { + if (!messages.some((msg) => msg.key === key)) { + this.#hintedMsgs.delete(key); + this.hints.removeOne(key); + } + }); + }, + `messageObserverFor_${propertyName}`, + ); + + return validator; } async create(memberTypeUnique: string) { @@ -145,6 +228,10 @@ export class UmbMemberWorkspaceContext return this.#get('username') || ''; } + get newPassword(): string { + return this.#get('newPassword') || ''; + } + get isLockedOut(): boolean { return this.#get('isLockedOut') || false; } 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 834e71cc11..8998552fd1 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 @@ -15,7 +15,7 @@ import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-reg @customElement('umb-member-workspace-view-member-info') export class UmbMemberWorkspaceViewMemberInfoElement extends UmbLitElement implements UmbWorkspaceViewElement { @state() - private _memberTypeUnique = ''; + private _memberTypeUnique?: string; @state() private _memberTypeName = ''; @@ -58,16 +58,21 @@ export class UmbMemberWorkspaceViewMemberInfoElement extends UmbLitElement imple this.consumeContext(UMB_MEMBER_WORKSPACE_CONTEXT, async (context) => { this.#workspaceContext = context; - this.observe(this.#workspaceContext?.contentTypeUnique, (unique) => (this._memberTypeUnique = unique || '')); + this.observe(this.#workspaceContext?.contentTypeUnique, async (unique) => { + if (unique === this._memberTypeUnique) return; + this._memberTypeUnique = unique; + + if (this._memberTypeUnique) { + const memberType = (await this.#memberTypeItemRepository.requestItems([this._memberTypeUnique])).data?.[0]; + if (!memberType) return; + this._memberTypeName = memberType.name; + this._memberTypeIcon = memberType.icon; + } + }); this.observe(this.#workspaceContext?.createDate, (date) => (this._createDate = this.#setDateFormat(date))); this.observe(this.#workspaceContext?.updateDate, (date) => (this._updateDate = this.#setDateFormat(date))); this.observe(this.#workspaceContext?.unique, (unique) => (this._unique = unique || '')); this.observe(this.#workspaceContext?.kind, (kind) => (this._memberKind = kind)); - - const memberType = (await this.#memberTypeItemRepository.requestItems([this._memberTypeUnique])).data?.[0]; - if (!memberType) return; - this._memberTypeName = memberType.name; - this._memberTypeIcon = memberType.icon; }); createExtensionApiByAlias(this, UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS, [ 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 4d163bc58c..ab101f6c0e 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 @@ -10,6 +10,7 @@ import type { UUIBooleanInputEvent } from '@umbraco-cms/backoffice/external/uui' import './member-workspace-view-member-info.element.js'; import type { UmbInputMemberGroupElement } from '@umbraco-cms/backoffice/member-group'; import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user'; +import { umbBindToValidation } from '@umbraco-cms/backoffice/validation'; @customElement('umb-member-workspace-view-member') export class UmbMemberWorkspaceViewMemberElement extends UmbLitElement implements UmbWorkspaceViewElement { @@ -80,7 +81,7 @@ export class UmbMemberWorkspaceViewMemberElement extends UmbLitElement implement }; #renderPasswordInput() { - if (this._isNew) { + if (this._isNew && this._workspaceContext) { return html` this.#onPasswordUpdate()}> + @input=${() => this.#onPasswordUpdate()} + value=${this._workspaceContext.newPassword} + required + ${umbBindToValidation(this, '$.password', this._workspaceContext.newPassword)}> @@ -97,6 +101,7 @@ export class UmbMemberWorkspaceViewMemberElement extends UmbLitElement implement name="confirmPassword" label="Confirm password" type="password" + value=${this._workspaceContext.newPassword} @input=${() => this.#onPasswordUpdate()}> @@ -157,6 +162,7 @@ export class UmbMemberWorkspaceViewMemberElement extends UmbLitElement implement name="login" label=${this.localize.term('general_username')} value=${this._workspaceContext.username} + ${umbBindToValidation(this, '$.username', this._workspaceContext.username)} required required-message=${this.localize.term('user_loginnameRequired')} @input=${(e: Event) => this.#onChange('username', (e.target as HTMLInputElement).value)}> @@ -168,6 +174,7 @@ export class UmbMemberWorkspaceViewMemberElement extends UmbLitElement implement name="email" label=${this.localize.term('general_email')} value=${this._workspaceContext.email} + ${umbBindToValidation(this, '$.email', this._workspaceContext.email)} required required-message=${this.localize.term('user_emailRequired')} @input=${(e: Event) => this.#onChange('email', (e.target as HTMLInputElement).value)}> diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/sources/package.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/sources/package.server.data.ts index 2277694786..094b24326e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/sources/package.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/sources/package.server.data.ts @@ -8,7 +8,7 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; /** * Data source for packages from the server - + */ export class UmbPackageServerDataSource { constructor(private readonly _host: UmbControllerHost) {} From 28b90bcfea64d22daaa7e153426a6f1e08e96e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 29 Aug 2025 20:05:26 +0200 Subject: [PATCH 29/33] structure manager refactor implementation (#19970) * todos * navigation context * replace raw manifests with view context * Array State has method * rename to hint and much more * Notes for later * correcting one word * more notes * update JS Docs * update tests for getHasOne * fix context api usage * update code for v.16 * correct test * export UMB_WORKSPACE_VIEW_CONTEXT * minor corrections * rename to _hintMap * refactor part 1 * update version number in comment * clear method for array states * declare hint import map * mega refactor * final corrections for working POC * clean up path logic * implement scaffold * propagation and inheritance from view to workspace * separate types from classes * refactor to view context * rename editor navigation context to editor context * propagate removals * clean up notes * Hints for Content Tabs * use const path * handle gone parent * added comments on something to be looked at * hints context types * contentTypeMergedContainers * lint fixes * public contentTypeMergedContainers * refactor property structure helper class * a few notes for Presets * set variant ID instead of parsing it to the constructor * do not inject root to the path * adjust structure manager logic * UmbPropertyTypeContainerMergedModel type update * correct mergedContainersOfParentIdAndType * refactor to utilize new observable for better outcome and performance * fix lint errors * fix missing import * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/Umbraco.Web.UI.Client/src/packages/core/hint/context/hints.controller.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-validation-to-hints.manager.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/content-validation-to-hints.manager.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * clean up * remove console.log * declare new exports of core * Update src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor-tab.element.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * clean up * fix const export * remove root from hints path * also check for invariant * name more as legacy * fix eslint * fix container id setting * fix resetting inherited property * fix re-rendering problem --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> --- ...ace-view-edit-content-no-router.element.ts | 28 +-- .../block-workspace-view-edit-tab.element.ts | 12 +- .../edit/block-workspace-view-edit.element.ts | 8 +- ...t-type-container-structure-helper.class.ts | 144 ++++++++++--- ...nt-type-property-structure-helper.class.ts | 6 +- .../content-type-structure-manager.class.ts | 49 ++++- ...ontent-type-design-editor-group.element.ts | 78 ++++---- ...ent-type-design-editor-property.element.ts | 4 + .../content-type-design-editor-tab.element.ts | 189 ++++++++++-------- .../content-type-design-editor.element.ts | 90 +++++---- .../views/edit/content-editor-tab.element.ts | 10 +- .../views/edit/content-editor.element.ts | 8 +- .../core/utils/path/stored-path.function.ts | 2 +- .../workspace-editor.element.ts | 3 +- 14 files changed, 407 insertions(+), 224 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/views/edit/block-workspace-view-edit-content-no-router.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/views/edit/block-workspace-view-edit-content-no-router.element.ts index 06108fe2c6..c1fd3ba231 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/views/edit/block-workspace-view-edit-content-no-router.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/views/edit/block-workspace-view-edit-content-no-router.element.ts @@ -4,7 +4,7 @@ import { css, html, customElement, state, repeat, nothing } from '@umbraco-cms/b import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbContentTypeContainerStructureHelper } from '@umbraco-cms/backoffice/content-type'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import type { UmbPropertyTypeContainerModel } from '@umbraco-cms/backoffice/content-type'; +import type { UmbPropertyTypeContainerMergedModel } from '@umbraco-cms/backoffice/content-type'; import type { UmbWorkspaceViewElement } from '@umbraco-cms/backoffice/workspace'; /** @@ -20,10 +20,10 @@ export class UmbBlockWorkspaceViewEditContentNoRouterElement extends UmbLitEleme private _hasRootGroups = false; @state() - private _tabs?: Array; + private _tabs?: Array; @state() - private _activeTabId?: string | null | undefined; + private _activeTabKey?: string | null | undefined; //@state() //private _activeTabName?: string | null | undefined; @@ -36,7 +36,7 @@ export class UmbBlockWorkspaceViewEditContentNoRouterElement extends UmbLitEleme this.#tabsStructureHelper.setIsRoot(true); this.#tabsStructureHelper.setContainerChildType('Tab'); - this.observe(this.#tabsStructureHelper.mergedContainers, (tabs) => { + this.observe(this.#tabsStructureHelper.childContainers, (tabs) => { this._tabs = tabs; this.#checkDefaultTabName(); }); @@ -68,20 +68,20 @@ export class UmbBlockWorkspaceViewEditContentNoRouterElement extends UmbLitEleme if (!this._tabs || !this.#blockWorkspace) return; // Find the default tab to grab: - if (this._activeTabId === undefined) { + if (this._activeTabKey === undefined) { if (this._hasRootGroups) { //this._activeTabName = null; - this._activeTabId = null; + this._activeTabKey = null; } else if (this._tabs.length > 0) { //this._activeTabName = this._tabs[0].name; - this._activeTabId = this._tabs[0].id; + this._activeTabKey = this._tabs[0].key; } } } - #setTabName(tabName: string | undefined | null, tabId: string | null | undefined) { + #setTabName(tabName: string | undefined | null, tabKey: string | null | undefined) { //this._activeTabName = tabName; - this._activeTabId = tabId; + this._activeTabKey = tabKey; } override render() { @@ -93,7 +93,7 @@ export class UmbBlockWorkspaceViewEditContentNoRouterElement extends UmbLitEleme ? html` this.#setTabName(null, null)} >Content @@ -105,19 +105,19 @@ export class UmbBlockWorkspaceViewEditContentNoRouterElement extends UmbLitEleme (tab) => { return html` this.#setTabName(tab.name, tab.id)} + .active=${tab.key === this._activeTabKey} + @click=${() => this.#setTabName(tab.name, tab.key)} >${tab.name}`; }, )} ` : nothing} - ${this._activeTabId !== undefined + ${this._activeTabKey !== undefined ? html` + .containerId=${this._activeTabKey}> ` : nothing} `; diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/views/edit/block-workspace-view-edit-tab.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/views/edit/block-workspace-view-edit-tab.element.ts index 8bbd9cec4d..986598b50c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/views/edit/block-workspace-view-edit-tab.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/views/edit/block-workspace-view-edit-tab.element.ts @@ -1,7 +1,7 @@ import { UMB_BLOCK_WORKSPACE_CONTEXT } from '../../block-workspace.context-token.js'; import { css, html, customElement, property, state, repeat } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import type { UmbContentTypeModel, UmbPropertyTypeContainerModel } from '@umbraco-cms/backoffice/content-type'; +import type { UmbContentTypeModel, UmbPropertyTypeContainerMergedModel } from '@umbraco-cms/backoffice/content-type'; import { UmbContentTypeContainerStructureHelper } from '@umbraco-cms/backoffice/content-type'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -42,7 +42,7 @@ export class UmbBlockWorkspaceViewEditTabElement extends UmbLitElement { hideSingleGroup = false; @state() - private _groups: Array = []; + private _groups: Array = []; @state() private _hasProperties = false; @@ -60,7 +60,7 @@ export class UmbBlockWorkspaceViewEditTabElement extends UmbLitElement { if (!this.#blockWorkspace || !this.#managerName) return; this.#groupStructureHelper.setStructureManager(this.#blockWorkspace[this.#managerName].structure); this.observe( - this.#groupStructureHelper.mergedContainers, + this.#groupStructureHelper.childContainers, (groups) => { this._groups = groups; }, @@ -89,18 +89,18 @@ export class UmbBlockWorkspaceViewEditTabElement extends UmbLitElement { ? this.renderGroup(this._groups[0]) : repeat( this._groups, - (group) => group.id, + (group) => group.key, (group) => html` ${this.renderGroup(group)}`, )} `; } - renderGroup(group: UmbPropertyTypeContainerModel) { + renderGroup(group: UmbPropertyTypeContainerMergedModel) { return html` + .containerId=${group.ids[0]}> `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/views/edit/block-workspace-view-edit.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/views/edit/block-workspace-view-edit.element.ts index de633b326b..cd0ba81f9f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/views/edit/block-workspace-view-edit.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/views/edit/block-workspace-view-edit.element.ts @@ -3,7 +3,7 @@ import { UMB_BLOCK_WORKSPACE_CONTEXT } from '../../block-workspace.context-token import type { UmbBlockWorkspaceViewEditTabElement } from './block-workspace-view-edit-tab.element.js'; import { css, html, customElement, state, repeat, property } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import type { UmbContentTypeModel, UmbPropertyTypeContainerModel } from '@umbraco-cms/backoffice/content-type'; +import type { UmbContentTypeModel, UmbPropertyTypeContainerMergedModel } from '@umbraco-cms/backoffice/content-type'; import { UmbContentTypeContainerStructureHelper } from '@umbraco-cms/backoffice/content-type'; import type { UmbRoute, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router'; import { encodeFolderName } from '@umbraco-cms/backoffice/router'; @@ -34,7 +34,7 @@ export class UmbBlockWorkspaceViewEditElement extends UmbLitElement implements U private _routes: UmbRoute[] = []; @state() - private _tabs?: Array; + private _tabs?: Array; @state() private _routerPath?: string; @@ -48,7 +48,7 @@ export class UmbBlockWorkspaceViewEditElement extends UmbLitElement implements U this.#tabsStructureHelper.setIsRoot(true); this.#tabsStructureHelper.setContainerChildType('Tab'); this.observe( - this.#tabsStructureHelper.mergedContainers, + this.#tabsStructureHelper.childContainers, (tabs) => { this._tabs = tabs; this.#createRoutes(); @@ -102,7 +102,7 @@ export class UmbBlockWorkspaceViewEditElement extends UmbLitElement implements U component: () => import('./block-workspace-view-edit-tab.element.js'), setup: (component) => { (component as UmbBlockWorkspaceViewEditTabElement).managerName = this.#managerName; - (component as UmbBlockWorkspaceViewEditTabElement).containerId = tab.id; + (component as UmbBlockWorkspaceViewEditTabElement).containerId = tab.ids[0]; }, }); }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-container-structure-helper.class.ts b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-container-structure-helper.class.ts index 58afbe2cb0..9558578e39 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-container-structure-helper.class.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-container-structure-helper.class.ts @@ -1,8 +1,13 @@ -import type { UmbContentTypeModel, UmbPropertyContainerTypes, UmbPropertyTypeContainerModel } from '../types.js'; +import type { + UmbContentTypeModel, + UmbPropertyContainerTypes, + UmbPropertyTypeContainerMergedModel, + UmbPropertyTypeContainerModel, +} from '../types.js'; import type { UmbContentTypeStructureManager } from './content-type-structure-manager.class.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbController, UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbArrayState, UmbBooleanState } from '@umbraco-cms/backoffice/observable-api'; /** * This class is a helper class for managing the structure of containers in a content type. @@ -11,6 +16,7 @@ import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api'; export class UmbContentTypeContainerStructureHelper extends UmbControllerBase { #init; #initResolver?: (value: unknown) => void; + #initRejector?: () => void; #containerId?: string | null; #childType?: UmbPropertyContainerTypes = 'Group'; @@ -21,31 +27,55 @@ export class UmbContentTypeContainerStructureHelper([], (x) => x.id); - readonly containers = this.#childContainers.asObservable(); + get containers() { + this.#startLegacy(); + return this.#childContainers.asObservable(); + } // State containing the merged containers (only one pr. name): - #mergedChildContainers = new UmbArrayState([], (x) => x.id); - readonly mergedContainers = this.#mergedChildContainers.asObservable(); + #legacyMergedChildContainers = new UmbArrayState([], (x) => x.id); + get mergedContainers() { + this.#startLegacy(); + return this.#legacyMergedChildContainers.asObservable(); + } + + #childContainersMerged = new UmbArrayState([], (x) => x.path); + public readonly childContainers = this.#childContainersMerged.asObservable(); // Owner containers are containers owned by the owner Content Type (The specific one up for editing) #ownerChildContainers: UmbPropertyTypeContainerModel[] = []; - #hasProperties = new UmbArrayState<{ id: string | null; has: boolean }>([], (x) => x.id); - readonly hasProperties = this.#hasProperties.asObservablePart((x) => x.some((y) => y.has)); + #hasProperties = new UmbBooleanState(false); + readonly hasProperties = this.#hasProperties.asObservable(); constructor(host: UmbControllerHost) { super(host); - this.#init = new Promise((resolve) => { + this.#init = new Promise((resolve, reject) => { this.#initResolver = resolve; + this.#initRejector = reject; }); - this.#mergedChildContainers.sortBy((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0)); - this.observe(this.containers, this.#performContainerMerge, null); + this.#legacyMergedChildContainers.sortBy((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0)); + } + + // TODO: Implement UmbDeprecated and Obsolete this from v.17 [NL] + #legacyMergeLogic = false; + #startLegacy() { + if (this.#legacyMergeLogic) return; + console.log( + "Pst. we will be deprecating 'mergedContainers' and 'containers' in v.17.0, feel free to use them until v.18.0. But please use 'childContainers'", + ); + this.#legacyMergeLogic = true; + this.#legacyObserveContainers(); + this.observe(this.containers, this.#legacyPerformContainerMerge, null); } public setStructureManager(structure: UmbContentTypeStructureManager | undefined) { if (this.#structure === structure || !structure) return; if (this.#structure && !structure) { + this.#initRejector?.(); + this.#initResolver = undefined; + this.#initRejector = undefined; throw new Error( 'Structure manager is already set, the helpers are not designed to be re-setup with new managers', ); @@ -53,7 +83,9 @@ export class UmbContentTypeContainerStructureHelper { + this.#childContainersMerged.setValue(childContainers ?? []); + }, + 'observeChildContainers', + ); + + if (this.#containerId === null) { + this.removeUmbControllerByAlias('observeParentContainer'); + // Observe root properties: + this.observe( + this.#structure?.hasPropertyStructuresOfRoot(), + (has) => { + this.#hasProperties.setValue(has ?? false); + }, + 'observeProperties', + ); + } else { + // Observe properties of the parent container and matching containers (therefor getting the merged container of the parent id): [NL] + const parentObservable = + this.#containerId !== undefined && this.#childType + ? this.#structure?.mergedContainersOfId(this.#containerId) + : undefined; + + this.observe( + parentObservable, + (parentContainer) => { + this.observe( + parentContainer ? this.#structure?.hasPropertyStructuresOfGroupIds(parentContainer.ids ?? []) : undefined, + (has) => { + this.#hasProperties.setValue(has ?? false); + }, + 'observeProperties', + ); + }, + 'observeParentContainer', + ); + } + } + + // LEGACY properties: #containerName?: string; #containerType?: UmbPropertyContainerTypes; #parentName?: string | null; #parentType?: UmbPropertyContainerTypes; - #observeContainers() { + // LEGACY method: + #legacyObserveContainers() { + if (!this.#legacyMergeLogic) return; if (!this.#structure || this.#containerId === undefined) return; if (this.#containerId === null) { - this.#observeHasPropertiesOf(null); - this.#observeRootContainers(); + //this.#observeHasPropertiesOf(null); + this.#legacyObserveRootContainers(); this.removeUmbControllerByAlias('_observeContainers'); } else { this.observe( @@ -133,8 +218,7 @@ export class UmbContentTypeContainerStructureHelper { - this.#hasProperties.setValue([]); + //this.#hasProperties.setValue([]); this.#childContainers.setValue([]); this.#containerObservers.forEach((x) => x.destroy()); this.#containerObservers = []; containers.forEach((container) => { - this.#observeHasPropertiesOf(container.id); + //this.#observeHasPropertiesOf(container.id); this.#containerObservers.push( this.observe( @@ -184,7 +269,8 @@ export class UmbContentTypeContainerStructureHelper) { + // LEGACY method: + #legacyFilterNonOwnerContainers(containers: Array) { return this.#ownerChildContainers.length > 0 ? containers.filter( (anyCon) => @@ -226,22 +315,23 @@ export class UmbContentTypeContainerStructureHelper) => { + // LEGACY method: + #legacyPerformContainerMerge = (containers: Array) => { // Remove containers that matches with a owner container: - let merged = this.#filterNonOwnerContainers(containers); + let merged = this.#legacyFilterNonOwnerContainers(containers); // Remove containers of same name and type: // This only works cause we are dealing with a single level of containers in this Helper, if we had more levels we would need to be more clever about the parent as well. [NL] merged = merged.filter((x, i, cons) => i === cons.findIndex((y) => y.name === x.name && y.type === x.type)); - this.#mergedChildContainers.setValue(merged); + this.#legacyMergedChildContainers.setValue(merged); }; /** * Returns true if the container is an owner container. * @param containerId */ - isOwnerChildContainer(containerId?: string) { + isOwnerChildContainer(containerId?: string): boolean | undefined { if (!this.#structure || !containerId) return; - return this.#ownerChildContainers.some((x) => x.id === containerId); + return this.#structure.isOwnerContainer(containerId); } getContentTypeOfContainer(containerId?: string) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-property-structure-helper.class.ts b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-property-structure-helper.class.ts index 10237041bf..be18514559 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-property-structure-helper.class.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-property-structure-helper.class.ts @@ -47,7 +47,7 @@ export class UmbContentTypePropertyStructureHelper { diff --git a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-structure-manager.class.ts b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-structure-manager.class.ts index ffb224e144..6d97aaef57 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-structure-manager.class.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/structure/content-type-structure-manager.class.ts @@ -497,19 +497,38 @@ export class UmbContentTypeStructureManager< makeEmptyContainerName( containerId: string, - containerType: UmbPropertyContainerTypes, - parentId: string | null = null, + legacyContainerType?: UmbPropertyContainerTypes, + legacyParentId?: string | null, ): string { return ( - this.makeContainerNameUniqueForOwnerContentType(containerId, 'Unnamed', containerType, parentId) ?? 'Unnamed' + this.makeContainerNameUniqueForOwnerContentType(containerId, 'Unnamed', legacyContainerType, legacyParentId) ?? + 'Unnamed' ); } + /** + * + * @param {string} containerId - The id of the container to make unique + * @param {string} newName - The new name to make unique + * @param {never} _legacyContainerType - do not use, has no effect. Is deprecated and will be removed in v.17 + * @param {never} _legacyParentId - do not use, has no effect. Is deprecated and will be removed in v.17 + * @returns + */ makeContainerNameUniqueForOwnerContentType( containerId: string, newName: string, - containerType: UmbPropertyContainerTypes, - parentId: string | null = null, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _legacyContainerType?: UmbPropertyContainerTypes, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _legacyParentId?: string | null, ) { + const container = this.getOwnerContainerById(containerId); + if (!container) { + console.warn(`Container with id ${containerId} not found in owner content type.`); + return null; + } + const containerType = container.type; + const parentId = container.parent?.id ?? null; + const ownerRootContainers = this.getOwnerContainers(containerType, parentId); //getRootContainers() can't differentiates between compositions and locals if (!ownerRootContainers) { return null; @@ -749,6 +768,26 @@ export class UmbContentTypeStructureManager< }); } + hasPropertyStructuresOfGroupIds(groupIds: Array) { + return this.#contentTypes.asObservablePart((docTypes) => { + return docTypes.some((docType) => { + return docType.properties?.some((property) => { + return property.container?.id && groupIds.includes(property.container.id); + }); + }); + }); + } + + hasPropertyStructuresOfRoot() { + return this.#contentTypes.asObservablePart((docTypes) => { + return docTypes.some((docType) => { + return docType.properties?.some((property) => { + return !property.container; + }); + }); + }); + } + rootContainers(containerType: UmbPropertyContainerTypes) { return createObservablePart(this.#contentTypeContainers, (data) => { return data.filter((x) => x.parent === null && x.type === containerType); diff --git a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor-group.element.ts b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor-group.element.ts index 2745074f62..68f83dac68 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor-group.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor-group.element.ts @@ -1,4 +1,4 @@ -import type { UmbContentTypeModel, UmbPropertyTypeContainerModel } from '../../../types.js'; +import type { UmbContentTypeModel, UmbPropertyTypeContainerMergedModel } from '../../../types.js'; import type { UmbContentTypeContainerStructureHelper } from '../../../structure/index.js'; import { css, customElement, html, nothing, property, repeat, state, when } from '@umbraco-cms/backoffice/external/lit'; import { umbConfirmModal } from '@umbraco-cms/backoffice/modal'; @@ -11,16 +11,16 @@ import './content-type-design-editor-properties.element.js'; @customElement('umb-content-type-design-editor-group') export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement { @property({ attribute: false }) - public set group(value: UmbPropertyTypeContainerModel | undefined) { + public set group(value: UmbPropertyTypeContainerMergedModel | undefined) { if (value === this._group) return; this._group = value; - this._groupId = value?.id; + this._groupId = value?.ownerId ?? value?.ids[0]; this.#checkInherited(); } - public get group(): UmbPropertyTypeContainerModel | undefined { + public get group(): UmbPropertyTypeContainerMergedModel | undefined { return this._group; } - private _group?: UmbPropertyTypeContainerModel | undefined; + private _group?: UmbPropertyTypeContainerMergedModel | undefined; @property({ attribute: false }) public set groupStructureHelper(value: UmbContentTypeContainerStructureHelper | undefined) { @@ -45,7 +45,8 @@ export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement { @state() private _hasOwnerContainer?: boolean; - @state() + // attrbute is used by Sorter Controller in parent scope. + @property({ type: Boolean, reflect: true, attribute: 'inherited' }) private _inherited?: boolean; @state() @@ -54,48 +55,46 @@ export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement { #checkInherited() { if (this.groupStructureHelper && this.group) { // Check is this container matches with any other group. If so it is inherited aka. merged with others. [NL] - if (this.group.name) { - // We can first match with something if we have a name [NL] - this.observe( - this.groupStructureHelper.containersByNameAndType(this.group.name, 'Group'), - (containers) => { - const ownerContainer = containers.find((con) => this.groupStructureHelper!.isOwnerChildContainer(con.id)); - const hasAOwnerContainer = !!ownerContainer; - const pureOwnerContainer = hasAOwnerContainer && containers.length === 1; - - this._hasOwnerContainer = hasAOwnerContainer; - this._inherited = !pureOwnerContainer; - this._inheritedFrom = containers - .filter((con) => con.id !== ownerContainer?.id) - .map((con) => this.groupStructureHelper!.getContentTypeOfContainer(con.id)) - .filter((contentType) => contentType !== undefined) as Array; - }, - 'observeGroupContainers', - ); - } else { - // We use name match to determine inheritance, so no name cannot inherit. - this._inherited = false; + if (this.group.ownerId) { this._hasOwnerContainer = true; - this.removeUmbControllerByAlias('observeGroupContainers'); + } + + const notOwnerContainerIds = this.group.ids.filter((id) => id !== this.group!.ownerId); + + if (notOwnerContainerIds.length > 0) { + this._inheritedFrom = notOwnerContainerIds + .map((id) => this.groupStructureHelper!.getContentTypeOfContainer(id)) + .filter((contentType) => contentType !== undefined) as Array; + this._inherited = true; + } else { + this._inheritedFrom = undefined; + this._inherited = false; } } } #singleValueUpdate(propertyName: string, value: string | number | boolean | null | undefined) { - if (!this._groupStructureHelper || !this.group) return; + if (!this._groupStructureHelper || !this._group) return; + + const ownerId = this._group.ownerId; + if (!ownerId) return; const partialObject = {} as any; partialObject[propertyName] = value; - this._groupStructureHelper.partialUpdateContainer(this.group.id, partialObject); + this._groupStructureHelper.partialUpdateContainer(ownerId, partialObject); } #renameGroup(e: InputEvent) { if (!this.groupStructureHelper || !this._group) return; + const ownerId = this._group.ownerId; + if (!ownerId) return; let newName = (e.target as HTMLInputElement).value; + // TODO: This does not seem right, the detection of a unique name requires better awareness on the level of the change. [NL] + // This seem to use check for root containers. const changedName = this.groupStructureHelper .getStructureManager()! - .makeContainerNameUniqueForOwnerContentType(this._group.id, newName, 'Group', this._group.parent?.id ?? null); + .makeContainerNameUniqueForOwnerContentType(ownerId, newName); if (changedName) { newName = changedName; } @@ -105,11 +104,11 @@ export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement { #blurGroup(e: InputEvent) { if (!this.groupStructureHelper || !this._group) return; + const ownerId = this._group.ownerId; + if (!ownerId) return; const newName = (e.target as HTMLInputElement).value; if (newName === '') { - const changedName = this.groupStructureHelper - .getStructureManager()! - .makeEmptyContainerName(this._group.id, 'Group', this._group.parent?.id ?? null); + const changedName = this.groupStructureHelper.getStructureManager()!.makeEmptyContainerName(ownerId); this.#singleValueUpdate('name', changedName); (e.target as HTMLInputElement).value = changedName; } @@ -119,21 +118,22 @@ export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement { e.preventDefault(); e.stopImmediatePropagation(); if (!this.groupStructureHelper || !this._group) return; + if (this._group.ownerId === undefined) return; // TODO: Do proper localization here: [NL] await umbConfirmModal(this, { headline: `${this.localize.term('actions_delete')} group`, content: html` - Are you sure you want to delete the group ${this._group.name ?? this._group.id} + Are you sure you want to delete the group ${this._group.name ?? this._group.ownerId}
`, confirmLabel: this.localize.term('actions_delete'), color: 'danger', }); - this.groupStructureHelper.removeContainer(this._group.id); + this.groupStructureHelper.removeContainer(this._group.ownerId); } override render() { @@ -277,6 +277,10 @@ export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement { padding: var(--uui-size-space-4) var(--uui-size-space-5); } + :host([inherited]) div[slot='header'] { + cursor: default; + } + div[slot='header'] > div { display: flex; align-items: center; diff --git a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor-property.element.ts b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor-property.element.ts index 49adf60673..75b3f5b8c8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor-property.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor-property.element.ts @@ -456,6 +456,10 @@ export class UmbContentTypeDesignEditorPropertyElement extends UmbLitElement { height: min-content; } + #header i { + opacity: 0.55; + } + #editor { position: relative; --uui-button-background-color: var(--uui-color-background); diff --git a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor-tab.element.ts b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor-tab.element.ts index 051f6caffc..34e8ddf56c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor-tab.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor-tab.element.ts @@ -1,5 +1,9 @@ import { UMB_CONTENT_TYPE_WORKSPACE_CONTEXT } from '../../content-type-workspace.context-token.js'; -import type { UmbContentTypeModel, UmbPropertyTypeContainerModel } from '../../../types.js'; +import type { + UmbContentTypeModel, + UmbPropertyTypeContainerMergedModel, + UmbPropertyTypeContainerModel, +} from '../../../types.js'; import { UmbContentTypeContainerStructureHelper } from '../../../structure/index.js'; import { UMB_CONTENT_TYPE_DESIGN_EDITOR_CONTEXT } from './content-type-design-editor.context-token.js'; import type { UmbContentTypeWorkspaceViewEditGroupElement } from './content-type-design-editor-group.element.js'; @@ -13,95 +17,122 @@ import type { UmbSorterConfig } from '@umbraco-cms/backoffice/sorter'; import './content-type-design-editor-properties.element.js'; import './content-type-design-editor-group.element.js'; -const SORTER_CONFIG: UmbSorterConfig = { - getUniqueOfElement: (element) => element.group?.id, - getUniqueOfModel: (modelEntry) => modelEntry.id, - // TODO: Make specific to the current owner document. [NL] - identifier: 'content-type-container-sorter', - itemSelector: 'umb-content-type-design-editor-group', - handleSelector: '.drag-handle', - containerSelector: '.container-list', -}; +const SORTER_CONFIG: UmbSorterConfig = + { + getUniqueOfElement: (element) => element.group?.key, + getUniqueOfModel: (modelEntry) => modelEntry.key, + // TODO: Make specific to the current owner document. [NL] + identifier: 'content-type-container-sorter', + itemSelector: 'umb-content-type-design-editor-group', + handleSelector: '.drag-handle', + disabledItemSelector: '[inherited]', // Inherited attribute is set by the umb-content-type-design-editor-group. + containerSelector: '.container-list', + }; @customElement('umb-content-type-design-editor-tab') export class UmbContentTypeDesignEditorTabElement extends UmbLitElement { - #sorter = new UmbSorterController(this, { - ...SORTER_CONFIG, - onChange: ({ model }) => { - this._groups = model; - }, - onEnd: ({ item }) => { - /*if (this._inherited === undefined) { + #sorter = new UmbSorterController( + this, + { + ...SORTER_CONFIG, + onChange: ({ model }) => { + this._groups = model; + }, + onEnd: ({ item }) => { + /*if (this._inherited === undefined) { throw new Error('OwnerTabId is not set, we have not made a local duplicated of this container.'); return; }*/ - /** - * Explanation: If the item is the first in list, we compare it to the item behind it to set a sortOrder. - * If it's not the first in list, we will compare to the item in before it, and check the following item to see if it caused overlapping sortOrder, then update - * the overlap if true, which may cause another overlap, so we loop through them till no more overlaps... - */ - const model = this._groups; - const newIndex = model.findIndex((entry) => entry.id === item.id); + /** + * Explanation: If the item is the first in list, we compare it to the item behind it to set a sortOrder. + * If it's not the first in list, we will compare to the item in before it, and check the following item to see if it caused overlapping sortOrder, then update + * the overlap if true, which may cause another overlap, so we loop through them till no more overlaps... + */ + const model = this._groups; + const newIndex = model.findIndex((entry) => entry.key === item.key); - // Doesn't exist in model - if (newIndex === -1) return; + // Doesn't exist in model + if (newIndex === -1) return; - // As origin we set prev sort order to -1, so if no other then our item will become 0 - let prevSortOrder = -1; + // As origin we set prev sort order to -1, so if no other then our item will become 0 + let prevSortOrder = -1; - // Not first in list - if (newIndex > 0 && model.length > 0) { - prevSortOrder = model[newIndex - 1].sortOrder; - } + // Not first in list + if (newIndex > 0 && model.length > 0) { + prevSortOrder = model[newIndex - 1].sortOrder; + } - // increase the prevSortOrder and use it for the moved item, - this.#groupStructureHelper.partialUpdateContainer(item.id, { - sortOrder: ++prevSortOrder, - }); + const ownerId = item.ownerId; - // Adjust everyone right after, meaning until there is a gap between the sortOrders: - let i = newIndex + 1; - let entry: UmbPropertyTypeContainerModel | undefined; - // As long as there is an item with the index & the sortOrder is less or equal to the prevSortOrder, we will update the sortOrder: - while ((entry = model[i]) !== undefined && entry.sortOrder <= prevSortOrder) { - // Increase the prevSortOrder and use it for the item: - this.#groupStructureHelper.partialUpdateContainer(entry.id, { + if (ownerId === undefined) { + // This may be possible later, but for now this is not possible. [NL] + throw new Error( + 'OwnerId is not set for the given container, we cannot move containers that are not owned by the current Document.', + ); + } + + // increase the prevSortOrder and use it for the moved item, + this.#groupStructureHelper.partialUpdateContainer(ownerId, { sortOrder: ++prevSortOrder, }); - i++; - } + // Adjust everyone right after, meaning until there is a gap between the sortOrders: + let i = newIndex + 1; + let entry: UmbPropertyTypeContainerMergedModel | undefined; + // As long as there is an item with the index & the sortOrder is less or equal to the prevSortOrder, we will update the sortOrder: + while ((entry = model[i]) !== undefined && entry.sortOrder <= prevSortOrder) { + // Only updated owned containers: + if (entry.ownerId) { + // Increase the prevSortOrder and use it for the item: + this.#groupStructureHelper.partialUpdateContainer(entry.ownerId, { + sortOrder: ++prevSortOrder, + }); + + i++; + } + } + }, + onRequestDrop: async ({ unique }) => { + const context = await this.getContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT); + if (!context) { + throw new Error('Could not get Workspace Context'); + } + return context.structure.getMergedContainerById(unique) as UmbPropertyTypeContainerMergedModel | undefined; + }, + requestExternalRemove: async ({ item }) => { + const context = await this.getContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT); + if (!context) { + throw new Error('Could not get Workspace Context'); + } + return await context.structure.removeContainer(null, item.ownerId, { preventRemovingProperties: true }).then( + () => true, + () => false, + ); + }, + requestExternalInsert: async ({ item }) => { + const context = await this.getContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT); + if (!context) { + throw new Error('Could not get Workspace Context'); + } + if (item.ownerId === undefined) { + // This may be possible later, but for now this is not possible. [NL] + throw new Error('OwnerId is not set, we cannot move containers that are not owned by the current Document.'); + } + const parent = this.#containerId ? { id: this.#containerId } : null; + const containerModelItem: UmbPropertyTypeContainerModel = { + id: item.ownerId, + name: item.name, + sortOrder: item.sortOrder, + type: item.type, + parent, + }; + return await context.structure.insertContainer(null, containerModelItem).then( + () => true, + () => false, + ); + }, }, - onRequestDrop: async ({ unique }) => { - const context = await this.getContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT); - if (!context) { - throw new Error('Could not get Workspace Context'); - } - return context.structure.getOwnerContainerById(unique); - }, - requestExternalRemove: async ({ item }) => { - const context = await this.getContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT); - if (!context) { - throw new Error('Could not get Workspace Context'); - } - return await context.structure.removeContainer(null, item.id, { preventRemovingProperties: true }).then( - () => true, - () => false, - ); - }, - requestExternalInsert: async ({ item }) => { - const context = await this.getContext(UMB_CONTENT_TYPE_WORKSPACE_CONTEXT); - if (!context) { - throw new Error('Could not get Workspace Context'); - } - const parent = this.#containerId ? { id: this.#containerId } : null; - const updatedItem = { ...item, parent }; - return await context.structure.insertContainer(null, updatedItem).then( - () => true, - () => false, - ); - }, - }); + ); #workspaceModal?: UmbModalRouteRegistrationController< typeof UMB_WORKSPACE_MODAL.DATA, @@ -122,7 +153,7 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement { } @state() - private _groups: Array = []; + private _groups: Array = []; @state() private _hasProperties = false; @@ -170,7 +201,7 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement { }); this.observe( - this.#groupStructureHelper.mergedContainers, + this.#groupStructureHelper.childContainers, (groups) => { this._groups = groups; this.#sorter.setModel(this._groups); @@ -212,14 +243,14 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement {
${repeat( this._groups, - (group) => group.id, + (group) => group.ids[0], (group) => html` `, diff --git a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor.element.ts index d37eef19a0..9f632ab6fc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/content/content-type/workspace/views/design/content-type-design-editor.element.ts @@ -2,7 +2,7 @@ import { UMB_CONTENT_TYPE_WORKSPACE_CONTEXT } from '../../content-type-workspace import type { UmbContentTypeCompositionModel, UmbContentTypeModel, - UmbPropertyTypeContainerModel, + UmbPropertyTypeContainerMergedModel, } from '../../../types.js'; import { UmbContentTypeContainerStructureHelper, @@ -33,9 +33,9 @@ import { UmbSorterController } from '@umbraco-cms/backoffice/sorter'; @customElement('umb-content-type-design-editor') export class UmbContentTypeDesignEditorElement extends UmbLitElement implements UmbWorkspaceViewElement { - #sorter = new UmbSorterController(this, { - getUniqueOfElement: (element) => element.getAttribute('data-umb-tab-id'), - getUniqueOfModel: (tab) => tab.id, + #sorter = new UmbSorterController(this, { + getUniqueOfElement: (element) => element.getAttribute('data-umb-tab-key'), + getUniqueOfModel: (tab) => tab.key, identifier: 'content-type-tabs-sorter', itemSelector: 'uui-tab', containerSelector: 'uui-tab-group', @@ -51,7 +51,7 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements * the overlap if true, which may cause another overlap, so we loop through them till no more overlaps... */ const model = this._tabs ?? []; - const newIndex = model.findIndex((entry) => entry.id === item.id); + const newIndex = model.findIndex((entry) => entry.key === item.key); // Doesn't exist in model if (newIndex === -1) return; @@ -64,20 +64,32 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements prevSortOrder = model[newIndex - 1].sortOrder; } + const ownerId = item.ownerId; + + if (ownerId === undefined) { + // This may be possible later, but for now this is not possible. [NL] + throw new Error( + 'OwnerId is not set for the given container, we cannot move containers that are not owned by the current Document.', + ); + } + // increase the prevSortOrder and use it for the moved item, - this.#tabsStructureHelper.partialUpdateContainer(item.id, { + this.#tabsStructureHelper.partialUpdateContainer(ownerId, { sortOrder: ++prevSortOrder, }); // Adjust everyone right after, until there is a gap between the sortOrders: [NL] let i = newIndex + 1; - let entry: UmbPropertyTypeContainerModel | undefined; + let entry: UmbPropertyTypeContainerMergedModel | undefined; // As long as there is an item with the index & the sortOrder is less or equal to the prevSortOrder, we will update the sortOrder: while ((entry = model[i]) !== undefined && entry.sortOrder <= prevSortOrder) { - // Increase the prevSortOrder and use it for the item: - this.#tabsStructureHelper.partialUpdateContainer(entry.id, { - sortOrder: ++prevSortOrder, - }); + // Only updated owned containers: + if (entry.ownerId) { + // Increase the prevSortOrder and use it for the item: + this.#tabsStructureHelper.partialUpdateContainer(entry.ownerId, { + sortOrder: ++prevSortOrder, + }); + } i++; } @@ -105,7 +117,7 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements private _routes: UmbRoute[] = []; @state() - private _tabs?: Array; + private _tabs?: Array; @state() private _routerPath?: string; @@ -136,7 +148,7 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements this.#tabsStructureHelper.setContainerChildType('Tab'); this.#tabsStructureHelper.setIsRoot(true); - this.observe(this.#tabsStructureHelper.mergedContainers, (tabs) => { + this.observe(this.#tabsStructureHelper.childContainers, (tabs) => { this._tabs = tabs; this.#sorter.setModel(tabs); this.#createRoutes(); @@ -180,7 +192,7 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements if (this._tabs.length > 0) { this._tabs?.forEach((tab) => { const tabName = tab.name && tab.name !== '' ? tab.name : '-'; - if (tab.id === this.#processingTabId) { + if (tab.ownerId && tab.ownerId === this.#processingTabId) { activeTabName = tabName; } routes.push({ @@ -188,7 +200,7 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements component: () => import('./content-type-design-editor-tab.element.js'), setup: (component) => { this.#currentTabComponent = component as UmbContentTypeDesignEditorTabElement; - this.#currentTabComponent.containerId = tab.id; + this.#currentTabComponent.containerId = tab.ownerId ?? tab.ids[0]; }, }); }); @@ -265,8 +277,8 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements } } - async #requestDeleteTab(tab: UmbPropertyTypeContainerModel | undefined) { - if (!tab) return; + async #requestDeleteTab(tab: UmbPropertyTypeContainerMergedModel | undefined) { + if (!tab || !tab.ownerId) return; // TODO: Localize this: const tabName = tab.name === '' ? 'Unnamed' : tab.name; // TODO: Localize this: @@ -288,10 +300,9 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements await umbConfirmModal(this, modalData); - this.#deleteTab(tab?.id); + this.#deleteTab(tab.ownerId); } - #deleteTab(tabId?: string) { - if (!tabId) return; + #deleteTab(tabId: string) { this.#workspaceContext?.structure.removeContainer(null, tabId); if (this.#processingTabId === tabId) { this.#processingTabId = undefined; @@ -332,12 +343,13 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements }, 100); } - async #tabNameChanged(event: InputEvent, tab: UmbPropertyTypeContainerModel) { - this.#processingTabId = tab.id; + async #tabNameChanged(event: InputEvent, tab: UmbPropertyTypeContainerMergedModel) { + if (!this.#workspaceContext || !tab.ownerId) return; + this.#processingTabId = tab.ownerId; let newName = (event.target as HTMLInputElement).value; - const changedName = this.#workspaceContext?.structure.makeContainerNameUniqueForOwnerContentType( - tab.id, + const changedName = this.#workspaceContext.structure.makeContainerNameUniqueForOwnerContentType( + tab.ownerId, newName, 'Tab', ); @@ -349,20 +361,20 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements (event.target as HTMLInputElement).value = newName; } - this.#tabsStructureHelper.partialUpdateContainer(tab.id!, { + this.#tabsStructureHelper.partialUpdateContainer(tab.ownerId, { name: newName, }); } - async #tabNameBlur(event: FocusEvent, tab: UmbPropertyTypeContainerModel) { - if (!this.#processingTabId) return; + async #tabNameBlur(event: FocusEvent, tab: UmbPropertyTypeContainerMergedModel) { + if (!this.#processingTabId || !tab.ownerId) return; const newName = (event.target as HTMLInputElement | undefined)?.value; if (newName === '') { const changedName = this.#workspaceContext!.structure.makeEmptyContainerName(this.#processingTabId, 'Tab'); (event.target as HTMLInputElement).value = changedName; - this.#tabsStructureHelper.partialUpdateContainer(tab.id!, { + this.#tabsStructureHelper.partialUpdateContainer(tab.ownerId, { name: changedName, }); } @@ -506,7 +518,7 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements ${this.renderRootTab()} ${repeat( this._tabs, - (tab) => tab.id, + (tab) => tab.ownerId ?? tab.ids[0], (tab) => this.renderTab(tab), )} @@ -535,16 +547,17 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements `; } - renderTab(tab: UmbPropertyTypeContainerModel) { + renderTab(tab: UmbPropertyTypeContainerMergedModel) { const path = this._routerPath + '/tab/' + encodeFolderName(tab.name && tab.name !== '' ? tab.name : '-'); const tabActive = path === this._activePath; - const ownedTab = this.#tabsStructureHelper.isOwnerChildContainer(tab.id!) ?? false; + const ownedTab = tab.ownerId ? true : false; return html` this.#onDragOver(event, path)}> @@ -552,14 +565,15 @@ export class UmbContentTypeDesignEditorElement extends UmbLitElement implements `; } - renderTabInner(tab: UmbPropertyTypeContainerModel, tabActive: boolean, ownedTab: boolean) { + renderTabInner(tab: UmbPropertyTypeContainerMergedModel, tabActive: boolean, ownedTab: boolean) { // TODO: Localize this: const hasTabName = tab.name && tab.name !== ''; const tabName = hasTabName ? tab.name : 'Unnamed'; + const tabId = tab.ownerId ?? tab.ids[0]; if (this._sortModeActive) { return html`
${ownedTab - ? html` ${tabName} + ? html` ${tabName} (this); @state() - private _groups: Array = []; + private _groups: Array = []; @state() private _hasProperties = false; @@ -42,7 +42,7 @@ export class UmbContentWorkspaceViewEditTabElement extends UmbLitElement { workspaceContext?.structure as unknown as UmbContentTypeStructureManager, ); }); - this.observe(this.#groupStructureHelper.mergedContainers, (groups) => { + this.observe(this.#groupStructureHelper.childContainers, (groups) => { this._groups = groups; }); this.observe(this.#groupStructureHelper.hasProperties, (hasProperties) => { @@ -63,12 +63,12 @@ export class UmbContentWorkspaceViewEditTabElement extends UmbLitElement { : ''} ${repeat( this._groups, - (group) => group.id, + (group) => group.key, (group) => html` + .containerId=${group.ids[0]}> `, )} `; diff --git a/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/views/edit/content-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/views/edit/content-editor.element.ts index dce11b6601..f5b9941d44 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/views/edit/content-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/content/content/workspace/views/edit/content-editor.element.ts @@ -4,7 +4,7 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import type { UmbContentTypeModel, UmbContentTypeStructureManager, - UmbPropertyTypeContainerModel, + UmbPropertyTypeContainerMergedModel, } from '@umbraco-cms/backoffice/content-type'; import { UmbContentTypeContainerStructureHelper, @@ -34,7 +34,7 @@ export class UmbContentWorkspaceViewEditElement extends UmbLitElement implements private _routes: UmbRoute[] = []; @state() - private _tabs?: Array; + private _tabs?: Array; @state() private _routerPath?: string; @@ -64,7 +64,7 @@ export class UmbContentWorkspaceViewEditElement extends UmbLitElement implements this._tabsStructureHelper.setIsRoot(true); this._tabsStructureHelper.setContainerChildType('Tab'); this.observe( - this._tabsStructureHelper.mergedContainers, + this._tabsStructureHelper.childContainers, (tabs) => { this._tabs = tabs; this.#createRoutes(); @@ -117,7 +117,7 @@ export class UmbContentWorkspaceViewEditElement extends UmbLitElement implements path, component: () => import('./content-editor-tab.element.js'), setup: (component) => { - (component as UmbContentWorkspaceViewEditTabElement).containerId = tab.id; + (component as UmbContentWorkspaceViewEditTabElement).containerId = tab.ownerId ?? tab.ids[0]; }, }); this.#createViewContext(path); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/stored-path.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/stored-path.function.ts index e143ee3920..6f485bf991 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/stored-path.function.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/stored-path.function.ts @@ -35,7 +35,7 @@ export function setStoredPath(path: string): void { * Redirect the user to the stored path or the base path if not available. * If the basePath matches the start of the stored path, the browser will replace the state instead of redirecting. * @param {string} basePath - The base path to redirect to if no stored path is available. - * @param {boolean} [force] - If true, will redirect using Location + * @param {boolean} force - If true, will redirect using Location */ export function redirectToStoredPath(basePath: string, force = false): void { const url = retrieveStoredPath(); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts index da8ecccf87..72276e6ac8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts @@ -213,8 +213,9 @@ export class UmbWorkspaceEditorElement extends UmbLitElement { } #renderRoutes() { - if (!this._routes || this._routes.length === 0 || !this._workspaceViews || this._workspaceViews.length === 0) + if (!this._routes || this._routes.length === 0 || !this._workspaceViews || this._workspaceViews.length === 0) { return nothing; + } return html` Date: Mon, 1 Sep 2025 09:32:07 +0200 Subject: [PATCH 30/33] V16: Moves icon dependencies to 'core' package.json (#20041) * build(deps-dev): moves icon dependencies to 'core' package + upgrades them to latest * chore: regenerates icons * chore(eslint): fixes eslint warnings --- .../devops/icons/index.js | 19 +- src/Umbraco.Web.UI.Client/package-lock.json | 141 +- src/Umbraco.Web.UI.Client/package.json | 3 - .../src/packages/core/icon-registry/icons.ts | 5814 ++++++++--------- .../core/icon-registry/icons/icon-azure.ts | 2 +- .../core/icon-registry/icons/icon-facebook.ts | 2 +- .../core/icon-registry/icons/icon-gitbook.ts | 2 +- .../core/icon-registry/icons/icon-github.ts | 2 +- .../core/icon-registry/icons/icon-gitlab.ts | 2 +- .../core/icon-registry/icons/icon-google.ts | 2 +- .../core/icon-registry/icons/icon-mastodon.ts | 2 +- .../icon-registry/icons/icon-microsoft.ts | 2 +- .../core/icon-registry/icons/icon-pictures.ts | 2 +- .../icon-registry/icons/icon-twitter-x.ts | 2 +- .../core/icon-registry/icons/icon-twitter.ts | 2 +- .../core/icon-registry/icons/icon-umbrella.ts | 2 +- .../src/packages/core/package.json | 7 +- 17 files changed, 2622 insertions(+), 3386 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/devops/icons/index.js b/src/Umbraco.Web.UI.Client/devops/icons/index.js index b3c90e057c..811e031200 100644 --- a/src/Umbraco.Web.UI.Client/devops/icons/index.js +++ b/src/Umbraco.Web.UI.Client/devops/icons/index.js @@ -1,6 +1,7 @@ +/* eslint-disable local-rules/enforce-umbraco-external-imports */ import { readFileSync, writeFile, mkdir, rmSync } from 'fs'; -import * as globModule from 'tiny-glob'; import * as pathModule from 'path'; +import * as globModule from 'tiny-glob'; import { optimize } from 'svgo'; const path = pathModule.default; @@ -23,7 +24,7 @@ const run = async () => { // Empty output directory: rmSync(iconsOutputDirectory, { recursive: true }); - var icons = await collectDictionaryIcons(); + let icons = await collectDictionaryIcons(); icons = await collectDiskIcons(icons); writeIconsToDisk(icons); generateJS(icons); @@ -59,7 +60,7 @@ const collectDictionaryIcons = async () => { }; icons.push(icon); - } catch (e) { + } catch { errors.push(`[Lucide] Could not load file: '${path}'`); console.log(`[Lucide] Could not load file: '${path}'`); } @@ -91,7 +92,7 @@ const collectDictionaryIcons = async () => { }; icons.push(icon); - } catch (e) { + } catch { errors.push(`[SimpleIcons] Could not load file: '${path}'`); console.log(`[SimpleIcons] Could not load file: '${path}'`); } @@ -117,7 +118,7 @@ const collectDictionaryIcons = async () => { }; icons.push(icon); - } catch (e) { + } catch { errors.push(`[Umbraco] Could not load file: '${path}'`); console.log(`[Umbraco] Could not load file: '${path}'`); } @@ -171,11 +172,9 @@ const writeIconsToDisk = (icons) => { writeFileWithDir(icon.output, content, (err) => { if (err) { - // eslint-disable-next-line no-undef console.log(err); } - // eslint-disable-next-line no-undef //console.log(`icon: ${icon.name} generated`); }); }); @@ -192,18 +191,18 @@ const generateJS = (icons) => { ${icon.legacy ? 'legacy: true,' : ''} ${icon.hidden || icon.legacy ? 'hidden: true,' : ''} path: () => import("./icons/${icon.fileName}.js"), - }`.replace(/\t/g, '').replace(/^\s*[\r\n]/gm, ''); // Regex removes white space [NL] // + regex that removes empty lines. [NL] + }` + .replace(/\t/g, '') // Regex removes white space [NL] + .replace(/^\s*[\r\n]/gm, ''); // Regex that removes empty lines. [NL] }); const content = `export default [${iconDescriptors.join(',')}];`; writeFileWithDir(JSPath, content, (err) => { if (err) { - // eslint-disable-next-line no-undef console.log(err); } - // eslint-disable-next-line no-undef console.log('Icons outputted and Icon Manifests generated!'); }); }; diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 2288fa8383..1e44328da8 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -44,7 +44,6 @@ "eslint-plugin-storybook": "9.0.14", "eslint-plugin-wc": "^2.2.1", "globals": "^16.3.0", - "lucide-static": "^0.539.0", "madge": "^8.0.0", "msw": "^1.3.5", "playwright-msw": "^3.0.1", @@ -52,9 +51,7 @@ "postcss-cli": "^11.0.1", "prettier": "3.6.2", "remark-gfm": "^4.0.1", - "simple-icons": "^14.15.0", "storybook": "9.0.14", - "svgo": "^3.3.2", "tiny-glob": "^0.2.9", "tsc-alias": "^1.8.16", "typedoc": "^0.28.10", @@ -2659,16 +2656,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/@ts-graphviz/adapter": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@ts-graphviz/adapter/-/adapter-2.0.6.tgz", @@ -6535,13 +6522,13 @@ } }, "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", "dev": true, "license": "MIT", "dependencies": { - "mdn-data": "2.0.30", + "mdn-data": "2.12.2", "source-map-js": "^1.0.1" }, "engines": { @@ -10519,9 +10506,9 @@ } }, "node_modules/lucide-static": { - "version": "0.539.0", - "resolved": "https://registry.npmjs.org/lucide-static/-/lucide-static-0.539.0.tgz", - "integrity": "sha512-ybhtBJOeIgY1d1WV3vxJkSOoWi1EaYOkA15WYtct9/kX3+HSTCdbkeM0fQ4i5JxsKmp874J8dsNI92r4t5qCzg==", + "version": "0.542.0", + "resolved": "https://registry.npmjs.org/lucide-static/-/lucide-static-0.542.0.tgz", + "integrity": "sha512-jnXxFQYH0F24Nj5Zjje5jmMbGjClohnuSEYwTjAGuAa7UYDQiUjl0H7t4Ha19lkKryhCQA3VfeAJMjarrhzNZQ==", "dev": true, "license": "ISC" }, @@ -10898,9 +10885,9 @@ } }, "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", "dev": true, "license": "CC0-1.0" }, @@ -13374,63 +13361,6 @@ "postcss": "^8.4.32" } }, - "node_modules/postcss-svgo/node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "node_modules/postcss-svgo/node_modules/css-tree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", - "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "mdn-data": "2.12.2", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/postcss-svgo/node_modules/mdn-data": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", - "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/postcss-svgo/node_modules/svgo": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.0.tgz", - "integrity": "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "^11.1.0", - "css-select": "^5.1.0", - "css-tree": "^3.0.1", - "css-what": "^6.1.0", - "csso": "^5.0.5", - "picocolors": "^1.1.1", - "sax": "^1.4.1" - }, - "bin": { - "svgo": "bin/svgo.js" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/svgo" - } - }, "node_modules/postcss-unique-selectors": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-7.0.4.tgz", @@ -14851,17 +14781,23 @@ "license": "ISC" }, "node_modules/simple-icons": { - "version": "14.15.0", - "resolved": "https://registry.npmjs.org/simple-icons/-/simple-icons-14.15.0.tgz", - "integrity": "sha512-yjlJ8skP4isCd4dQTDGFbv0hQgDIr57DbWaovEeHADPAZa5DBEAs+3ZnBb76ti+yz7/OzFI3SqTP1SKku1uhCw==", + "version": "15.13.0", + "resolved": "https://registry.npmjs.org/simple-icons/-/simple-icons-15.13.0.tgz", + "integrity": "sha512-Tk3p1Lgmji+8kdUOIvvU3f0loYtWVo/bvO1T82Whpb6BhQ+wM2JR8BaVLQT+TiqqF25DVGrVYXeXrsPo6YDOvg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/simple-icons" + }, + { + "type": "github", + "url": "https://github.com/sponsors/simple-icons" + } + ], "license": "CC0-1.0", "engines": { "node": ">=0.12.18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/simple-icons" } }, "node_modules/slash": { @@ -15331,25 +15267,25 @@ } }, "node_modules/svgo": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", - "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.0.tgz", + "integrity": "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==", "dev": true, "license": "MIT", "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", + "commander": "^11.1.0", "css-select": "^5.1.0", - "css-tree": "^2.3.1", + "css-tree": "^3.0.1", "css-what": "^6.1.0", "csso": "^5.0.5", - "picocolors": "^1.0.0" + "picocolors": "^1.1.1", + "sax": "^1.4.1" }, "bin": { - "svgo": "bin/svgo" + "svgo": "bin/svgo.js" }, "engines": { - "node": ">=14.0.0" + "node": ">=16" }, "funding": { "type": "opencollective", @@ -15357,13 +15293,13 @@ } }, "node_modules/svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "dev": true, "license": "MIT", "engines": { - "node": ">= 10" + "node": ">=16" } }, "node_modules/synckit": { @@ -17170,6 +17106,11 @@ "@types/diff": "^7.0.2", "diff": "^7.0.0", "uuid": "^11.1.0" + }, + "devDependencies": { + "lucide-static": "^0.542.0", + "simple-icons": "^15.13.0", + "svgo": "^4.0.0" } }, "src/packages/core/node_modules/diff": { diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 96f6663eda..7577e7a544 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -242,7 +242,6 @@ "eslint-plugin-storybook": "9.0.14", "eslint-plugin-wc": "^2.2.1", "globals": "^16.3.0", - "lucide-static": "^0.539.0", "madge": "^8.0.0", "msw": "^1.3.5", "playwright-msw": "^3.0.1", @@ -250,9 +249,7 @@ "postcss-cli": "^11.0.1", "prettier": "3.6.2", "remark-gfm": "^4.0.1", - "simple-icons": "^14.15.0", "storybook": "9.0.14", - "svgo": "^3.3.2", "tiny-glob": "^0.2.9", "tsc-alias": "^1.8.16", "typedoc": "^0.28.10", diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons.ts index 353fe7c641..653bf6a54e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons.ts @@ -1,3260 +1,2554 @@ -export default [ - { - name: 'icon-activity', - path: () => import('./icons/icon-activity.js'), - }, - { - name: 'icon-add', - path: () => import('./icons/icon-add.js'), - }, - { - name: 'icon-addressbook', - path: () => import('./icons/icon-addressbook.js'), - }, - { - name: 'icon-alarm-clock', - path: () => import('./icons/icon-alarm-clock.js'), - }, - { - name: 'icon-alert-alt', - path: () => import('./icons/icon-alert-alt.js'), - }, - { - name: 'icon-alert', - path: () => import('./icons/icon-alert.js'), - }, - { - name: 'icon-alt', - path: () => import('./icons/icon-alt.js'), - }, - { - name: 'icon-anchor', - path: () => import('./icons/icon-anchor.js'), - }, - { - name: 'icon-app', - path: () => import('./icons/icon-app.js'), - }, - { - name: 'icon-application-error', - path: () => import('./icons/icon-application-error.js'), - }, - { - name: 'icon-application-window-alt', - path: () => import('./icons/icon-application-window-alt.js'), - }, - { - name: 'icon-application-window', - path: () => import('./icons/icon-application-window.js'), - }, - { - name: 'icon-arrivals', - path: () => import('./icons/icon-arrivals.js'), - }, - { - name: 'icon-arrow-down', - path: () => import('./icons/icon-arrow-down.js'), - }, - { - name: 'icon-arrow-left', - path: () => import('./icons/icon-arrow-left.js'), - }, - { - name: 'icon-arrow-right', - path: () => import('./icons/icon-arrow-right.js'), - }, - { - name: 'icon-arrow-up', - path: () => import('./icons/icon-arrow-up.js'), - }, - { - name: 'icon-attachment', - path: () => import('./icons/icon-attachment.js'), - }, - { - name: 'icon-audio-lines', - path: () => import('./icons/icon-audio-lines.js'), - }, - { - name: 'icon-autofill', - path: () => import('./icons/icon-autofill.js'), - }, - { - name: 'icon-award', - path: () => import('./icons/icon-award.js'), - }, - { - name: 'icon-axis-rotation-2', - path: () => import('./icons/icon-axis-rotation-2.js'), - }, - { - name: 'icon-axis-rotation-3', - path: () => import('./icons/icon-axis-rotation-3.js'), - }, - { - name: 'icon-axis-rotation', - path: () => import('./icons/icon-axis-rotation.js'), - }, - { - name: 'icon-backspace', - path: () => import('./icons/icon-backspace.js'), - }, - { - name: 'icon-badge-add', - path: () => import('./icons/icon-badge-add.js'), - }, - { - name: 'icon-badge-remove', - path: () => import('./icons/icon-badge-remove.js'), - }, - { - name: 'icon-badge-restricted', - legacy: true, - hidden: true, - path: () => import('./icons/icon-badge-restricted.js'), - }, - { - name: 'icon-ball', - path: () => import('./icons/icon-ball.js'), - }, - { - name: 'icon-bar-chart', - path: () => import('./icons/icon-bar-chart.js'), - }, - { - name: 'icon-barcode', - path: () => import('./icons/icon-barcode.js'), - }, - { - name: 'icon-bars', - path: () => import('./icons/icon-bars.js'), - }, - { - name: 'icon-battery-full', - path: () => import('./icons/icon-battery-full.js'), - }, - { - name: 'icon-battery-low', - path: () => import('./icons/icon-battery-low.js'), - }, - { - name: 'icon-beer-glass', - path: () => import('./icons/icon-beer-glass.js'), - }, - { - name: 'icon-bell-off', - path: () => import('./icons/icon-bell-off.js'), - }, - { - name: 'icon-bell', - path: () => import('./icons/icon-bell.js'), - }, - { - name: 'icon-binarycode', - path: () => import('./icons/icon-binarycode.js'), - }, - { - name: 'icon-binoculars', - legacy: true, - hidden: true, - path: () => import('./icons/icon-binoculars.js'), - }, - { - name: 'icon-bird', - path: () => import('./icons/icon-bird.js'), - }, - { - name: 'icon-birthday-cake', - path: () => import('./icons/icon-birthday-cake.js'), - }, - { - name: 'icon-block', - path: () => import('./icons/icon-block.js'), - }, - { - name: 'icon-blockquote', - path: () => import('./icons/icon-blockquote.js'), - }, - { - name: 'icon-bluetooth', - path: () => import('./icons/icon-bluetooth.js'), - }, - { - name: 'icon-boat-shipping', - path: () => import('./icons/icon-boat-shipping.js'), - }, - { - name: 'icon-bold', - path: () => import('./icons/icon-bold.js'), - }, - { - name: 'icon-bones', - path: () => import('./icons/icon-bones.js'), - }, - { - name: 'icon-book-alt-2', - path: () => import('./icons/icon-book-alt-2.js'), - }, - { - name: 'icon-book-alt', - path: () => import('./icons/icon-book-alt.js'), - }, - { - name: 'icon-book', - path: () => import('./icons/icon-book.js'), - }, - { - name: 'icon-bookmark', - path: () => import('./icons/icon-bookmark.js'), - }, - { - name: 'icon-books', - path: () => import('./icons/icon-books.js'), - }, - { - name: 'icon-box-alt', - path: () => import('./icons/icon-box-alt.js'), - }, - { - name: 'icon-box-open', - path: () => import('./icons/icon-box-open.js'), - }, - { - name: 'icon-box', - path: () => import('./icons/icon-box.js'), - }, - { - name: 'icon-brackets', - path: () => import('./icons/icon-brackets.js'), - }, - { - name: 'icon-brick', - path: () => import('./icons/icon-brick.js'), - }, - { - name: 'icon-briefcase', - path: () => import('./icons/icon-briefcase.js'), - }, - { - name: 'icon-browser-window', - path: () => import('./icons/icon-browser-window.js'), - }, - { - name: 'icon-brush-alt-2', - path: () => import('./icons/icon-brush-alt-2.js'), - }, - { - name: 'icon-brush-alt', - path: () => import('./icons/icon-brush-alt.js'), - }, - { - name: 'icon-brush', - path: () => import('./icons/icon-brush.js'), - }, - { - name: 'icon-bug', - path: () => import('./icons/icon-bug.js'), - }, - { - name: 'icon-bulleted-list', - path: () => import('./icons/icon-bulleted-list.js'), - }, - { - name: 'icon-burn', - path: () => import('./icons/icon-burn.js'), - }, - { - name: 'icon-bus', - path: () => import('./icons/icon-bus.js'), - }, - { - name: 'icon-calculator', - path: () => import('./icons/icon-calculator.js'), - }, - { - name: 'icon-calendar-alt', - path: () => import('./icons/icon-calendar-alt.js'), - }, - { - name: 'icon-calendar', - path: () => import('./icons/icon-calendar.js'), - }, - { - name: 'icon-camcorder', - legacy: true, - hidden: true, - path: () => import('./icons/icon-camcorder.js'), - }, - { - name: 'icon-camera-roll', - path: () => import('./icons/icon-camera-roll.js'), - }, - { - name: 'icon-candy', - path: () => import('./icons/icon-candy.js'), - }, - { - name: 'icon-caps-lock', - path: () => import('./icons/icon-caps-lock.js'), - }, - { - name: 'icon-car', - path: () => import('./icons/icon-car.js'), - }, - { - name: 'icon-categories', - path: () => import('./icons/icon-categories.js'), - }, - { - name: 'icon-certificate', - path: () => import('./icons/icon-certificate.js'), - }, - { - name: 'icon-chart-curve', - path: () => import('./icons/icon-chart-curve.js'), - }, - { - name: 'icon-chart', - path: () => import('./icons/icon-chart.js'), - }, - { - name: 'icon-chat-active', - legacy: true, - hidden: true, - path: () => import('./icons/icon-chat-active.js'), - }, - { - name: 'icon-chat', - path: () => import('./icons/icon-chat.js'), - }, - { - name: 'icon-check', - path: () => import('./icons/icon-check.js'), - }, - { - name: 'icon-checkbox-dotted', - path: () => import('./icons/icon-checkbox-dotted.js'), - }, - { - name: 'icon-checkbox-empty', - legacy: true, - hidden: true, - path: () => import('./icons/icon-checkbox-empty.js'), - }, - { - name: 'icon-checkbox', - path: () => import('./icons/icon-checkbox.js'), - }, - { - name: 'icon-chip-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-chip-alt.js'), - }, - { - name: 'icon-chip', - path: () => import('./icons/icon-chip.js'), - }, - { - name: 'icon-cinema', - path: () => import('./icons/icon-cinema.js'), - }, - { - name: 'icon-circle-dotted-active', - path: () => import('./icons/icon-circle-dotted-active.js'), - }, - { - name: 'icon-circle-dotted', - path: () => import('./icons/icon-circle-dotted.js'), - }, - { - name: 'icon-circuits', - path: () => import('./icons/icon-circuits.js'), - }, - { - name: 'icon-clear-formatting', - path: () => import('./icons/icon-clear-formatting.js'), - }, - { - name: 'icon-client', - legacy: true, - hidden: true, - path: () => import('./icons/icon-client.js'), - }, - { - name: 'icon-clipboard', - path: () => import('./icons/icon-clipboard.js'), - }, - { - name: 'icon-clipboard-copy', - path: () => import('./icons/icon-clipboard-copy.js'), - }, - { - name: 'icon-clipboard-entry', - path: () => import('./icons/icon-clipboard-entry.js'), - }, - { - name: 'icon-clipboard-paste', - path: () => import('./icons/icon-clipboard-paste.js'), - }, - { - name: 'icon-cloud-drive', - path: () => import('./icons/icon-cloud-drive.js'), - }, - { - name: 'icon-cloud-upload', - path: () => import('./icons/icon-cloud-upload.js'), - }, - { - name: 'icon-cloud', - path: () => import('./icons/icon-cloud.js'), - }, - { - name: 'icon-cloudy', - path: () => import('./icons/icon-cloudy.js'), - }, - { - name: 'icon-clubs', - path: () => import('./icons/icon-clubs.js'), - }, - { - name: 'icon-cocktail', - path: () => import('./icons/icon-cocktail.js'), - }, - { - name: 'icon-code', - path: () => import('./icons/icon-code.js'), - }, - { - name: 'icon-code-xml', - path: () => import('./icons/icon-code-xml.js'), - }, - { - name: 'icon-coffee', - path: () => import('./icons/icon-coffee.js'), - }, - { - name: 'icon-coin-dollar', - path: () => import('./icons/icon-coin-dollar.js'), - }, - { - name: 'icon-coin-euro', - path: () => import('./icons/icon-coin-euro.js'), - }, - { - name: 'icon-coin-pound', - path: () => import('./icons/icon-coin-pound.js'), - }, - { - name: 'icon-coin-yen', - path: () => import('./icons/icon-coin-yen.js'), - }, - { - name: 'icon-coins-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-coins-alt.js'), - }, - { - name: 'icon-coins', - path: () => import('./icons/icon-coins.js'), - }, - { - name: 'icon-color-bucket', - path: () => import('./icons/icon-color-bucket.js'), - }, - { - name: 'icon-colorpicker', - path: () => import('./icons/icon-colorpicker.js'), - }, - { - name: 'icon-columns', - path: () => import('./icons/icon-columns.js'), - }, - { - name: 'icon-columns-2', - path: () => import('./icons/icon-columns-2.js'), - }, - { - name: 'icon-columns-3', - path: () => import('./icons/icon-columns-3.js'), - }, - { - name: 'icon-columns-4', - path: () => import('./icons/icon-columns-4.js'), - }, - { - name: 'icon-rows-2', - path: () => import('./icons/icon-rows-2.js'), - }, - { - name: 'icon-rows-3', - path: () => import('./icons/icon-rows-3.js'), - }, - { - name: 'icon-rows-4', - path: () => import('./icons/icon-rows-4.js'), - }, - { - name: 'icon-grid-2', - path: () => import('./icons/icon-grid-2.js'), - }, - { - name: 'icon-grid-3', - path: () => import('./icons/icon-grid-3.js'), - }, - { - name: 'icon-combination-lock-open', - path: () => import('./icons/icon-combination-lock-open.js'), - }, - { - name: 'icon-combination-lock', - path: () => import('./icons/icon-combination-lock.js'), - }, - { - name: 'icon-command', - path: () => import('./icons/icon-command.js'), - }, - { - name: 'icon-company', - path: () => import('./icons/icon-company.js'), - }, - { - name: 'icon-compress', - path: () => import('./icons/icon-compress.js'), - }, - { - name: 'icon-connection', - path: () => import('./icons/icon-connection.js'), - }, - { - name: 'icon-console', - path: () => import('./icons/icon-console.js'), - }, - { - name: 'icon-contrast', - path: () => import('./icons/icon-contrast.js'), - }, - { - name: 'icon-conversation-alt', - path: () => import('./icons/icon-conversation-alt.js'), - }, - { - name: 'icon-conversation', - legacy: true, - hidden: true, - path: () => import('./icons/icon-conversation.js'), - }, - { - name: 'icon-coverflow', - path: () => import('./icons/icon-coverflow.js'), - }, - { - name: 'icon-credit-card-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-credit-card-alt.js'), - }, - { - name: 'icon-credit-card', - path: () => import('./icons/icon-credit-card.js'), - }, - { - name: 'icon-crop', - path: () => import('./icons/icon-crop.js'), - }, - { - name: 'icon-crosshair', - path: () => import('./icons/icon-crosshair.js'), - }, - { - name: 'icon-crown-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-crown-alt.js'), - }, - { - name: 'icon-crown', - path: () => import('./icons/icon-crown.js'), - }, - { - name: 'icon-cupcake', - legacy: true, - hidden: true, - path: () => import('./icons/icon-cupcake.js'), - }, - { - name: 'icon-curve', - path: () => import('./icons/icon-curve.js'), - }, - { - name: 'icon-cut', - path: () => import('./icons/icon-cut.js'), - }, - { - name: 'icon-dashboard', - path: () => import('./icons/icon-dashboard.js'), - }, - { - name: 'icon-defrag', - path: () => import('./icons/icon-defrag.js'), - }, - { - name: 'icon-delete-key', - path: () => import('./icons/icon-delete-key.js'), - }, - { - name: 'icon-delete', - path: () => import('./icons/icon-delete.js'), - }, - { - name: 'icon-departure', - path: () => import('./icons/icon-departure.js'), - }, - { - name: 'icon-desktop', - legacy: true, - hidden: true, - path: () => import('./icons/icon-desktop.js'), - }, - { - name: 'icon-diagnostics', - path: () => import('./icons/icon-diagnostics.js'), - }, - { - name: 'icon-diagonal-arrow-alt', - path: () => import('./icons/icon-diagonal-arrow-alt.js'), - }, - { - name: 'icon-diagonal-arrow', - path: () => import('./icons/icon-diagonal-arrow.js'), - }, - { - name: 'icon-diamond', - path: () => import('./icons/icon-diamond.js'), - }, - { - name: 'icon-diamonds', - path: () => import('./icons/icon-diamonds.js'), - }, - { - name: 'icon-dice', - path: () => import('./icons/icon-dice.js'), - }, - { - name: 'icon-diploma-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-diploma-alt.js'), - }, - { - name: 'icon-diploma', - path: () => import('./icons/icon-diploma.js'), - }, - { - name: 'icon-directions-alt', - path: () => import('./icons/icon-directions-alt.js'), - }, - { - name: 'icon-directions', - path: () => import('./icons/icon-directions.js'), - }, - { - name: 'icon-disc', - path: () => import('./icons/icon-disc.js'), - }, - { - name: 'icon-disk-image', - path: () => import('./icons/icon-disk-image.js'), - }, - { - name: 'icon-display', - path: () => import('./icons/icon-display.js'), - }, - { - name: 'icon-dna', - path: () => import('./icons/icon-dna.js'), - }, - { - name: 'icon-dock-connector', - path: () => import('./icons/icon-dock-connector.js'), - }, - { - name: 'icon-document-dashed-line', - legacy: true, - hidden: true, - path: () => import('./icons/icon-document-dashed-line.js'), - }, - { - name: 'icon-document', - path: () => import('./icons/icon-document.js'), - }, - { - name: 'icon-documents', - path: () => import('./icons/icon-documents.js'), - }, - { - name: 'icon-donate', - legacy: true, - hidden: true, - path: () => import('./icons/icon-donate.js'), - }, - { - name: 'icon-door-open-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-door-open-alt.js'), - }, - { - name: 'icon-door-open', - path: () => import('./icons/icon-door-open.js'), - }, - { - name: 'icon-download-alt', - path: () => import('./icons/icon-download-alt.js'), - }, - { - name: 'icon-download', - path: () => import('./icons/icon-download.js'), - }, - { - name: 'icon-drop', - path: () => import('./icons/icon-drop.js'), - }, - { - name: 'icon-eco', - path: () => import('./icons/icon-eco.js'), - }, - { - name: 'icon-economy', - legacy: true, - hidden: true, - path: () => import('./icons/icon-economy.js'), - }, - { - name: 'icon-edit', - path: () => import('./icons/icon-edit.js'), - }, - { - name: 'icon-embed', - path: () => import('./icons/icon-embed.js'), - }, - { - name: 'icon-employee', - legacy: true, - hidden: true, - path: () => import('./icons/icon-employee.js'), - }, - { - name: 'icon-energy-saving-bulb', - path: () => import('./icons/icon-energy-saving-bulb.js'), - }, - { - name: 'icon-enter', - path: () => import('./icons/icon-enter.js'), - }, - { - name: 'icon-equalizer', - path: () => import('./icons/icon-equalizer.js'), - }, - { - name: 'icon-escape', - path: () => import('./icons/icon-escape.js'), - }, - { - name: 'icon-ethernet', - path: () => import('./icons/icon-ethernet.js'), - }, - { - name: 'icon-eye', - path: () => import('./icons/icon-eye.js'), - }, - { - name: 'icon-exit-fullscreen', - path: () => import('./icons/icon-exit-fullscreen.js'), - }, - { - name: 'icon-facebook-like', - path: () => import('./icons/icon-facebook-like.js'), - }, - { - name: 'icon-factory', - path: () => import('./icons/icon-factory.js'), - }, - { - name: 'icon-favorite', - path: () => import('./icons/icon-favorite.js'), - }, - { - name: 'icon-file-cabinet', - path: () => import('./icons/icon-file-cabinet.js'), - }, - { - name: 'icon-files', - path: () => import('./icons/icon-files.js'), - }, - { - name: 'icon-filter-arrows', - path: () => import('./icons/icon-filter-arrows.js'), - }, - { - name: 'icon-filter', - path: () => import('./icons/icon-filter.js'), - }, - { - name: 'icon-fingerprint', - path: () => import('./icons/icon-fingerprint.js'), - }, - { - name: 'icon-fire', - path: () => import('./icons/icon-fire.js'), - }, - { - name: 'icon-firewire', - legacy: true, - hidden: true, - path: () => import('./icons/icon-firewire.js'), - }, - { - name: 'icon-flag-alt', - path: () => import('./icons/icon-flag-alt.js'), - }, - { - name: 'icon-flag', - path: () => import('./icons/icon-flag.js'), - }, - { - name: 'icon-flash', - path: () => import('./icons/icon-flash.js'), - }, - { - name: 'icon-flashlight', - path: () => import('./icons/icon-flashlight.js'), - }, - { - name: 'icon-flowerpot', - path: () => import('./icons/icon-flowerpot.js'), - }, - { - name: 'icon-folder', - path: () => import('./icons/icon-folder.js'), - }, - { - name: 'icon-folders', - path: () => import('./icons/icon-folders.js'), - }, - { - name: 'icon-font', - path: () => import('./icons/icon-font.js'), - }, - { - name: 'icon-food', - path: () => import('./icons/icon-food.js'), - }, - { - name: 'icon-footprints', - path: () => import('./icons/icon-footprints.js'), - }, - { - name: 'icon-forking', - path: () => import('./icons/icon-forking.js'), - }, - { - name: 'icon-frame-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-frame-alt.js'), - }, - { - name: 'icon-frame', - path: () => import('./icons/icon-frame.js'), - }, - { - name: 'icon-fullscreen-alt', - path: () => import('./icons/icon-fullscreen-alt.js'), - }, - { - name: 'icon-fullscreen', - path: () => import('./icons/icon-fullscreen.js'), - }, - { - name: 'icon-game', - path: () => import('./icons/icon-game.js'), - }, - { - name: 'icon-geometry', - legacy: true, - hidden: true, - path: () => import('./icons/icon-geometry.js'), - }, - { - name: 'icon-gift', - path: () => import('./icons/icon-gift.js'), - }, - { - name: 'icon-glasses', - path: () => import('./icons/icon-glasses.js'), - }, - { - name: 'icon-globe-alt', - path: () => import('./icons/icon-globe-alt.js'), - }, - { - name: 'icon-globe-asia', - legacy: true, - hidden: true, - path: () => import('./icons/icon-globe-asia.js'), - }, - { - name: 'icon-globe-europe-africa', - legacy: true, - hidden: true, - path: () => import('./icons/icon-globe-europe-africa.js'), - }, - { - name: 'icon-globe-inverted-america', - legacy: true, - hidden: true, - path: () => import('./icons/icon-globe-inverted-america.js'), - }, - { - name: 'icon-globe-inverted-asia', - legacy: true, - hidden: true, - path: () => import('./icons/icon-globe-inverted-asia.js'), - }, - { - name: 'icon-globe-inverted-europe-africa', - legacy: true, - hidden: true, - path: () => import('./icons/icon-globe-inverted-europe-africa.js'), - }, - { - name: 'icon-globe', - path: () => import('./icons/icon-globe.js'), - }, - { - name: 'icon-gps', - path: () => import('./icons/icon-gps.js'), - }, - { - name: 'icon-graduate', - path: () => import('./icons/icon-graduate.js'), - }, - { - name: 'icon-grid', - path: () => import('./icons/icon-grid.js'), - }, - { - name: 'icon-grip', - hidden: true, - path: () => import('./icons/icon-grip.js'), - }, - { - name: 'icon-hammer', - path: () => import('./icons/icon-hammer.js'), - }, - { - name: 'icon-hand-active-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-hand-active-alt.js'), - }, - { - name: 'icon-hand-active', - path: () => import('./icons/icon-hand-active.js'), - }, - { - name: 'icon-hand-pointer-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-hand-pointer-alt.js'), - }, - { - name: 'icon-hand-pointer', - path: () => import('./icons/icon-hand-pointer.js'), - }, - { - name: 'icon-handshake', - path: () => import('./icons/icon-handshake.js'), - }, - { - name: 'icon-handtool-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-handtool-alt.js'), - }, - { - name: 'icon-handtool', - path: () => import('./icons/icon-handtool.js'), - }, - { - name: 'icon-hard-drive-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-hard-drive-alt.js'), - }, - { - name: 'icon-hard-drive', - legacy: true, - hidden: true, - path: () => import('./icons/icon-hard-drive.js'), - }, - { - name: 'icon-heading-1', - path: () => import('./icons/icon-heading-1.js'), - }, - { - name: 'icon-heading-2', - path: () => import('./icons/icon-heading-2.js'), - }, - { - name: 'icon-heading-3', - path: () => import('./icons/icon-heading-3.js'), - }, - { - name: 'icon-heading-4', - path: () => import('./icons/icon-heading-4.js'), - }, - { - name: 'icon-headphones', - path: () => import('./icons/icon-headphones.js'), - }, - { - name: 'icon-headset', - legacy: true, - hidden: true, - path: () => import('./icons/icon-headset.js'), - }, - { - name: 'icon-hearts', - path: () => import('./icons/icon-hearts.js'), - }, - { - name: 'icon-height', - path: () => import('./icons/icon-height.js'), - }, - { - name: 'icon-help-alt', - path: () => import('./icons/icon-help-alt.js'), - }, - { - name: 'icon-help', - path: () => import('./icons/icon-help.js'), - }, - { - name: 'icon-history', - path: () => import('./icons/icon-history.js'), - }, - { - name: 'icon-home', - path: () => import('./icons/icon-home.js'), - }, - { - name: 'icon-horizontal-rule', - path: () => import('./icons/icon-horizontal-rule.js'), - }, - { - name: 'icon-hourglass', - path: () => import('./icons/icon-hourglass.js'), - }, - { - name: 'icon-imac', - legacy: true, - hidden: true, - path: () => import('./icons/icon-imac.js'), - }, - { - name: 'icon-image-up', - path: () => import('./icons/icon-image-up.js'), - }, - { - name: 'icon-inbox-full', - legacy: true, - hidden: true, - path: () => import('./icons/icon-inbox-full.js'), - }, - { - name: 'icon-inbox', - path: () => import('./icons/icon-inbox.js'), - }, - { - name: 'icon-indent', - path: () => import('./icons/icon-indent.js'), - }, - { - name: 'icon-infinity', - path: () => import('./icons/icon-infinity.js'), - }, - { - name: 'icon-info', - path: () => import('./icons/icon-info.js'), - }, - { - name: 'icon-invoice', - legacy: true, - hidden: true, - path: () => import('./icons/icon-invoice.js'), - }, - { - name: 'icon-ipad', - legacy: true, - hidden: true, - path: () => import('./icons/icon-ipad.js'), - }, - { - name: 'icon-iphone', - legacy: true, - hidden: true, - path: () => import('./icons/icon-iphone.js'), - }, - { - name: 'icon-italic', - path: () => import('./icons/icon-italic.js'), - }, - { - name: 'icon-item-arrangement', - legacy: true, - hidden: true, - path: () => import('./icons/icon-item-arrangement.js'), - }, - { - name: 'icon-junk', - path: () => import('./icons/icon-junk.js'), - }, - { - name: 'icon-key', - path: () => import('./icons/icon-key.js'), - }, - { - name: 'icon-keyboard', - path: () => import('./icons/icon-keyboard.js'), - }, - { - name: 'icon-lab', - path: () => import('./icons/icon-lab.js'), - }, - { - name: 'icon-laptop', - path: () => import('./icons/icon-laptop.js'), - }, - { - name: 'icon-layers-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-layers-alt.js'), - }, - { - name: 'icon-layers', - path: () => import('./icons/icon-layers.js'), - }, - { - name: 'icon-layout', - path: () => import('./icons/icon-layout.js'), - }, - { - name: 'icon-left-double-arrow', - path: () => import('./icons/icon-left-double-arrow.js'), - }, - { - name: 'icon-legal', - path: () => import('./icons/icon-legal.js'), - }, - { - name: 'icon-lense', - legacy: true, - hidden: true, - path: () => import('./icons/icon-lense.js'), - }, - { - name: 'icon-library', - path: () => import('./icons/icon-library.js'), - }, - { - name: 'icon-light-down', - path: () => import('./icons/icon-light-down.js'), - }, - { - name: 'icon-light-up', - path: () => import('./icons/icon-light-up.js'), - }, - { - name: 'icon-lightbulb-active', - path: () => import('./icons/icon-lightbulb-active.js'), - }, - { - name: 'icon-lightbulb', - legacy: true, - hidden: true, - path: () => import('./icons/icon-lightbulb.js'), - }, - { - name: 'icon-lightning', - path: () => import('./icons/icon-lightning.js'), - }, - { - name: 'icon-link', - path: () => import('./icons/icon-link.js'), - }, - { - name: 'icon-list', - path: () => import('./icons/icon-list.js'), - }, - { - name: 'icon-load', - legacy: true, - hidden: true, - path: () => import('./icons/icon-load.js'), - }, - { - name: 'icon-loading', - legacy: true, - hidden: true, - path: () => import('./icons/icon-loading.js'), - }, - { - name: 'icon-locate', - path: () => import('./icons/icon-locate.js'), - }, - { - name: 'icon-location-near-me', - legacy: true, - hidden: true, - path: () => import('./icons/icon-location-near-me.js'), - }, - { - name: 'icon-location-nearby', - path: () => import('./icons/icon-location-nearby.js'), - }, - { - name: 'icon-lock', - path: () => import('./icons/icon-lock.js'), - }, - { - name: 'icon-log-out', - path: () => import('./icons/icon-log-out.js'), - }, - { - name: 'icon-logout', - legacy: true, - hidden: true, - path: () => import('./icons/icon-logout.js'), - }, - { - name: 'icon-loupe', - legacy: true, - hidden: true, - path: () => import('./icons/icon-loupe.js'), - }, - { - name: 'icon-magnet', - path: () => import('./icons/icon-magnet.js'), - }, - { - name: 'icon-mailbox', - path: () => import('./icons/icon-mailbox.js'), - }, - { - name: 'icon-map-alt', - path: () => import('./icons/icon-map-alt.js'), - }, - { - name: 'icon-map-location', - legacy: true, - hidden: true, - path: () => import('./icons/icon-map-location.js'), - }, - { - name: 'icon-map-marker', - path: () => import('./icons/icon-map-marker.js'), - }, - { - name: 'icon-map', - path: () => import('./icons/icon-map.js'), - }, - { - name: 'icon-medal', - path: () => import('./icons/icon-medal.js'), - }, - { - name: 'icon-medical-emergency', - path: () => import('./icons/icon-medical-emergency.js'), - }, - { - name: 'icon-medicine', - path: () => import('./icons/icon-medicine.js'), - }, - { - name: 'icon-meeting', - legacy: true, - hidden: true, - path: () => import('./icons/icon-meeting.js'), - }, - { - name: 'icon-megaphone', - path: () => import('./icons/icon-megaphone.js'), - }, - { - name: 'icon-merge', - path: () => import('./icons/icon-merge.js'), - }, - { - name: 'icon-message-open', - path: () => import('./icons/icon-message-open.js'), - }, - { - name: 'icon-message-unopened', - legacy: true, - hidden: true, - path: () => import('./icons/icon-message-unopened.js'), - }, - { - name: 'icon-message', - path: () => import('./icons/icon-message.js'), - }, - { - name: 'icon-microscope', - path: () => import('./icons/icon-microscope.js'), - }, - { - name: 'icon-mindmap', - legacy: true, - hidden: true, - path: () => import('./icons/icon-mindmap.js'), - }, - { - name: 'icon-mobile', - path: () => import('./icons/icon-mobile.js'), - }, - { - name: 'icon-mountain', - path: () => import('./icons/icon-mountain.js'), - }, - { - name: 'icon-mouse-cursor', - path: () => import('./icons/icon-mouse-cursor.js'), - }, - { - name: 'icon-mouse', - path: () => import('./icons/icon-mouse.js'), - }, - { - name: 'icon-movie-alt', - path: () => import('./icons/icon-movie-alt.js'), - }, - { - name: 'icon-movie', - path: () => import('./icons/icon-movie.js'), - }, - { - name: 'icon-multiple-credit-cards', - path: () => import('./icons/icon-multiple-credit-cards.js'), - }, - { - name: 'icon-multiple-windows', - path: () => import('./icons/icon-multiple-windows.js'), - }, - { - name: 'icon-music', - path: () => import('./icons/icon-music.js'), - }, - { - name: 'icon-name-badge', - legacy: true, - hidden: true, - path: () => import('./icons/icon-name-badge.js'), - }, - { - name: 'icon-navigation-bottom', - legacy: true, - hidden: true, - path: () => import('./icons/icon-navigation-bottom.js'), - }, - { - name: 'icon-navigation-down', - legacy: true, - hidden: true, - path: () => import('./icons/icon-navigation-down.js'), - }, - { - name: 'icon-navigation-first', - legacy: true, - hidden: true, - path: () => import('./icons/icon-navigation-first.js'), - }, - { - name: 'icon-navigation-horizontal', - legacy: true, - hidden: true, - path: () => import('./icons/icon-navigation-horizontal.js'), - }, - { - name: 'icon-navigation-last', - legacy: true, - hidden: true, - path: () => import('./icons/icon-navigation-last.js'), - }, - { - name: 'icon-navigation-left', - legacy: true, - hidden: true, - path: () => import('./icons/icon-navigation-left.js'), - }, - { - name: 'icon-navigation-right', - legacy: true, - hidden: true, - path: () => import('./icons/icon-navigation-right.js'), - }, - { - name: 'icon-navigation-road', - legacy: true, - hidden: true, - path: () => import('./icons/icon-navigation-road.js'), - }, - { - name: 'icon-navigation-top', - legacy: true, - hidden: true, - path: () => import('./icons/icon-navigation-top.js'), - }, - { - name: 'icon-navigation-up', - legacy: true, - hidden: true, - path: () => import('./icons/icon-navigation-up.js'), - }, - { - name: 'icon-navigation-vertical', - legacy: true, - hidden: true, - path: () => import('./icons/icon-navigation-vertical.js'), - }, - { - name: 'icon-navigation', - legacy: true, - hidden: true, - path: () => import('./icons/icon-navigation.js'), - }, - { - name: 'icon-navigational-arrow', - path: () => import('./icons/icon-navigational-arrow.js'), - }, - { - name: 'icon-network-alt', - path: () => import('./icons/icon-network-alt.js'), - }, - { - name: 'icon-newspaper-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-newspaper-alt.js'), - }, - { - name: 'icon-newspaper', - path: () => import('./icons/icon-newspaper.js'), - }, - { - name: 'icon-next-media', - legacy: true, - hidden: true, - path: () => import('./icons/icon-next-media.js'), - }, - { - name: 'icon-next', - path: () => import('./icons/icon-next.js'), - }, - { - name: 'icon-nodes', - legacy: true, - hidden: true, - path: () => import('./icons/icon-nodes.js'), - }, - { - name: 'icon-notepad-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-notepad-alt.js'), - }, - { - name: 'icon-notepad', - path: () => import('./icons/icon-notepad.js'), - }, - { - name: 'icon-old-key', - path: () => import('./icons/icon-old-key.js'), - }, - { - name: 'icon-old-phone', - legacy: true, - hidden: true, - path: () => import('./icons/icon-old-phone.js'), - }, - { - name: 'icon-omega', - path: () => import('./icons/icon-omega.js'), - }, - { - name: 'icon-operator', - path: () => import('./icons/icon-operator.js'), - }, - { - name: 'icon-ordered-list', - path: () => import('./icons/icon-ordered-list.js'), - }, - { - name: 'icon-origami', - path: () => import('./icons/icon-origami.js'), - }, - { - name: 'icon-out', - path: () => import('./icons/icon-out.js'), - }, - { - name: 'icon-outbox', - legacy: true, - hidden: true, - path: () => import('./icons/icon-outbox.js'), - }, - { - name: 'icon-outdent', - path: () => import('./icons/icon-outdent.js'), - }, - { - name: 'icon-page-add', - path: () => import('./icons/icon-page-add.js'), - }, - { - name: 'icon-page-down', - path: () => import('./icons/icon-page-down.js'), - }, - { - name: 'icon-page-remove', - path: () => import('./icons/icon-page-remove.js'), - }, - { - name: 'icon-page-restricted', - path: () => import('./icons/icon-page-restricted.js'), - }, - { - name: 'icon-page-up', - path: () => import('./icons/icon-page-up.js'), - }, - { - name: 'icon-paint-roller', - legacy: true, - hidden: true, - path: () => import('./icons/icon-paint-roller.js'), - }, - { - name: 'icon-palette', - path: () => import('./icons/icon-palette.js'), - }, - { - name: 'icon-panel-show', - path: () => import('./icons/icon-panel-show.js'), - }, - { - name: 'icon-pannel-close', - path: () => import('./icons/icon-pannel-close.js'), - }, - { - name: 'icon-paper-bag', - legacy: true, - hidden: true, - path: () => import('./icons/icon-paper-bag.js'), - }, - { - name: 'icon-paper-plane-alt', - path: () => import('./icons/icon-paper-plane-alt.js'), - }, - { - name: 'icon-paper-plane', - path: () => import('./icons/icon-paper-plane.js'), - }, - { - name: 'icon-partly-cloudy', - path: () => import('./icons/icon-partly-cloudy.js'), - }, - { - name: 'icon-paragraph', - path: () => import('./icons/icon-paragraph.js'), - }, - { - name: 'icon-paste-in', - legacy: true, - hidden: true, - path: () => import('./icons/icon-paste-in.js'), - }, - { - name: 'icon-pause', - path: () => import('./icons/icon-pause.js'), - }, - { - name: 'icon-pc', - legacy: true, - hidden: true, - path: () => import('./icons/icon-pc.js'), - }, - { - name: 'icon-people-alt-2', - legacy: true, - hidden: true, - path: () => import('./icons/icon-people-alt-2.js'), - }, - { - name: 'icon-people-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-people-alt.js'), - }, - { - name: 'icon-people-female', - legacy: true, - hidden: true, - path: () => import('./icons/icon-people-female.js'), - }, - { - name: 'icon-people', - path: () => import('./icons/icon-people.js'), - }, - { - name: 'icon-phone-ring', - path: () => import('./icons/icon-phone-ring.js'), - }, - { - name: 'icon-phone', - path: () => import('./icons/icon-phone.js'), - }, - { - name: 'icon-photo-album', - path: () => import('./icons/icon-photo-album.js'), - }, - { - name: 'icon-picture', - path: () => import('./icons/icon-picture.js'), - }, - { - name: 'icon-pictures-alt-2', - path: () => import('./icons/icon-pictures-alt-2.js'), - }, - { - name: 'icon-pictures-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-pictures-alt.js'), - }, - { - name: 'icon-pictures', - path: () => import('./icons/icon-pictures.js'), - }, - { - name: 'icon-pie-chart', - path: () => import('./icons/icon-pie-chart.js'), - }, - { - name: 'icon-piggy-bank', - path: () => import('./icons/icon-piggy-bank.js'), - }, - { - name: 'icon-pin-location', - path: () => import('./icons/icon-pin-location.js'), - }, - { - name: 'icon-plane', - path: () => import('./icons/icon-plane.js'), - }, - { - name: 'icon-planet', - legacy: true, - hidden: true, - path: () => import('./icons/icon-planet.js'), - }, - { - name: 'icon-play', - path: () => import('./icons/icon-play.js'), - }, - { - name: 'icon-playing-cards', - legacy: true, - hidden: true, - path: () => import('./icons/icon-playing-cards.js'), - }, - { - name: 'icon-playlist', - path: () => import('./icons/icon-playlist.js'), - }, - { - name: 'icon-plugin', - path: () => import('./icons/icon-plugin.js'), - }, - { - name: 'icon-podcast', - path: () => import('./icons/icon-podcast.js'), - }, - { - name: 'icon-poll', - legacy: true, - hidden: true, - path: () => import('./icons/icon-poll.js'), - }, - { - name: 'icon-post-it', - path: () => import('./icons/icon-post-it.js'), - }, - { - name: 'icon-power-outlet', - legacy: true, - hidden: true, - path: () => import('./icons/icon-power-outlet.js'), - }, - { - name: 'icon-power', - path: () => import('./icons/icon-power.js'), - }, - { - name: 'icon-presentation', - path: () => import('./icons/icon-presentation.js'), - }, - { - name: 'icon-previous-media', - path: () => import('./icons/icon-previous-media.js'), - }, - { - name: 'icon-previous', - path: () => import('./icons/icon-previous.js'), - }, - { - name: 'icon-price-dollar', - legacy: true, - hidden: true, - path: () => import('./icons/icon-price-dollar.js'), - }, - { - name: 'icon-price-euro', - legacy: true, - hidden: true, - path: () => import('./icons/icon-price-euro.js'), - }, - { - name: 'icon-price-pound', - legacy: true, - hidden: true, - path: () => import('./icons/icon-price-pound.js'), - }, - { - name: 'icon-price-yen', - legacy: true, - hidden: true, - path: () => import('./icons/icon-price-yen.js'), - }, - { - name: 'icon-print', - path: () => import('./icons/icon-print.js'), - }, - { - name: 'icon-printer-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-printer-alt.js'), - }, - { - name: 'icon-projector', - path: () => import('./icons/icon-projector.js'), - }, - { - name: 'icon-pulse', - path: () => import('./icons/icon-pulse.js'), - }, - { - name: 'icon-pushpin', - path: () => import('./icons/icon-pushpin.js'), - }, - { - name: 'icon-qr-code', - path: () => import('./icons/icon-qr-code.js'), - }, - { - name: 'icon-quote', - path: () => import('./icons/icon-quote.js'), - }, - { - name: 'icon-radio-alt', - path: () => import('./icons/icon-radio-alt.js'), - }, - { - name: 'icon-radio-receiver', - path: () => import('./icons/icon-radio-receiver.js'), - }, - { - name: 'icon-radio', - path: () => import('./icons/icon-radio.js'), - }, - { - name: 'icon-rain', - path: () => import('./icons/icon-rain.js'), - }, - { - name: 'icon-rate', - legacy: true, - hidden: true, - path: () => import('./icons/icon-rate.js'), - }, - { - name: 'icon-re-post', - path: () => import('./icons/icon-re-post.js'), - }, - { - name: 'icon-readonly', - path: () => import('./icons/icon-readonly.js'), - }, - { - name: 'icon-receipt-alt', - path: () => import('./icons/icon-receipt-alt.js'), - }, - { - name: 'icon-reception', - path: () => import('./icons/icon-reception.js'), - }, - { - name: 'icon-record', - legacy: true, - hidden: true, - path: () => import('./icons/icon-record.js'), - }, - { - name: 'icon-rectangle-ellipsis', - path: () => import('./icons/icon-rectangle-ellipsis.js'), - }, - { - name: 'icon-redo', - path: () => import('./icons/icon-redo.js'), - }, - { - name: 'icon-refresh', - path: () => import('./icons/icon-refresh.js'), - }, - { - name: 'icon-remote', - legacy: true, - hidden: true, - path: () => import('./icons/icon-remote.js'), - }, - { - name: 'icon-remove', - path: () => import('./icons/icon-remove.js'), - }, - { - name: 'icon-repeat-one', - path: () => import('./icons/icon-repeat-one.js'), - }, - { - name: 'icon-repeat', - path: () => import('./icons/icon-repeat.js'), - }, - { - name: 'icon-reply-arrow', - path: () => import('./icons/icon-reply-arrow.js'), - }, - { - name: 'icon-resize', - path: () => import('./icons/icon-resize.js'), - }, - { - name: 'icon-return-to-top', - legacy: true, - hidden: true, - path: () => import('./icons/icon-return-to-top.js'), - }, - { - name: 'icon-right-double-arrow', - legacy: true, - hidden: true, - path: () => import('./icons/icon-right-double-arrow.js'), - }, - { - name: 'icon-roadsign', - legacy: true, - hidden: true, - path: () => import('./icons/icon-roadsign.js'), - }, - { - name: 'icon-rocket', - path: () => import('./icons/icon-rocket.js'), - }, - { - name: 'icon-rss', - path: () => import('./icons/icon-rss.js'), - }, - { - name: 'icon-ruler-alt', - path: () => import('./icons/icon-ruler-alt.js'), - }, - { - name: 'icon-ruler', - path: () => import('./icons/icon-ruler.js'), - }, - { - name: 'icon-satellite-dish', - path: () => import('./icons/icon-satellite-dish.js'), - }, - { - name: 'icon-save', - path: () => import('./icons/icon-save.js'), - }, - { - name: 'icon-scan', - path: () => import('./icons/icon-scan.js'), - }, - { - name: 'icon-school', - path: () => import('./icons/icon-school.js'), - }, - { - name: 'icon-screensharing', - path: () => import('./icons/icon-screensharing.js'), - }, - { - name: 'icon-script-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-script-alt.js'), - }, - { - name: 'icon-script', - path: () => import('./icons/icon-script.js'), - }, - { - name: 'icon-scull', - path: () => import('./icons/icon-scull.js'), - }, - { - name: 'icon-search', - path: () => import('./icons/icon-search.js'), - }, - { - name: 'icon-sensor', - path: () => import('./icons/icon-sensor.js'), - }, - { - name: 'icon-server-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-server-alt.js'), - }, - { - name: 'icon-server', - path: () => import('./icons/icon-server.js'), - }, - { - name: 'icon-settings-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-settings-alt.js'), - }, - { - name: 'icon-settings', - path: () => import('./icons/icon-settings.js'), - }, - { - name: 'icon-share-alt', - path: () => import('./icons/icon-share-alt.js'), - }, - { - name: 'icon-share', - path: () => import('./icons/icon-share.js'), - }, - { - name: 'icon-sharing-iphone', - path: () => import('./icons/icon-sharing-iphone.js'), - }, - { - name: 'icon-shield', - path: () => import('./icons/icon-shield.js'), - }, - { - name: 'icon-shift', - path: () => import('./icons/icon-shift.js'), - }, - { - name: 'icon-shipping-box', - path: () => import('./icons/icon-shipping-box.js'), - }, - { - name: 'icon-shipping', - path: () => import('./icons/icon-shipping.js'), - }, - { - name: 'icon-shoe', - legacy: true, - hidden: true, - path: () => import('./icons/icon-shoe.js'), - }, - { - name: 'icon-shopping-basket-alt-2', - legacy: true, - hidden: true, - path: () => import('./icons/icon-shopping-basket-alt-2.js'), - }, - { - name: 'icon-shopping-basket-alt', - path: () => import('./icons/icon-shopping-basket-alt.js'), - }, - { - name: 'icon-shopping-basket', - path: () => import('./icons/icon-shopping-basket.js'), - }, - { - name: 'icon-shuffle', - path: () => import('./icons/icon-shuffle.js'), - }, - { - name: 'icon-sience', - legacy: true, - hidden: true, - path: () => import('./icons/icon-sience.js'), - }, - { - name: 'icon-science', - path: () => import('./icons/icon-science.js'), - }, - { - name: 'icon-single-note', - path: () => import('./icons/icon-single-note.js'), - }, - { - name: 'icon-sitemap', - legacy: true, - hidden: true, - path: () => import('./icons/icon-sitemap.js'), - }, - { - name: 'icon-sleep', - path: () => import('./icons/icon-sleep.js'), - }, - { - name: 'icon-slideshow', - legacy: true, - hidden: true, - path: () => import('./icons/icon-slideshow.js'), - }, - { - name: 'icon-smiley-inverted', - legacy: true, - hidden: true, - path: () => import('./icons/icon-smiley-inverted.js'), - }, - { - name: 'icon-smiley', - path: () => import('./icons/icon-smiley.js'), - }, - { - name: 'icon-snow', - path: () => import('./icons/icon-snow.js'), - }, - { - name: 'icon-sound-low', - path: () => import('./icons/icon-sound-low.js'), - }, - { - name: 'icon-sound-medium', - legacy: true, - hidden: true, - path: () => import('./icons/icon-sound-medium.js'), - }, - { - name: 'icon-sound-off', - path: () => import('./icons/icon-sound-off.js'), - }, - { - name: 'icon-sound-waves', - path: () => import('./icons/icon-sound-waves.js'), - }, - { - name: 'icon-sound', - path: () => import('./icons/icon-sound.js'), - }, - { - name: 'icon-spades', - path: () => import('./icons/icon-spades.js'), - }, - { - name: 'icon-speaker', - path: () => import('./icons/icon-speaker.js'), - }, - { - name: 'icon-speed-gauge', - path: () => import('./icons/icon-speed-gauge.js'), - }, - { - name: 'icon-split-alt', - path: () => import('./icons/icon-split-alt.js'), - }, - { - name: 'icon-split', - path: () => import('./icons/icon-split.js'), - }, - { - name: 'icon-sprout', - path: () => import('./icons/icon-sprout.js'), - }, - { - name: 'icon-squiggly-line', - legacy: true, - hidden: true, - path: () => import('./icons/icon-squiggly-line.js'), - }, - { - name: 'icon-ssd', - legacy: true, - hidden: true, - path: () => import('./icons/icon-ssd.js'), - }, - { - name: 'icon-stacked-disks', - legacy: true, - hidden: true, - path: () => import('./icons/icon-stacked-disks.js'), - }, - { - name: 'icon-stamp', - legacy: true, - hidden: true, - path: () => import('./icons/icon-stamp.js'), - }, - { - name: 'icon-stop-alt', - path: () => import('./icons/icon-stop-alt.js'), - }, - { - name: 'icon-stop-hand', - legacy: true, - hidden: true, - path: () => import('./icons/icon-stop-hand.js'), - }, - { - name: 'icon-stop', - path: () => import('./icons/icon-stop.js'), - }, - { - name: 'icon-store', - path: () => import('./icons/icon-store.js'), - }, - { - name: 'icon-stream', - legacy: true, - hidden: true, - path: () => import('./icons/icon-stream.js'), - }, - { - name: 'icon-strikethrough', - path: () => import('./icons/icon-strikethrough.js'), - }, - { - name: 'icon-subscript', - path: () => import('./icons/icon-subscript.js'), - }, - { - name: 'icon-superscript', - path: () => import('./icons/icon-superscript.js'), - }, - { - name: 'icon-sunny', - path: () => import('./icons/icon-sunny.js'), - }, - { - name: 'icon-sweatshirt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-sweatshirt.js'), - }, - { - name: 'icon-sync', - path: () => import('./icons/icon-sync.js'), - }, - { - name: 'icon-t-shirt', - path: () => import('./icons/icon-t-shirt.js'), - }, - { - name: 'icon-tab-key', - path: () => import('./icons/icon-tab-key.js'), - }, - { - name: 'icon-table', - path: () => import('./icons/icon-table.js'), - }, - { - name: 'icon-tag', - path: () => import('./icons/icon-tag.js'), - }, - { - name: 'icon-tags', - path: () => import('./icons/icon-tags.js'), - }, - { - name: 'icon-takeaway-cup', - legacy: true, - hidden: true, - path: () => import('./icons/icon-takeaway-cup.js'), - }, - { - name: 'icon-target', - path: () => import('./icons/icon-target.js'), - }, - { - name: 'icon-temperatrure-alt', - path: () => import('./icons/icon-temperatrure-alt.js'), - }, - { - name: 'icon-temperature', - path: () => import('./icons/icon-temperature.js'), - }, - { - name: 'icon-terminal', - path: () => import('./icons/icon-terminal.js'), - }, - { - name: 'icon-text-align-center', - path: () => import('./icons/icon-text-align-center.js'), - }, - { - name: 'icon-text-align-justify', - path: () => import('./icons/icon-text-align-justify.js'), - }, - { - name: 'icon-text-align-left', - path: () => import('./icons/icon-text-align-left.js'), - }, - { - name: 'icon-text-align-right', - path: () => import('./icons/icon-text-align-right.js'), - }, - { - name: 'icon-text-direction-ltr', - path: () => import('./icons/icon-text-direction-ltr.js'), - }, - { - name: 'icon-text-direction-rtl', - path: () => import('./icons/icon-text-direction-rtl.js'), - }, - { - name: 'icon-theater', - path: () => import('./icons/icon-theater.js'), - }, - { - name: 'icon-thumb-down', - path: () => import('./icons/icon-thumb-down.js'), - }, - { - name: 'icon-thumb-up', - path: () => import('./icons/icon-thumb-up.js'), - }, - { - name: 'icon-thumbnail-list', - path: () => import('./icons/icon-thumbnail-list.js'), - }, - { - name: 'icon-thumbnails-small', - path: () => import('./icons/icon-thumbnails-small.js'), - }, - { - name: 'icon-thumbnails', - path: () => import('./icons/icon-thumbnails.js'), - }, - { - name: 'icon-ticket', - path: () => import('./icons/icon-ticket.js'), - }, - { - name: 'icon-time', - path: () => import('./icons/icon-time.js'), - }, - { - name: 'icon-timer', - path: () => import('./icons/icon-timer.js'), - }, - { - name: 'icon-tools', - legacy: true, - hidden: true, - path: () => import('./icons/icon-tools.js'), - }, - { - name: 'icon-top', - legacy: true, - hidden: true, - path: () => import('./icons/icon-top.js'), - }, - { - name: 'icon-traffic-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-traffic-alt.js'), - }, - { - name: 'icon-trafic', - path: () => import('./icons/icon-trafic.js'), - }, - { - name: 'icon-train', - path: () => import('./icons/icon-train.js'), - }, - { - name: 'icon-trash-alt-2', - legacy: true, - hidden: true, - path: () => import('./icons/icon-trash-alt-2.js'), - }, - { - name: 'icon-trash-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-trash-alt.js'), - }, - { - name: 'icon-trash', - path: () => import('./icons/icon-trash.js'), - }, - { - name: 'icon-tree', - path: () => import('./icons/icon-tree.js'), - }, - { - name: 'icon-trophy', - path: () => import('./icons/icon-trophy.js'), - }, - { - name: 'icon-truck', - path: () => import('./icons/icon-truck.js'), - }, - { - name: 'icon-tv-old', - path: () => import('./icons/icon-tv-old.js'), - }, - { - name: 'icon-tv', - path: () => import('./icons/icon-tv.js'), - }, - { - name: 'icon-umb-content', - legacy: true, - hidden: true, - path: () => import('./icons/icon-umb-content.js'), - }, - { - name: 'icon-umb-developer', - legacy: true, - hidden: true, - path: () => import('./icons/icon-umb-developer.js'), - }, - { - name: 'icon-umb-media', - legacy: true, - hidden: true, - path: () => import('./icons/icon-umb-media.js'), - }, - { - name: 'icon-umb-settings', - legacy: true, - hidden: true, - path: () => import('./icons/icon-umb-settings.js'), - }, - { - name: 'icon-umb-users', - legacy: true, - hidden: true, - path: () => import('./icons/icon-umb-users.js'), - }, - { - name: 'icon-umbrella', - path: () => import('./icons/icon-umbrella.js'), - }, - { - name: 'icon-undo', - path: () => import('./icons/icon-undo.js'), - }, - { - name: 'icon-underline', - path: () => import('./icons/icon-underline.js'), - }, - { - name: 'icon-unlink', - path: () => import('./icons/icon-unlink.js'), - }, - { - name: 'icon-unlocked', - path: () => import('./icons/icon-unlocked.js'), - }, - { - name: 'icon-unplug', - path: () => import('./icons/icon-unplug.js'), - }, - { - name: 'icon-untitled', - legacy: true, - hidden: true, - path: () => import('./icons/icon-untitled.js'), - }, - { - name: 'icon-usb-connector', - legacy: true, - hidden: true, - path: () => import('./icons/icon-usb-connector.js'), - }, - { - name: 'icon-usb', - path: () => import('./icons/icon-usb.js'), - }, - { - name: 'icon-user-female', - legacy: true, - hidden: true, - path: () => import('./icons/icon-user-female.js'), - }, - { - name: 'icon-user-females-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-user-females-alt.js'), - }, - { - name: 'icon-user-females', - legacy: true, - hidden: true, - path: () => import('./icons/icon-user-females.js'), - }, - { - name: 'icon-user-glasses', - legacy: true, - hidden: true, - path: () => import('./icons/icon-user-glasses.js'), - }, - { - name: 'icon-user', - path: () => import('./icons/icon-user.js'), - }, - { - name: 'icon-users-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-users-alt.js'), - }, - { - name: 'icon-users', - path: () => import('./icons/icon-users.js'), - }, - { - name: 'icon-utilities', - path: () => import('./icons/icon-utilities.js'), - }, - { - name: 'icon-vcard', - path: () => import('./icons/icon-vcard.js'), - }, - { - name: 'icon-video', - path: () => import('./icons/icon-video.js'), - }, - { - name: 'icon-voice', - path: () => import('./icons/icon-voice.js'), - }, - { - name: 'icon-wall-plug', - path: () => import('./icons/icon-wall-plug.js'), - }, - { - name: 'icon-wallet', - path: () => import('./icons/icon-wallet.js'), - }, - { - name: 'icon-wand', - path: () => import('./icons/icon-wand.js'), - }, - { - name: 'icon-webhook', - path: () => import('./icons/icon-webhook.js'), - }, - { - name: 'icon-weight', - path: () => import('./icons/icon-weight.js'), - }, - { - name: 'icon-width', - path: () => import('./icons/icon-width.js'), - }, - { - name: 'icon-wifi', - path: () => import('./icons/icon-wifi.js'), - }, - { - name: 'icon-window-popin', - path: () => import('./icons/icon-window-popin.js'), - }, - { - name: 'icon-window-popout', - path: () => import('./icons/icon-window-popout.js'), - }, - { - name: 'icon-window-sizes', - path: () => import('./icons/icon-window-sizes.js'), - }, - { - name: 'icon-wine-glass', - path: () => import('./icons/icon-wine-glass.js'), - }, - { - name: 'icon-wrench', - path: () => import('./icons/icon-wrench.js'), - }, - { - name: 'icon-wrong', - path: () => import('./icons/icon-wrong.js'), - }, - { - name: 'icon-zip', - path: () => import('./icons/icon-zip.js'), - }, - { - name: 'icon-zom-out', - legacy: true, - hidden: true, - path: () => import('./icons/icon-zom-out.js'), - }, - { - name: 'icon-zoom-in', - path: () => import('./icons/icon-zoom-in.js'), - }, - { - name: 'icon-zoom-out', - path: () => import('./icons/icon-zoom-out.js'), - }, - { - name: 'icon-star', - path: () => import('./icons/icon-star.js'), - }, - { - name: 'icon-database', - path: () => import('./icons/icon-database.js'), - }, - { - name: 'icon-umb-manifest', - hidden: true, - path: () => import('./icons/icon-umb-manifest.js'), - }, - { - name: 'icon-puzzle-piece', - path: () => import('./icons/icon-puzzle-piece.js'), - }, - { - name: 'icon-document-3d', - path: () => import('./icons/icon-document-3d.js'), - }, - { - name: 'icon-document-medal', - path: () => import('./icons/icon-document-medal.js'), - }, - { - name: 'icon-document-chart-bar', - path: () => import('./icons/icon-document-chart-bar.js'), - }, - { - name: 'icon-document-chart-graph', - path: () => import('./icons/icon-document-chart-graph.js'), - }, - { - name: 'icon-document-html', - path: () => import('./icons/icon-document-html.js'), - }, - { - name: 'icon-document-js', - path: () => import('./icons/icon-document-js.js'), - }, - { - name: 'icon-document-key', - path: () => import('./icons/icon-document-key.js'), - }, - { - name: 'icon-document-search', - path: () => import('./icons/icon-document-search.js'), - }, - { - name: 'icon-document-settings', - path: () => import('./icons/icon-document-settings.js'), - }, - { - name: 'icon-document-spreadsheet', - path: () => import('./icons/icon-document-spreadsheet.js'), - }, - { - name: 'icon-document-command', - path: () => import('./icons/icon-document-command.js'), - }, - { - name: 'icon-document-command', - path: () => import('./icons/icon-document-command.js'), - }, - { - name: 'icon-document-font', - path: () => import('./icons/icon-document-font.js'), - }, - { - name: 'icon-document-user', - path: () => import('./icons/icon-document-user.js'), - }, - { - name: 'icon-document-image', - path: () => import('./icons/icon-document-image.js'), - }, - { - name: 'icon-document-play', - path: () => import('./icons/icon-document-play.js'), - }, - { - name: 'icon-document-play', - path: () => import('./icons/icon-document-play.js'), - }, - { - name: 'icon-shared-value', - path: () => import('./icons/icon-shared-value.js'), - }, - { - name: 'icon-layout-masonry', - path: () => import('./icons/icon-layout-masonry.js'), - }, - { - name: 'icon-layout-grid', - path: () => import('./icons/icon-layout-grid.js'), - }, - { - name: 'icon-layout-list', - path: () => import('./icons/icon-layout-list.js'), - }, - { - name: 'icon-layout-panel-left', - path: () => import('./icons/icon-layout-panel-left.js'), - }, - { - name: 'icon-spray-can', - path: () => import('./icons/icon-spray-can.js'), - }, - { - name: 'icon-swatch-book', - path: () => import('./icons/icon-swatch-book.js'), - }, - { - name: 'icon-shape-cylinder', - path: () => import('./icons/icon-shape-cylinder.js'), - }, - { - name: 'icon-shape-triangle-right', - path: () => import('./icons/icon-shape-triangle-right.js'), - }, - { - name: 'icon-shape-triangle', - path: () => import('./icons/icon-shape-triangle.js'), - }, - { - name: 'icon-shape-circle', - path: () => import('./icons/icon-shape-circle.js'), - }, - { - name: 'icon-shape-square', - path: () => import('./icons/icon-shape-square.js'), - }, - { - name: 'icon-shape-hexagon', - path: () => import('./icons/icon-shape-hexagon.js'), - }, - { - name: 'icon-shape-rectangle-horizontal', - path: () => import('./icons/icon-shape-rectangle-horizontal.js'), - }, - { - name: 'icon-shape-rectangle-vertical', - path: () => import('./icons/icon-shape-rectangle-vertical.js'), - }, - { - name: 'icon-shapes', - path: () => import('./icons/icon-shapes.js'), - }, - { - name: 'icon-layout-dislocated', - path: () => import('./icons/icon-layout-dislocated.js'), - }, - { - name: 'icon-blend', - path: () => import('./icons/icon-blend.js'), - }, - { - name: 'icon-land-plot', - path: () => import('./icons/icon-land-plot.js'), - }, - { - name: 'icon-facebook', - path: () => import('./icons/icon-facebook.js'), - }, - { - name: 'icon-gitbook', - path: () => import('./icons/icon-gitbook.js'), - }, - { - name: 'icon-github', - path: () => import('./icons/icon-github.js'), - }, - { - name: 'icon-gitlab', - path: () => import('./icons/icon-gitlab.js'), - }, - { - name: 'icon-google', - path: () => import('./icons/icon-google.js'), - }, - { - name: 'icon-mastodon', - path: () => import('./icons/icon-mastodon.js'), - }, - { - name: 'icon-twitter-x', - path: () => import('./icons/icon-twitter-x.js'), - }, - { - name: 'icon-art-easel', - legacy: true, - hidden: true, - path: () => import('./icons/icon-art-easel.js'), - }, - { - name: 'icon-article', - legacy: true, - hidden: true, - path: () => import('./icons/icon-article.js'), - }, - { - name: 'icon-auction-hammer', - legacy: true, - hidden: true, - path: () => import('./icons/icon-auction-hammer.js'), - }, - { - name: 'icon-badge-count', - legacy: true, - hidden: true, - path: () => import('./icons/icon-badge-count.js'), - }, - { - name: 'icon-band-aid', - legacy: true, - hidden: true, - path: () => import('./icons/icon-band-aid.js'), - }, - { - name: 'icon-baby-stroller', - legacy: true, - hidden: true, - path: () => import('./icons/icon-baby-stroller.js'), - }, - { - name: 'icon-bill-dollar', - legacy: true, - hidden: true, - path: () => import('./icons/icon-bill-dollar.js'), - }, - { - name: 'icon-bill-euro', - legacy: true, - hidden: true, - path: () => import('./icons/icon-bill-euro.js'), - }, - { - name: 'icon-bill-pound', - legacy: true, - hidden: true, - path: () => import('./icons/icon-bill-pound.js'), - }, - { - name: 'icon-bill-yen', - legacy: true, - hidden: true, - path: () => import('./icons/icon-bill-yen.js'), - }, - { - name: 'icon-bill', - legacy: true, - hidden: true, - path: () => import('./icons/icon-bill.js'), - }, - { - name: 'icon-billboard', - legacy: true, - hidden: true, - path: () => import('./icons/icon-billboard.js'), - }, - { - name: 'icon-bills-dollar', - legacy: true, - hidden: true, - path: () => import('./icons/icon-bills-dollar.js'), - }, - { - name: 'icon-bills-euro', - legacy: true, - hidden: true, - path: () => import('./icons/icon-bills-euro.js'), - }, - { - name: 'icon-bills-pound', - legacy: true, - hidden: true, - path: () => import('./icons/icon-bills-pound.js'), - }, - { - name: 'icon-bills-yen', - legacy: true, - hidden: true, - path: () => import('./icons/icon-bills-yen.js'), - }, - { - name: 'icon-bills', - legacy: true, - hidden: true, - path: () => import('./icons/icon-bills.js'), - }, - { - name: 'icon-blueprint', - legacy: true, - hidden: true, - path: () => import('./icons/icon-blueprint.js'), - }, - { - name: 'icon-bomb', - legacy: true, - hidden: true, - path: () => import('./icons/icon-bomb.js'), - }, - { - name: 'icon-cash-register', - legacy: true, - hidden: true, - path: () => import('./icons/icon-cash-register.js'), - }, - { - name: 'icon-checkbox-dotted-active', - legacy: true, - hidden: true, - path: () => import('./icons/icon-checkbox-dotted-active.js'), - }, - { - name: 'icon-chess', - legacy: true, - hidden: true, - path: () => import('./icons/icon-chess.js'), - }, - { - name: 'icon-circus', - legacy: true, - hidden: true, - path: () => import('./icons/icon-circus.js'), - }, - { - name: 'icon-clothes-hanger', - legacy: true, - hidden: true, - path: () => import('./icons/icon-clothes-hanger.js'), - }, - { - name: 'icon-coin', - legacy: true, - hidden: true, - path: () => import('./icons/icon-coin.js'), - }, - { - name: 'icon-coins-dollar-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-coins-dollar-alt.js'), - }, - { - name: 'icon-coins-dollar', - legacy: true, - hidden: true, - path: () => import('./icons/icon-coins-dollar.js'), - }, - { - name: 'icon-coins-euro-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-coins-euro-alt.js'), - }, - { - name: 'icon-coins-euro', - legacy: true, - hidden: true, - path: () => import('./icons/icon-coins-euro.js'), - }, - { - name: 'icon-coins-pound-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-coins-pound-alt.js'), - }, - { - name: 'icon-coins-pound', - legacy: true, - hidden: true, - path: () => import('./icons/icon-coins-pound.js'), - }, - { - name: 'icon-coins-yen-alt', - legacy: true, - hidden: true, - path: () => import('./icons/icon-coins-yen-alt.js'), - }, - { - name: 'icon-coins-yen', - legacy: true, - hidden: true, - path: () => import('./icons/icon-coins-yen.js'), - }, - { - name: 'icon-comb', - legacy: true, - hidden: true, - path: () => import('./icons/icon-comb.js'), - }, - { - name: 'icon-desk', - legacy: true, - hidden: true, - path: () => import('./icons/icon-desk.js'), - }, - { - name: 'icon-dollar-bag', - legacy: true, - hidden: true, - path: () => import('./icons/icon-dollar-bag.js'), - }, - { - name: 'icon-eject', - legacy: true, - hidden: true, - path: () => import('./icons/icon-eject.js'), - }, - { - name: 'icon-euro-bag', - legacy: true, - hidden: true, - path: () => import('./icons/icon-euro-bag.js'), - }, - { - name: 'icon-female-symbol', - legacy: true, - hidden: true, - path: () => import('./icons/icon-female-symbol.js'), - }, - { - name: 'icon-firewall', - legacy: true, - hidden: true, - path: () => import('./icons/icon-firewall.js'), - }, - { - name: 'icon-folder-open', - legacy: true, - hidden: true, - path: () => import('./icons/icon-folder-open.js'), - }, - { - name: 'icon-folder-outline', - legacy: true, - hidden: true, - path: () => import('./icons/icon-folder-outline.js'), - }, - { - name: 'icon-handprint', - legacy: true, - hidden: true, - path: () => import('./icons/icon-handprint.js'), - }, - { - name: 'icon-hat', - legacy: true, - hidden: true, - path: () => import('./icons/icon-hat.js'), - }, - { - name: 'icon-hd', - legacy: true, - hidden: true, - path: () => import('./icons/icon-hd.js'), - }, - { - name: 'icon-inactive-line', - legacy: true, - hidden: true, - path: () => import('./icons/icon-inactive-line.js'), - }, - { - name: 'icon-keychain', - legacy: true, - hidden: true, - path: () => import('./icons/icon-keychain.js'), - }, - { - name: 'icon-keyhole', - legacy: true, - hidden: true, - path: () => import('./icons/icon-keyhole.js'), - }, - { - name: 'icon-linkedin', - legacy: true, - hidden: true, - path: () => import('./icons/icon-linkedin.js'), - }, - { - name: 'icon-linux-tux', - legacy: true, - hidden: true, - path: () => import('./icons/icon-linux-tux.js'), - }, - { - name: 'icon-male-and-female', - legacy: true, - hidden: true, - path: () => import('./icons/icon-male-and-female.js'), - }, - { - name: 'icon-male-symbol', - legacy: true, - hidden: true, - path: () => import('./icons/icon-male-symbol.js'), - }, - { - name: 'icon-molecular-network', - legacy: true, - hidden: true, - path: () => import('./icons/icon-molecular-network.js'), - }, - { - name: 'icon-molecular', - legacy: true, - hidden: true, - path: () => import('./icons/icon-molecular.js'), - }, - { - name: 'icon-umbraco', - path: () => import('./icons/icon-umbraco.js'), - }, - { - name: 'icon-azure', - legacy: true, - hidden: true, - path: () => import('./icons/icon-azure.js'), - }, - { - name: 'icon-microsoft', - legacy: true, - hidden: true, - path: () => import('./icons/icon-microsoft.js'), - }, - { - name: 'icon-os-x', - legacy: true, - hidden: true, - path: () => import('./icons/icon-os-x.js'), - }, - { - name: 'icon-pants', - legacy: true, - hidden: true, - path: () => import('./icons/icon-pants.js'), - }, - { - name: 'icon-parachute-drop', - legacy: true, - hidden: true, - path: () => import('./icons/icon-parachute-drop.js'), - }, - { - name: 'icon-parental-control', - legacy: true, - hidden: true, - path: () => import('./icons/icon-parental-control.js'), - }, - { - name: 'icon-path', - legacy: true, - hidden: true, - path: () => import('./icons/icon-path.js'), - }, - { - name: 'icon-piracy', - legacy: true, - hidden: true, - path: () => import('./icons/icon-piracy.js'), - }, - { - name: 'icon-poker-chip', - legacy: true, - hidden: true, - path: () => import('./icons/icon-poker-chip.js'), - }, - { - name: 'icon-pound-bag', - legacy: true, - hidden: true, - path: () => import('./icons/icon-pound-bag.js'), - }, - { - name: 'icon-receipt-dollar', - legacy: true, - hidden: true, - path: () => import('./icons/icon-receipt-dollar.js'), - }, - { - name: 'icon-receipt-euro', - legacy: true, - hidden: true, - path: () => import('./icons/icon-receipt-euro.js'), - }, - { - name: 'icon-receipt-pound', - legacy: true, - hidden: true, - path: () => import('./icons/icon-receipt-pound.js'), - }, - { - name: 'icon-receipt-yen', - legacy: true, - hidden: true, - path: () => import('./icons/icon-receipt-yen.js'), - }, - { - name: 'icon-road', - legacy: true, - hidden: true, - path: () => import('./icons/icon-road.js'), - }, - { - name: 'icon-safe', - legacy: true, - hidden: true, - path: () => import('./icons/icon-safe.js'), - }, - { - name: 'icon-safedial', - legacy: true, - hidden: true, - path: () => import('./icons/icon-safedial.js'), - }, - { - name: 'icon-sandbox-toys', - legacy: true, - hidden: true, - path: () => import('./icons/icon-sandbox-toys.js'), - }, - { - name: 'icon-security-camera', - legacy: true, - hidden: true, - path: () => import('./icons/icon-security-camera.js'), - }, - { - name: 'icon-settings-alt-2', - legacy: true, - hidden: true, - path: () => import('./icons/icon-settings-alt-2.js'), - }, - { - name: 'icon-share-alt-2', - legacy: true, - hidden: true, - path: () => import('./icons/icon-share-alt-2.js'), - }, - { - name: 'icon-shorts', - legacy: true, - hidden: true, - path: () => import('./icons/icon-shorts.js'), - }, - { - name: 'icon-simcard', - legacy: true, - hidden: true, - path: () => import('./icons/icon-simcard.js'), - }, - { - name: 'icon-tab', - legacy: true, - hidden: true, - path: () => import('./icons/icon-tab.js'), - }, - { - name: 'icon-tactics', - legacy: true, - hidden: true, - path: () => import('./icons/icon-tactics.js'), - }, - { - name: 'icon-theif', - legacy: true, - hidden: true, - path: () => import('./icons/icon-theif.js'), - }, - { - name: 'icon-thought-bubble', - legacy: true, - hidden: true, - path: () => import('./icons/icon-thought-bubble.js'), - }, - { - name: 'icon-twitter', - legacy: true, - hidden: true, - path: () => import('./icons/icon-twitter.js'), - }, - { - name: 'icon-umb-contour', - legacy: true, - hidden: true, - path: () => import('./icons/icon-umb-contour.js'), - }, - { - name: 'icon-umb-deploy', - legacy: true, - hidden: true, - path: () => import('./icons/icon-umb-deploy.js'), - }, - { - name: 'icon-umb-members', - legacy: true, - hidden: true, - path: () => import('./icons/icon-umb-members.js'), - }, - { - name: 'icon-universal', - legacy: true, - hidden: true, - path: () => import('./icons/icon-universal.js'), - }, - { - name: 'icon-war', - legacy: true, - hidden: true, - path: () => import('./icons/icon-war.js'), - }, - { - name: 'icon-windows', - legacy: true, - hidden: true, - path: () => import('./icons/icon-windows.js'), - }, - { - name: 'icon-yen-bag', - legacy: true, - hidden: true, - path: () => import('./icons/icon-yen-bag.js'), - }, -]; +export default [{ +name: "icon-activity", +path: () => import("./icons/icon-activity.js"), +},{ +name: "icon-add", +path: () => import("./icons/icon-add.js"), +},{ +name: "icon-addressbook", +path: () => import("./icons/icon-addressbook.js"), +},{ +name: "icon-alarm-clock", +path: () => import("./icons/icon-alarm-clock.js"), +},{ +name: "icon-alert-alt", +path: () => import("./icons/icon-alert-alt.js"), +},{ +name: "icon-alert", +path: () => import("./icons/icon-alert.js"), +},{ +name: "icon-alt", +path: () => import("./icons/icon-alt.js"), +},{ +name: "icon-anchor", +path: () => import("./icons/icon-anchor.js"), +},{ +name: "icon-app", +path: () => import("./icons/icon-app.js"), +},{ +name: "icon-application-error", +path: () => import("./icons/icon-application-error.js"), +},{ +name: "icon-application-window-alt", +path: () => import("./icons/icon-application-window-alt.js"), +},{ +name: "icon-application-window", +path: () => import("./icons/icon-application-window.js"), +},{ +name: "icon-arrivals", +path: () => import("./icons/icon-arrivals.js"), +},{ +name: "icon-arrow-down", +path: () => import("./icons/icon-arrow-down.js"), +},{ +name: "icon-arrow-left", +path: () => import("./icons/icon-arrow-left.js"), +},{ +name: "icon-arrow-right", +path: () => import("./icons/icon-arrow-right.js"), +},{ +name: "icon-arrow-up", +path: () => import("./icons/icon-arrow-up.js"), +},{ +name: "icon-attachment", +path: () => import("./icons/icon-attachment.js"), +},{ +name: "icon-audio-lines", +path: () => import("./icons/icon-audio-lines.js"), +},{ +name: "icon-autofill", +path: () => import("./icons/icon-autofill.js"), +},{ +name: "icon-award", +path: () => import("./icons/icon-award.js"), +},{ +name: "icon-axis-rotation-2", +path: () => import("./icons/icon-axis-rotation-2.js"), +},{ +name: "icon-axis-rotation-3", +path: () => import("./icons/icon-axis-rotation-3.js"), +},{ +name: "icon-axis-rotation", +path: () => import("./icons/icon-axis-rotation.js"), +},{ +name: "icon-backspace", +path: () => import("./icons/icon-backspace.js"), +},{ +name: "icon-badge-add", +path: () => import("./icons/icon-badge-add.js"), +},{ +name: "icon-badge-remove", +path: () => import("./icons/icon-badge-remove.js"), +},{ +name: "icon-badge-restricted", +legacy: true, +hidden: true, +path: () => import("./icons/icon-badge-restricted.js"), +},{ +name: "icon-ball", +path: () => import("./icons/icon-ball.js"), +},{ +name: "icon-bar-chart", +path: () => import("./icons/icon-bar-chart.js"), +},{ +name: "icon-barcode", +path: () => import("./icons/icon-barcode.js"), +},{ +name: "icon-bars", +path: () => import("./icons/icon-bars.js"), +},{ +name: "icon-battery-full", +path: () => import("./icons/icon-battery-full.js"), +},{ +name: "icon-battery-low", +path: () => import("./icons/icon-battery-low.js"), +},{ +name: "icon-beer-glass", +path: () => import("./icons/icon-beer-glass.js"), +},{ +name: "icon-bell-off", +path: () => import("./icons/icon-bell-off.js"), +},{ +name: "icon-bell", +path: () => import("./icons/icon-bell.js"), +},{ +name: "icon-binarycode", +path: () => import("./icons/icon-binarycode.js"), +},{ +name: "icon-binoculars", +legacy: true, +hidden: true, +path: () => import("./icons/icon-binoculars.js"), +},{ +name: "icon-bird", +path: () => import("./icons/icon-bird.js"), +},{ +name: "icon-birthday-cake", +path: () => import("./icons/icon-birthday-cake.js"), +},{ +name: "icon-block", +path: () => import("./icons/icon-block.js"), +},{ +name: "icon-blockquote", +path: () => import("./icons/icon-blockquote.js"), +},{ +name: "icon-bluetooth", +path: () => import("./icons/icon-bluetooth.js"), +},{ +name: "icon-boat-shipping", +path: () => import("./icons/icon-boat-shipping.js"), +},{ +name: "icon-bold", +path: () => import("./icons/icon-bold.js"), +},{ +name: "icon-bones", +path: () => import("./icons/icon-bones.js"), +},{ +name: "icon-book-alt-2", +path: () => import("./icons/icon-book-alt-2.js"), +},{ +name: "icon-book-alt", +path: () => import("./icons/icon-book-alt.js"), +},{ +name: "icon-book", +path: () => import("./icons/icon-book.js"), +},{ +name: "icon-bookmark", +path: () => import("./icons/icon-bookmark.js"), +},{ +name: "icon-books", +path: () => import("./icons/icon-books.js"), +},{ +name: "icon-box-alt", +path: () => import("./icons/icon-box-alt.js"), +},{ +name: "icon-box-open", +path: () => import("./icons/icon-box-open.js"), +},{ +name: "icon-box", +path: () => import("./icons/icon-box.js"), +},{ +name: "icon-brackets", +path: () => import("./icons/icon-brackets.js"), +},{ +name: "icon-brick", +path: () => import("./icons/icon-brick.js"), +},{ +name: "icon-briefcase", +path: () => import("./icons/icon-briefcase.js"), +},{ +name: "icon-browser-window", +path: () => import("./icons/icon-browser-window.js"), +},{ +name: "icon-brush-alt-2", +path: () => import("./icons/icon-brush-alt-2.js"), +},{ +name: "icon-brush-alt", +path: () => import("./icons/icon-brush-alt.js"), +},{ +name: "icon-brush", +path: () => import("./icons/icon-brush.js"), +},{ +name: "icon-bug", +path: () => import("./icons/icon-bug.js"), +},{ +name: "icon-bulleted-list", +path: () => import("./icons/icon-bulleted-list.js"), +},{ +name: "icon-burn", +path: () => import("./icons/icon-burn.js"), +},{ +name: "icon-bus", +path: () => import("./icons/icon-bus.js"), +},{ +name: "icon-calculator", +path: () => import("./icons/icon-calculator.js"), +},{ +name: "icon-calendar-alt", +path: () => import("./icons/icon-calendar-alt.js"), +},{ +name: "icon-calendar", +path: () => import("./icons/icon-calendar.js"), +},{ +name: "icon-camcorder", +legacy: true, +hidden: true, +path: () => import("./icons/icon-camcorder.js"), +},{ +name: "icon-camera-roll", +path: () => import("./icons/icon-camera-roll.js"), +},{ +name: "icon-candy", +path: () => import("./icons/icon-candy.js"), +},{ +name: "icon-caps-lock", +path: () => import("./icons/icon-caps-lock.js"), +},{ +name: "icon-car", +path: () => import("./icons/icon-car.js"), +},{ +name: "icon-categories", +path: () => import("./icons/icon-categories.js"), +},{ +name: "icon-certificate", +path: () => import("./icons/icon-certificate.js"), +},{ +name: "icon-chart-curve", +path: () => import("./icons/icon-chart-curve.js"), +},{ +name: "icon-chart", +path: () => import("./icons/icon-chart.js"), +},{ +name: "icon-chat-active", +legacy: true, +hidden: true, +path: () => import("./icons/icon-chat-active.js"), +},{ +name: "icon-chat", +path: () => import("./icons/icon-chat.js"), +},{ +name: "icon-check", +path: () => import("./icons/icon-check.js"), +},{ +name: "icon-checkbox-dotted", +path: () => import("./icons/icon-checkbox-dotted.js"), +},{ +name: "icon-checkbox-empty", +legacy: true, +hidden: true, +path: () => import("./icons/icon-checkbox-empty.js"), +},{ +name: "icon-checkbox", +path: () => import("./icons/icon-checkbox.js"), +},{ +name: "icon-chip-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-chip-alt.js"), +},{ +name: "icon-chip", +path: () => import("./icons/icon-chip.js"), +},{ +name: "icon-cinema", +path: () => import("./icons/icon-cinema.js"), +},{ +name: "icon-circle-dotted-active", +path: () => import("./icons/icon-circle-dotted-active.js"), +},{ +name: "icon-circle-dotted", +path: () => import("./icons/icon-circle-dotted.js"), +},{ +name: "icon-circuits", +path: () => import("./icons/icon-circuits.js"), +},{ +name: "icon-clear-formatting", +path: () => import("./icons/icon-clear-formatting.js"), +},{ +name: "icon-client", +legacy: true, +hidden: true, +path: () => import("./icons/icon-client.js"), +},{ +name: "icon-clipboard", +path: () => import("./icons/icon-clipboard.js"), +},{ +name: "icon-clipboard-copy", +path: () => import("./icons/icon-clipboard-copy.js"), +},{ +name: "icon-clipboard-entry", +path: () => import("./icons/icon-clipboard-entry.js"), +},{ +name: "icon-clipboard-paste", +path: () => import("./icons/icon-clipboard-paste.js"), +},{ +name: "icon-cloud-drive", +path: () => import("./icons/icon-cloud-drive.js"), +},{ +name: "icon-cloud-upload", +path: () => import("./icons/icon-cloud-upload.js"), +},{ +name: "icon-cloud", +path: () => import("./icons/icon-cloud.js"), +},{ +name: "icon-cloudy", +path: () => import("./icons/icon-cloudy.js"), +},{ +name: "icon-clubs", +path: () => import("./icons/icon-clubs.js"), +},{ +name: "icon-cocktail", +path: () => import("./icons/icon-cocktail.js"), +},{ +name: "icon-code", +path: () => import("./icons/icon-code.js"), +},{ +name: "icon-code-xml", +path: () => import("./icons/icon-code-xml.js"), +},{ +name: "icon-coffee", +path: () => import("./icons/icon-coffee.js"), +},{ +name: "icon-coin-dollar", +path: () => import("./icons/icon-coin-dollar.js"), +},{ +name: "icon-coin-euro", +path: () => import("./icons/icon-coin-euro.js"), +},{ +name: "icon-coin-pound", +path: () => import("./icons/icon-coin-pound.js"), +},{ +name: "icon-coin-yen", +path: () => import("./icons/icon-coin-yen.js"), +},{ +name: "icon-coins-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-coins-alt.js"), +},{ +name: "icon-coins", +path: () => import("./icons/icon-coins.js"), +},{ +name: "icon-color-bucket", +path: () => import("./icons/icon-color-bucket.js"), +},{ +name: "icon-colorpicker", +path: () => import("./icons/icon-colorpicker.js"), +},{ +name: "icon-columns", +path: () => import("./icons/icon-columns.js"), +},{ +name: "icon-columns-2", +path: () => import("./icons/icon-columns-2.js"), +},{ +name: "icon-columns-3", +path: () => import("./icons/icon-columns-3.js"), +},{ +name: "icon-columns-4", +path: () => import("./icons/icon-columns-4.js"), +},{ +name: "icon-rows-2", +path: () => import("./icons/icon-rows-2.js"), +},{ +name: "icon-rows-3", +path: () => import("./icons/icon-rows-3.js"), +},{ +name: "icon-rows-4", +path: () => import("./icons/icon-rows-4.js"), +},{ +name: "icon-grid-2", +path: () => import("./icons/icon-grid-2.js"), +},{ +name: "icon-grid-3", +path: () => import("./icons/icon-grid-3.js"), +},{ +name: "icon-combination-lock-open", +path: () => import("./icons/icon-combination-lock-open.js"), +},{ +name: "icon-combination-lock", +path: () => import("./icons/icon-combination-lock.js"), +},{ +name: "icon-command", +path: () => import("./icons/icon-command.js"), +},{ +name: "icon-company", +path: () => import("./icons/icon-company.js"), +},{ +name: "icon-compress", +path: () => import("./icons/icon-compress.js"), +},{ +name: "icon-connection", +path: () => import("./icons/icon-connection.js"), +},{ +name: "icon-console", +path: () => import("./icons/icon-console.js"), +},{ +name: "icon-contrast", +path: () => import("./icons/icon-contrast.js"), +},{ +name: "icon-conversation-alt", +path: () => import("./icons/icon-conversation-alt.js"), +},{ +name: "icon-conversation", +legacy: true, +hidden: true, +path: () => import("./icons/icon-conversation.js"), +},{ +name: "icon-coverflow", +path: () => import("./icons/icon-coverflow.js"), +},{ +name: "icon-credit-card-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-credit-card-alt.js"), +},{ +name: "icon-credit-card", +path: () => import("./icons/icon-credit-card.js"), +},{ +name: "icon-crop", +path: () => import("./icons/icon-crop.js"), +},{ +name: "icon-crosshair", +path: () => import("./icons/icon-crosshair.js"), +},{ +name: "icon-crown-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-crown-alt.js"), +},{ +name: "icon-crown", +path: () => import("./icons/icon-crown.js"), +},{ +name: "icon-cupcake", +legacy: true, +hidden: true, +path: () => import("./icons/icon-cupcake.js"), +},{ +name: "icon-curve", +path: () => import("./icons/icon-curve.js"), +},{ +name: "icon-cut", +path: () => import("./icons/icon-cut.js"), +},{ +name: "icon-dashboard", +path: () => import("./icons/icon-dashboard.js"), +},{ +name: "icon-defrag", +path: () => import("./icons/icon-defrag.js"), +},{ +name: "icon-delete-key", +path: () => import("./icons/icon-delete-key.js"), +},{ +name: "icon-delete", +path: () => import("./icons/icon-delete.js"), +},{ +name: "icon-departure", +path: () => import("./icons/icon-departure.js"), +},{ +name: "icon-desktop", +legacy: true, +hidden: true, +path: () => import("./icons/icon-desktop.js"), +},{ +name: "icon-diagnostics", +path: () => import("./icons/icon-diagnostics.js"), +},{ +name: "icon-diagonal-arrow-alt", +path: () => import("./icons/icon-diagonal-arrow-alt.js"), +},{ +name: "icon-diagonal-arrow", +path: () => import("./icons/icon-diagonal-arrow.js"), +},{ +name: "icon-diamond", +path: () => import("./icons/icon-diamond.js"), +},{ +name: "icon-diamonds", +path: () => import("./icons/icon-diamonds.js"), +},{ +name: "icon-dice", +path: () => import("./icons/icon-dice.js"), +},{ +name: "icon-diploma-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-diploma-alt.js"), +},{ +name: "icon-diploma", +path: () => import("./icons/icon-diploma.js"), +},{ +name: "icon-directions-alt", +path: () => import("./icons/icon-directions-alt.js"), +},{ +name: "icon-directions", +path: () => import("./icons/icon-directions.js"), +},{ +name: "icon-disc", +path: () => import("./icons/icon-disc.js"), +},{ +name: "icon-disk-image", +path: () => import("./icons/icon-disk-image.js"), +},{ +name: "icon-display", +path: () => import("./icons/icon-display.js"), +},{ +name: "icon-dna", +path: () => import("./icons/icon-dna.js"), +},{ +name: "icon-dock-connector", +path: () => import("./icons/icon-dock-connector.js"), +},{ +name: "icon-document-dashed-line", +legacy: true, +hidden: true, +path: () => import("./icons/icon-document-dashed-line.js"), +},{ +name: "icon-document", +path: () => import("./icons/icon-document.js"), +},{ +name: "icon-documents", +path: () => import("./icons/icon-documents.js"), +},{ +name: "icon-donate", +legacy: true, +hidden: true, +path: () => import("./icons/icon-donate.js"), +},{ +name: "icon-door-open-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-door-open-alt.js"), +},{ +name: "icon-door-open", +path: () => import("./icons/icon-door-open.js"), +},{ +name: "icon-download-alt", +path: () => import("./icons/icon-download-alt.js"), +},{ +name: "icon-download", +path: () => import("./icons/icon-download.js"), +},{ +name: "icon-drop", +path: () => import("./icons/icon-drop.js"), +},{ +name: "icon-eco", +path: () => import("./icons/icon-eco.js"), +},{ +name: "icon-economy", +legacy: true, +hidden: true, +path: () => import("./icons/icon-economy.js"), +},{ +name: "icon-edit", +path: () => import("./icons/icon-edit.js"), +},{ +name: "icon-embed", +path: () => import("./icons/icon-embed.js"), +},{ +name: "icon-employee", +legacy: true, +hidden: true, +path: () => import("./icons/icon-employee.js"), +},{ +name: "icon-energy-saving-bulb", +path: () => import("./icons/icon-energy-saving-bulb.js"), +},{ +name: "icon-enter", +path: () => import("./icons/icon-enter.js"), +},{ +name: "icon-equalizer", +path: () => import("./icons/icon-equalizer.js"), +},{ +name: "icon-escape", +path: () => import("./icons/icon-escape.js"), +},{ +name: "icon-ethernet", +path: () => import("./icons/icon-ethernet.js"), +},{ +name: "icon-eye", +path: () => import("./icons/icon-eye.js"), +},{ +name: "icon-exit-fullscreen", +path: () => import("./icons/icon-exit-fullscreen.js"), +},{ +name: "icon-facebook-like", +path: () => import("./icons/icon-facebook-like.js"), +},{ +name: "icon-factory", +path: () => import("./icons/icon-factory.js"), +},{ +name: "icon-favorite", +path: () => import("./icons/icon-favorite.js"), +},{ +name: "icon-file-cabinet", +path: () => import("./icons/icon-file-cabinet.js"), +},{ +name: "icon-files", +path: () => import("./icons/icon-files.js"), +},{ +name: "icon-filter-arrows", +path: () => import("./icons/icon-filter-arrows.js"), +},{ +name: "icon-filter", +path: () => import("./icons/icon-filter.js"), +},{ +name: "icon-fingerprint", +path: () => import("./icons/icon-fingerprint.js"), +},{ +name: "icon-fire", +path: () => import("./icons/icon-fire.js"), +},{ +name: "icon-firewire", +legacy: true, +hidden: true, +path: () => import("./icons/icon-firewire.js"), +},{ +name: "icon-flag-alt", +path: () => import("./icons/icon-flag-alt.js"), +},{ +name: "icon-flag", +path: () => import("./icons/icon-flag.js"), +},{ +name: "icon-flash", +path: () => import("./icons/icon-flash.js"), +},{ +name: "icon-flashlight", +path: () => import("./icons/icon-flashlight.js"), +},{ +name: "icon-flowerpot", +path: () => import("./icons/icon-flowerpot.js"), +},{ +name: "icon-folder", +path: () => import("./icons/icon-folder.js"), +},{ +name: "icon-folders", +path: () => import("./icons/icon-folders.js"), +},{ +name: "icon-font", +path: () => import("./icons/icon-font.js"), +},{ +name: "icon-food", +path: () => import("./icons/icon-food.js"), +},{ +name: "icon-footprints", +path: () => import("./icons/icon-footprints.js"), +},{ +name: "icon-forking", +path: () => import("./icons/icon-forking.js"), +},{ +name: "icon-frame-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-frame-alt.js"), +},{ +name: "icon-frame", +path: () => import("./icons/icon-frame.js"), +},{ +name: "icon-fullscreen-alt", +path: () => import("./icons/icon-fullscreen-alt.js"), +},{ +name: "icon-fullscreen", +path: () => import("./icons/icon-fullscreen.js"), +},{ +name: "icon-game", +path: () => import("./icons/icon-game.js"), +},{ +name: "icon-geometry", +legacy: true, +hidden: true, +path: () => import("./icons/icon-geometry.js"), +},{ +name: "icon-gift", +path: () => import("./icons/icon-gift.js"), +},{ +name: "icon-glasses", +path: () => import("./icons/icon-glasses.js"), +},{ +name: "icon-globe-alt", +path: () => import("./icons/icon-globe-alt.js"), +},{ +name: "icon-globe-asia", +legacy: true, +hidden: true, +path: () => import("./icons/icon-globe-asia.js"), +},{ +name: "icon-globe-europe-africa", +legacy: true, +hidden: true, +path: () => import("./icons/icon-globe-europe-africa.js"), +},{ +name: "icon-globe-inverted-america", +legacy: true, +hidden: true, +path: () => import("./icons/icon-globe-inverted-america.js"), +},{ +name: "icon-globe-inverted-asia", +legacy: true, +hidden: true, +path: () => import("./icons/icon-globe-inverted-asia.js"), +},{ +name: "icon-globe-inverted-europe-africa", +legacy: true, +hidden: true, +path: () => import("./icons/icon-globe-inverted-europe-africa.js"), +},{ +name: "icon-globe", +path: () => import("./icons/icon-globe.js"), +},{ +name: "icon-gps", +path: () => import("./icons/icon-gps.js"), +},{ +name: "icon-graduate", +path: () => import("./icons/icon-graduate.js"), +},{ +name: "icon-grid", +path: () => import("./icons/icon-grid.js"), +},{ +name: "icon-grip", +hidden: true, +path: () => import("./icons/icon-grip.js"), +},{ +name: "icon-hammer", +path: () => import("./icons/icon-hammer.js"), +},{ +name: "icon-hand-active-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-hand-active-alt.js"), +},{ +name: "icon-hand-active", +path: () => import("./icons/icon-hand-active.js"), +},{ +name: "icon-hand-pointer-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-hand-pointer-alt.js"), +},{ +name: "icon-hand-pointer", +path: () => import("./icons/icon-hand-pointer.js"), +},{ +name: "icon-handshake", +path: () => import("./icons/icon-handshake.js"), +},{ +name: "icon-handtool-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-handtool-alt.js"), +},{ +name: "icon-handtool", +path: () => import("./icons/icon-handtool.js"), +},{ +name: "icon-hard-drive-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-hard-drive-alt.js"), +},{ +name: "icon-hard-drive", +legacy: true, +hidden: true, +path: () => import("./icons/icon-hard-drive.js"), +},{ +name: "icon-heading-1", +path: () => import("./icons/icon-heading-1.js"), +},{ +name: "icon-heading-2", +path: () => import("./icons/icon-heading-2.js"), +},{ +name: "icon-heading-3", +path: () => import("./icons/icon-heading-3.js"), +},{ +name: "icon-heading-4", +path: () => import("./icons/icon-heading-4.js"), +},{ +name: "icon-headphones", +path: () => import("./icons/icon-headphones.js"), +},{ +name: "icon-headset", +legacy: true, +hidden: true, +path: () => import("./icons/icon-headset.js"), +},{ +name: "icon-hearts", +path: () => import("./icons/icon-hearts.js"), +},{ +name: "icon-height", +path: () => import("./icons/icon-height.js"), +},{ +name: "icon-help-alt", +path: () => import("./icons/icon-help-alt.js"), +},{ +name: "icon-help", +path: () => import("./icons/icon-help.js"), +},{ +name: "icon-history", +path: () => import("./icons/icon-history.js"), +},{ +name: "icon-home", +path: () => import("./icons/icon-home.js"), +},{ +name: "icon-horizontal-rule", +path: () => import("./icons/icon-horizontal-rule.js"), +},{ +name: "icon-hourglass", +path: () => import("./icons/icon-hourglass.js"), +},{ +name: "icon-imac", +legacy: true, +hidden: true, +path: () => import("./icons/icon-imac.js"), +},{ +name: "icon-image-up", +path: () => import("./icons/icon-image-up.js"), +},{ +name: "icon-inbox-full", +legacy: true, +hidden: true, +path: () => import("./icons/icon-inbox-full.js"), +},{ +name: "icon-inbox", +path: () => import("./icons/icon-inbox.js"), +},{ +name: "icon-indent", +path: () => import("./icons/icon-indent.js"), +},{ +name: "icon-infinity", +path: () => import("./icons/icon-infinity.js"), +},{ +name: "icon-info", +path: () => import("./icons/icon-info.js"), +},{ +name: "icon-invoice", +legacy: true, +hidden: true, +path: () => import("./icons/icon-invoice.js"), +},{ +name: "icon-ipad", +legacy: true, +hidden: true, +path: () => import("./icons/icon-ipad.js"), +},{ +name: "icon-iphone", +legacy: true, +hidden: true, +path: () => import("./icons/icon-iphone.js"), +},{ +name: "icon-italic", +path: () => import("./icons/icon-italic.js"), +},{ +name: "icon-item-arrangement", +legacy: true, +hidden: true, +path: () => import("./icons/icon-item-arrangement.js"), +},{ +name: "icon-junk", +path: () => import("./icons/icon-junk.js"), +},{ +name: "icon-key", +path: () => import("./icons/icon-key.js"), +},{ +name: "icon-keyboard", +path: () => import("./icons/icon-keyboard.js"), +},{ +name: "icon-lab", +path: () => import("./icons/icon-lab.js"), +},{ +name: "icon-laptop", +path: () => import("./icons/icon-laptop.js"), +},{ +name: "icon-layers-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-layers-alt.js"), +},{ +name: "icon-layers", +path: () => import("./icons/icon-layers.js"), +},{ +name: "icon-layout", +path: () => import("./icons/icon-layout.js"), +},{ +name: "icon-left-double-arrow", +path: () => import("./icons/icon-left-double-arrow.js"), +},{ +name: "icon-legal", +path: () => import("./icons/icon-legal.js"), +},{ +name: "icon-lense", +legacy: true, +hidden: true, +path: () => import("./icons/icon-lense.js"), +},{ +name: "icon-library", +path: () => import("./icons/icon-library.js"), +},{ +name: "icon-light-down", +path: () => import("./icons/icon-light-down.js"), +},{ +name: "icon-light-up", +path: () => import("./icons/icon-light-up.js"), +},{ +name: "icon-lightbulb-active", +path: () => import("./icons/icon-lightbulb-active.js"), +},{ +name: "icon-lightbulb", +legacy: true, +hidden: true, +path: () => import("./icons/icon-lightbulb.js"), +},{ +name: "icon-lightning", +path: () => import("./icons/icon-lightning.js"), +},{ +name: "icon-link", +path: () => import("./icons/icon-link.js"), +},{ +name: "icon-list", +path: () => import("./icons/icon-list.js"), +},{ +name: "icon-load", +legacy: true, +hidden: true, +path: () => import("./icons/icon-load.js"), +},{ +name: "icon-loading", +legacy: true, +hidden: true, +path: () => import("./icons/icon-loading.js"), +},{ +name: "icon-locate", +path: () => import("./icons/icon-locate.js"), +},{ +name: "icon-location-near-me", +legacy: true, +hidden: true, +path: () => import("./icons/icon-location-near-me.js"), +},{ +name: "icon-location-nearby", +path: () => import("./icons/icon-location-nearby.js"), +},{ +name: "icon-lock", +path: () => import("./icons/icon-lock.js"), +},{ +name: "icon-log-out", +path: () => import("./icons/icon-log-out.js"), +},{ +name: "icon-logout", +legacy: true, +hidden: true, +path: () => import("./icons/icon-logout.js"), +},{ +name: "icon-loupe", +legacy: true, +hidden: true, +path: () => import("./icons/icon-loupe.js"), +},{ +name: "icon-magnet", +path: () => import("./icons/icon-magnet.js"), +},{ +name: "icon-mailbox", +path: () => import("./icons/icon-mailbox.js"), +},{ +name: "icon-map-alt", +path: () => import("./icons/icon-map-alt.js"), +},{ +name: "icon-map-location", +legacy: true, +hidden: true, +path: () => import("./icons/icon-map-location.js"), +},{ +name: "icon-map-marker", +path: () => import("./icons/icon-map-marker.js"), +},{ +name: "icon-map", +path: () => import("./icons/icon-map.js"), +},{ +name: "icon-medal", +path: () => import("./icons/icon-medal.js"), +},{ +name: "icon-medical-emergency", +path: () => import("./icons/icon-medical-emergency.js"), +},{ +name: "icon-medicine", +path: () => import("./icons/icon-medicine.js"), +},{ +name: "icon-meeting", +legacy: true, +hidden: true, +path: () => import("./icons/icon-meeting.js"), +},{ +name: "icon-megaphone", +path: () => import("./icons/icon-megaphone.js"), +},{ +name: "icon-merge", +path: () => import("./icons/icon-merge.js"), +},{ +name: "icon-message-open", +path: () => import("./icons/icon-message-open.js"), +},{ +name: "icon-message-unopened", +legacy: true, +hidden: true, +path: () => import("./icons/icon-message-unopened.js"), +},{ +name: "icon-message", +path: () => import("./icons/icon-message.js"), +},{ +name: "icon-microscope", +path: () => import("./icons/icon-microscope.js"), +},{ +name: "icon-mindmap", +legacy: true, +hidden: true, +path: () => import("./icons/icon-mindmap.js"), +},{ +name: "icon-mobile", +path: () => import("./icons/icon-mobile.js"), +},{ +name: "icon-mountain", +path: () => import("./icons/icon-mountain.js"), +},{ +name: "icon-mouse-cursor", +path: () => import("./icons/icon-mouse-cursor.js"), +},{ +name: "icon-mouse", +path: () => import("./icons/icon-mouse.js"), +},{ +name: "icon-movie-alt", +path: () => import("./icons/icon-movie-alt.js"), +},{ +name: "icon-movie", +path: () => import("./icons/icon-movie.js"), +},{ +name: "icon-multiple-credit-cards", +path: () => import("./icons/icon-multiple-credit-cards.js"), +},{ +name: "icon-multiple-windows", +path: () => import("./icons/icon-multiple-windows.js"), +},{ +name: "icon-music", +path: () => import("./icons/icon-music.js"), +},{ +name: "icon-name-badge", +legacy: true, +hidden: true, +path: () => import("./icons/icon-name-badge.js"), +},{ +name: "icon-navigation-bottom", +legacy: true, +hidden: true, +path: () => import("./icons/icon-navigation-bottom.js"), +},{ +name: "icon-navigation-down", +legacy: true, +hidden: true, +path: () => import("./icons/icon-navigation-down.js"), +},{ +name: "icon-navigation-first", +legacy: true, +hidden: true, +path: () => import("./icons/icon-navigation-first.js"), +},{ +name: "icon-navigation-horizontal", +legacy: true, +hidden: true, +path: () => import("./icons/icon-navigation-horizontal.js"), +},{ +name: "icon-navigation-last", +legacy: true, +hidden: true, +path: () => import("./icons/icon-navigation-last.js"), +},{ +name: "icon-navigation-left", +legacy: true, +hidden: true, +path: () => import("./icons/icon-navigation-left.js"), +},{ +name: "icon-navigation-right", +legacy: true, +hidden: true, +path: () => import("./icons/icon-navigation-right.js"), +},{ +name: "icon-navigation-road", +legacy: true, +hidden: true, +path: () => import("./icons/icon-navigation-road.js"), +},{ +name: "icon-navigation-top", +legacy: true, +hidden: true, +path: () => import("./icons/icon-navigation-top.js"), +},{ +name: "icon-navigation-up", +legacy: true, +hidden: true, +path: () => import("./icons/icon-navigation-up.js"), +},{ +name: "icon-navigation-vertical", +legacy: true, +hidden: true, +path: () => import("./icons/icon-navigation-vertical.js"), +},{ +name: "icon-navigation", +legacy: true, +hidden: true, +path: () => import("./icons/icon-navigation.js"), +},{ +name: "icon-navigational-arrow", +path: () => import("./icons/icon-navigational-arrow.js"), +},{ +name: "icon-network-alt", +path: () => import("./icons/icon-network-alt.js"), +},{ +name: "icon-newspaper-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-newspaper-alt.js"), +},{ +name: "icon-newspaper", +path: () => import("./icons/icon-newspaper.js"), +},{ +name: "icon-next-media", +legacy: true, +hidden: true, +path: () => import("./icons/icon-next-media.js"), +},{ +name: "icon-next", +path: () => import("./icons/icon-next.js"), +},{ +name: "icon-nodes", +legacy: true, +hidden: true, +path: () => import("./icons/icon-nodes.js"), +},{ +name: "icon-notepad-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-notepad-alt.js"), +},{ +name: "icon-notepad", +path: () => import("./icons/icon-notepad.js"), +},{ +name: "icon-old-key", +path: () => import("./icons/icon-old-key.js"), +},{ +name: "icon-old-phone", +legacy: true, +hidden: true, +path: () => import("./icons/icon-old-phone.js"), +},{ +name: "icon-omega", +path: () => import("./icons/icon-omega.js"), +},{ +name: "icon-operator", +path: () => import("./icons/icon-operator.js"), +},{ +name: "icon-ordered-list", +path: () => import("./icons/icon-ordered-list.js"), +},{ +name: "icon-origami", +path: () => import("./icons/icon-origami.js"), +},{ +name: "icon-out", +path: () => import("./icons/icon-out.js"), +},{ +name: "icon-outbox", +legacy: true, +hidden: true, +path: () => import("./icons/icon-outbox.js"), +},{ +name: "icon-outdent", +path: () => import("./icons/icon-outdent.js"), +},{ +name: "icon-page-add", +path: () => import("./icons/icon-page-add.js"), +},{ +name: "icon-page-down", +path: () => import("./icons/icon-page-down.js"), +},{ +name: "icon-page-remove", +path: () => import("./icons/icon-page-remove.js"), +},{ +name: "icon-page-restricted", +path: () => import("./icons/icon-page-restricted.js"), +},{ +name: "icon-page-up", +path: () => import("./icons/icon-page-up.js"), +},{ +name: "icon-paint-roller", +legacy: true, +hidden: true, +path: () => import("./icons/icon-paint-roller.js"), +},{ +name: "icon-palette", +path: () => import("./icons/icon-palette.js"), +},{ +name: "icon-panel-show", +path: () => import("./icons/icon-panel-show.js"), +},{ +name: "icon-pannel-close", +path: () => import("./icons/icon-pannel-close.js"), +},{ +name: "icon-paper-bag", +legacy: true, +hidden: true, +path: () => import("./icons/icon-paper-bag.js"), +},{ +name: "icon-paper-plane-alt", +path: () => import("./icons/icon-paper-plane-alt.js"), +},{ +name: "icon-paper-plane", +path: () => import("./icons/icon-paper-plane.js"), +},{ +name: "icon-partly-cloudy", +path: () => import("./icons/icon-partly-cloudy.js"), +},{ +name: "icon-paragraph", +path: () => import("./icons/icon-paragraph.js"), +},{ +name: "icon-paste-in", +legacy: true, +hidden: true, +path: () => import("./icons/icon-paste-in.js"), +},{ +name: "icon-pause", +path: () => import("./icons/icon-pause.js"), +},{ +name: "icon-pc", +legacy: true, +hidden: true, +path: () => import("./icons/icon-pc.js"), +},{ +name: "icon-people-alt-2", +legacy: true, +hidden: true, +path: () => import("./icons/icon-people-alt-2.js"), +},{ +name: "icon-people-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-people-alt.js"), +},{ +name: "icon-people-female", +legacy: true, +hidden: true, +path: () => import("./icons/icon-people-female.js"), +},{ +name: "icon-people", +path: () => import("./icons/icon-people.js"), +},{ +name: "icon-phone-ring", +path: () => import("./icons/icon-phone-ring.js"), +},{ +name: "icon-phone", +path: () => import("./icons/icon-phone.js"), +},{ +name: "icon-photo-album", +path: () => import("./icons/icon-photo-album.js"), +},{ +name: "icon-picture", +path: () => import("./icons/icon-picture.js"), +},{ +name: "icon-pictures-alt-2", +path: () => import("./icons/icon-pictures-alt-2.js"), +},{ +name: "icon-pictures-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-pictures-alt.js"), +},{ +name: "icon-pictures", +path: () => import("./icons/icon-pictures.js"), +},{ +name: "icon-pie-chart", +path: () => import("./icons/icon-pie-chart.js"), +},{ +name: "icon-piggy-bank", +path: () => import("./icons/icon-piggy-bank.js"), +},{ +name: "icon-pin-location", +path: () => import("./icons/icon-pin-location.js"), +},{ +name: "icon-plane", +path: () => import("./icons/icon-plane.js"), +},{ +name: "icon-planet", +legacy: true, +hidden: true, +path: () => import("./icons/icon-planet.js"), +},{ +name: "icon-play", +path: () => import("./icons/icon-play.js"), +},{ +name: "icon-playing-cards", +legacy: true, +hidden: true, +path: () => import("./icons/icon-playing-cards.js"), +},{ +name: "icon-playlist", +path: () => import("./icons/icon-playlist.js"), +},{ +name: "icon-plugin", +path: () => import("./icons/icon-plugin.js"), +},{ +name: "icon-podcast", +path: () => import("./icons/icon-podcast.js"), +},{ +name: "icon-poll", +legacy: true, +hidden: true, +path: () => import("./icons/icon-poll.js"), +},{ +name: "icon-post-it", +path: () => import("./icons/icon-post-it.js"), +},{ +name: "icon-power-outlet", +legacy: true, +hidden: true, +path: () => import("./icons/icon-power-outlet.js"), +},{ +name: "icon-power", +path: () => import("./icons/icon-power.js"), +},{ +name: "icon-presentation", +path: () => import("./icons/icon-presentation.js"), +},{ +name: "icon-previous-media", +path: () => import("./icons/icon-previous-media.js"), +},{ +name: "icon-previous", +path: () => import("./icons/icon-previous.js"), +},{ +name: "icon-price-dollar", +legacy: true, +hidden: true, +path: () => import("./icons/icon-price-dollar.js"), +},{ +name: "icon-price-euro", +legacy: true, +hidden: true, +path: () => import("./icons/icon-price-euro.js"), +},{ +name: "icon-price-pound", +legacy: true, +hidden: true, +path: () => import("./icons/icon-price-pound.js"), +},{ +name: "icon-price-yen", +legacy: true, +hidden: true, +path: () => import("./icons/icon-price-yen.js"), +},{ +name: "icon-print", +path: () => import("./icons/icon-print.js"), +},{ +name: "icon-printer-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-printer-alt.js"), +},{ +name: "icon-projector", +path: () => import("./icons/icon-projector.js"), +},{ +name: "icon-pulse", +path: () => import("./icons/icon-pulse.js"), +},{ +name: "icon-pushpin", +path: () => import("./icons/icon-pushpin.js"), +},{ +name: "icon-qr-code", +path: () => import("./icons/icon-qr-code.js"), +},{ +name: "icon-quote", +path: () => import("./icons/icon-quote.js"), +},{ +name: "icon-radio-alt", +path: () => import("./icons/icon-radio-alt.js"), +},{ +name: "icon-radio-receiver", +path: () => import("./icons/icon-radio-receiver.js"), +},{ +name: "icon-radio", +path: () => import("./icons/icon-radio.js"), +},{ +name: "icon-rain", +path: () => import("./icons/icon-rain.js"), +},{ +name: "icon-rate", +legacy: true, +hidden: true, +path: () => import("./icons/icon-rate.js"), +},{ +name: "icon-re-post", +path: () => import("./icons/icon-re-post.js"), +},{ +name: "icon-readonly", +path: () => import("./icons/icon-readonly.js"), +},{ +name: "icon-receipt-alt", +path: () => import("./icons/icon-receipt-alt.js"), +},{ +name: "icon-reception", +path: () => import("./icons/icon-reception.js"), +},{ +name: "icon-record", +legacy: true, +hidden: true, +path: () => import("./icons/icon-record.js"), +},{ +name: "icon-rectangle-ellipsis", +path: () => import("./icons/icon-rectangle-ellipsis.js"), +},{ +name: "icon-redo", +path: () => import("./icons/icon-redo.js"), +},{ +name: "icon-refresh", +path: () => import("./icons/icon-refresh.js"), +},{ +name: "icon-remote", +legacy: true, +hidden: true, +path: () => import("./icons/icon-remote.js"), +},{ +name: "icon-remove", +path: () => import("./icons/icon-remove.js"), +},{ +name: "icon-repeat-one", +path: () => import("./icons/icon-repeat-one.js"), +},{ +name: "icon-repeat", +path: () => import("./icons/icon-repeat.js"), +},{ +name: "icon-reply-arrow", +path: () => import("./icons/icon-reply-arrow.js"), +},{ +name: "icon-resize", +path: () => import("./icons/icon-resize.js"), +},{ +name: "icon-return-to-top", +legacy: true, +hidden: true, +path: () => import("./icons/icon-return-to-top.js"), +},{ +name: "icon-right-double-arrow", +legacy: true, +hidden: true, +path: () => import("./icons/icon-right-double-arrow.js"), +},{ +name: "icon-roadsign", +legacy: true, +hidden: true, +path: () => import("./icons/icon-roadsign.js"), +},{ +name: "icon-rocket", +path: () => import("./icons/icon-rocket.js"), +},{ +name: "icon-rss", +path: () => import("./icons/icon-rss.js"), +},{ +name: "icon-ruler-alt", +path: () => import("./icons/icon-ruler-alt.js"), +},{ +name: "icon-ruler", +path: () => import("./icons/icon-ruler.js"), +},{ +name: "icon-satellite-dish", +path: () => import("./icons/icon-satellite-dish.js"), +},{ +name: "icon-save", +path: () => import("./icons/icon-save.js"), +},{ +name: "icon-scan", +path: () => import("./icons/icon-scan.js"), +},{ +name: "icon-school", +path: () => import("./icons/icon-school.js"), +},{ +name: "icon-screensharing", +path: () => import("./icons/icon-screensharing.js"), +},{ +name: "icon-script-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-script-alt.js"), +},{ +name: "icon-script", +path: () => import("./icons/icon-script.js"), +},{ +name: "icon-scull", +path: () => import("./icons/icon-scull.js"), +},{ +name: "icon-search", +path: () => import("./icons/icon-search.js"), +},{ +name: "icon-sensor", +path: () => import("./icons/icon-sensor.js"), +},{ +name: "icon-server-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-server-alt.js"), +},{ +name: "icon-server", +path: () => import("./icons/icon-server.js"), +},{ +name: "icon-settings-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-settings-alt.js"), +},{ +name: "icon-settings", +path: () => import("./icons/icon-settings.js"), +},{ +name: "icon-share-alt", +path: () => import("./icons/icon-share-alt.js"), +},{ +name: "icon-share", +path: () => import("./icons/icon-share.js"), +},{ +name: "icon-sharing-iphone", +path: () => import("./icons/icon-sharing-iphone.js"), +},{ +name: "icon-shield", +path: () => import("./icons/icon-shield.js"), +},{ +name: "icon-shift", +path: () => import("./icons/icon-shift.js"), +},{ +name: "icon-shipping-box", +path: () => import("./icons/icon-shipping-box.js"), +},{ +name: "icon-shipping", +path: () => import("./icons/icon-shipping.js"), +},{ +name: "icon-shoe", +legacy: true, +hidden: true, +path: () => import("./icons/icon-shoe.js"), +},{ +name: "icon-shopping-basket-alt-2", +legacy: true, +hidden: true, +path: () => import("./icons/icon-shopping-basket-alt-2.js"), +},{ +name: "icon-shopping-basket-alt", +path: () => import("./icons/icon-shopping-basket-alt.js"), +},{ +name: "icon-shopping-basket", +path: () => import("./icons/icon-shopping-basket.js"), +},{ +name: "icon-shuffle", +path: () => import("./icons/icon-shuffle.js"), +},{ +name: "icon-sience", +legacy: true, +hidden: true, +path: () => import("./icons/icon-sience.js"), +},{ +name: "icon-science", +path: () => import("./icons/icon-science.js"), +},{ +name: "icon-single-note", +path: () => import("./icons/icon-single-note.js"), +},{ +name: "icon-sitemap", +legacy: true, +hidden: true, +path: () => import("./icons/icon-sitemap.js"), +},{ +name: "icon-sleep", +path: () => import("./icons/icon-sleep.js"), +},{ +name: "icon-slideshow", +legacy: true, +hidden: true, +path: () => import("./icons/icon-slideshow.js"), +},{ +name: "icon-smiley-inverted", +legacy: true, +hidden: true, +path: () => import("./icons/icon-smiley-inverted.js"), +},{ +name: "icon-smiley", +path: () => import("./icons/icon-smiley.js"), +},{ +name: "icon-snow", +path: () => import("./icons/icon-snow.js"), +},{ +name: "icon-sound-low", +path: () => import("./icons/icon-sound-low.js"), +},{ +name: "icon-sound-medium", +legacy: true, +hidden: true, +path: () => import("./icons/icon-sound-medium.js"), +},{ +name: "icon-sound-off", +path: () => import("./icons/icon-sound-off.js"), +},{ +name: "icon-sound-waves", +path: () => import("./icons/icon-sound-waves.js"), +},{ +name: "icon-sound", +path: () => import("./icons/icon-sound.js"), +},{ +name: "icon-spades", +path: () => import("./icons/icon-spades.js"), +},{ +name: "icon-speaker", +path: () => import("./icons/icon-speaker.js"), +},{ +name: "icon-speed-gauge", +path: () => import("./icons/icon-speed-gauge.js"), +},{ +name: "icon-split-alt", +path: () => import("./icons/icon-split-alt.js"), +},{ +name: "icon-split", +path: () => import("./icons/icon-split.js"), +},{ +name: "icon-sprout", +path: () => import("./icons/icon-sprout.js"), +},{ +name: "icon-squiggly-line", +legacy: true, +hidden: true, +path: () => import("./icons/icon-squiggly-line.js"), +},{ +name: "icon-ssd", +legacy: true, +hidden: true, +path: () => import("./icons/icon-ssd.js"), +},{ +name: "icon-stacked-disks", +legacy: true, +hidden: true, +path: () => import("./icons/icon-stacked-disks.js"), +},{ +name: "icon-stamp", +legacy: true, +hidden: true, +path: () => import("./icons/icon-stamp.js"), +},{ +name: "icon-stop-alt", +path: () => import("./icons/icon-stop-alt.js"), +},{ +name: "icon-stop-hand", +legacy: true, +hidden: true, +path: () => import("./icons/icon-stop-hand.js"), +},{ +name: "icon-stop", +path: () => import("./icons/icon-stop.js"), +},{ +name: "icon-store", +path: () => import("./icons/icon-store.js"), +},{ +name: "icon-stream", +legacy: true, +hidden: true, +path: () => import("./icons/icon-stream.js"), +},{ +name: "icon-strikethrough", +path: () => import("./icons/icon-strikethrough.js"), +},{ +name: "icon-subscript", +path: () => import("./icons/icon-subscript.js"), +},{ +name: "icon-superscript", +path: () => import("./icons/icon-superscript.js"), +},{ +name: "icon-sunny", +path: () => import("./icons/icon-sunny.js"), +},{ +name: "icon-sweatshirt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-sweatshirt.js"), +},{ +name: "icon-sync", +path: () => import("./icons/icon-sync.js"), +},{ +name: "icon-t-shirt", +path: () => import("./icons/icon-t-shirt.js"), +},{ +name: "icon-tab-key", +path: () => import("./icons/icon-tab-key.js"), +},{ +name: "icon-table", +path: () => import("./icons/icon-table.js"), +},{ +name: "icon-tag", +path: () => import("./icons/icon-tag.js"), +},{ +name: "icon-tags", +path: () => import("./icons/icon-tags.js"), +},{ +name: "icon-takeaway-cup", +legacy: true, +hidden: true, +path: () => import("./icons/icon-takeaway-cup.js"), +},{ +name: "icon-target", +path: () => import("./icons/icon-target.js"), +},{ +name: "icon-temperatrure-alt", +path: () => import("./icons/icon-temperatrure-alt.js"), +},{ +name: "icon-temperature", +path: () => import("./icons/icon-temperature.js"), +},{ +name: "icon-terminal", +path: () => import("./icons/icon-terminal.js"), +},{ +name: "icon-text-align-center", +path: () => import("./icons/icon-text-align-center.js"), +},{ +name: "icon-text-align-justify", +path: () => import("./icons/icon-text-align-justify.js"), +},{ +name: "icon-text-align-left", +path: () => import("./icons/icon-text-align-left.js"), +},{ +name: "icon-text-align-right", +path: () => import("./icons/icon-text-align-right.js"), +},{ +name: "icon-text-direction-ltr", +path: () => import("./icons/icon-text-direction-ltr.js"), +},{ +name: "icon-text-direction-rtl", +path: () => import("./icons/icon-text-direction-rtl.js"), +},{ +name: "icon-theater", +path: () => import("./icons/icon-theater.js"), +},{ +name: "icon-thumb-down", +path: () => import("./icons/icon-thumb-down.js"), +},{ +name: "icon-thumb-up", +path: () => import("./icons/icon-thumb-up.js"), +},{ +name: "icon-thumbnail-list", +path: () => import("./icons/icon-thumbnail-list.js"), +},{ +name: "icon-thumbnails-small", +path: () => import("./icons/icon-thumbnails-small.js"), +},{ +name: "icon-thumbnails", +path: () => import("./icons/icon-thumbnails.js"), +},{ +name: "icon-ticket", +path: () => import("./icons/icon-ticket.js"), +},{ +name: "icon-time", +path: () => import("./icons/icon-time.js"), +},{ +name: "icon-timer", +path: () => import("./icons/icon-timer.js"), +},{ +name: "icon-tools", +legacy: true, +hidden: true, +path: () => import("./icons/icon-tools.js"), +},{ +name: "icon-top", +legacy: true, +hidden: true, +path: () => import("./icons/icon-top.js"), +},{ +name: "icon-traffic-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-traffic-alt.js"), +},{ +name: "icon-trafic", +path: () => import("./icons/icon-trafic.js"), +},{ +name: "icon-train", +path: () => import("./icons/icon-train.js"), +},{ +name: "icon-trash-alt-2", +legacy: true, +hidden: true, +path: () => import("./icons/icon-trash-alt-2.js"), +},{ +name: "icon-trash-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-trash-alt.js"), +},{ +name: "icon-trash", +path: () => import("./icons/icon-trash.js"), +},{ +name: "icon-tree", +path: () => import("./icons/icon-tree.js"), +},{ +name: "icon-trophy", +path: () => import("./icons/icon-trophy.js"), +},{ +name: "icon-truck", +path: () => import("./icons/icon-truck.js"), +},{ +name: "icon-tv-old", +path: () => import("./icons/icon-tv-old.js"), +},{ +name: "icon-tv", +path: () => import("./icons/icon-tv.js"), +},{ +name: "icon-umb-content", +legacy: true, +hidden: true, +path: () => import("./icons/icon-umb-content.js"), +},{ +name: "icon-umb-developer", +legacy: true, +hidden: true, +path: () => import("./icons/icon-umb-developer.js"), +},{ +name: "icon-umb-media", +legacy: true, +hidden: true, +path: () => import("./icons/icon-umb-media.js"), +},{ +name: "icon-umb-settings", +legacy: true, +hidden: true, +path: () => import("./icons/icon-umb-settings.js"), +},{ +name: "icon-umb-users", +legacy: true, +hidden: true, +path: () => import("./icons/icon-umb-users.js"), +},{ +name: "icon-umbrella", +path: () => import("./icons/icon-umbrella.js"), +},{ +name: "icon-undo", +path: () => import("./icons/icon-undo.js"), +},{ +name: "icon-underline", +path: () => import("./icons/icon-underline.js"), +},{ +name: "icon-unlink", +path: () => import("./icons/icon-unlink.js"), +},{ +name: "icon-unlocked", +path: () => import("./icons/icon-unlocked.js"), +},{ +name: "icon-unplug", +path: () => import("./icons/icon-unplug.js"), +},{ +name: "icon-untitled", +legacy: true, +hidden: true, +path: () => import("./icons/icon-untitled.js"), +},{ +name: "icon-usb-connector", +legacy: true, +hidden: true, +path: () => import("./icons/icon-usb-connector.js"), +},{ +name: "icon-usb", +path: () => import("./icons/icon-usb.js"), +},{ +name: "icon-user-female", +legacy: true, +hidden: true, +path: () => import("./icons/icon-user-female.js"), +},{ +name: "icon-user-females-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-user-females-alt.js"), +},{ +name: "icon-user-females", +legacy: true, +hidden: true, +path: () => import("./icons/icon-user-females.js"), +},{ +name: "icon-user-glasses", +legacy: true, +hidden: true, +path: () => import("./icons/icon-user-glasses.js"), +},{ +name: "icon-user", +path: () => import("./icons/icon-user.js"), +},{ +name: "icon-users-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-users-alt.js"), +},{ +name: "icon-users", +path: () => import("./icons/icon-users.js"), +},{ +name: "icon-utilities", +path: () => import("./icons/icon-utilities.js"), +},{ +name: "icon-vcard", +path: () => import("./icons/icon-vcard.js"), +},{ +name: "icon-video", +path: () => import("./icons/icon-video.js"), +},{ +name: "icon-voice", +path: () => import("./icons/icon-voice.js"), +},{ +name: "icon-wall-plug", +path: () => import("./icons/icon-wall-plug.js"), +},{ +name: "icon-wallet", +path: () => import("./icons/icon-wallet.js"), +},{ +name: "icon-wand", +path: () => import("./icons/icon-wand.js"), +},{ +name: "icon-webhook", +path: () => import("./icons/icon-webhook.js"), +},{ +name: "icon-weight", +path: () => import("./icons/icon-weight.js"), +},{ +name: "icon-width", +path: () => import("./icons/icon-width.js"), +},{ +name: "icon-wifi", +path: () => import("./icons/icon-wifi.js"), +},{ +name: "icon-window-popin", +path: () => import("./icons/icon-window-popin.js"), +},{ +name: "icon-window-popout", +path: () => import("./icons/icon-window-popout.js"), +},{ +name: "icon-window-sizes", +path: () => import("./icons/icon-window-sizes.js"), +},{ +name: "icon-wine-glass", +path: () => import("./icons/icon-wine-glass.js"), +},{ +name: "icon-wrench", +path: () => import("./icons/icon-wrench.js"), +},{ +name: "icon-wrong", +path: () => import("./icons/icon-wrong.js"), +},{ +name: "icon-zip", +path: () => import("./icons/icon-zip.js"), +},{ +name: "icon-zom-out", +legacy: true, +hidden: true, +path: () => import("./icons/icon-zom-out.js"), +},{ +name: "icon-zoom-in", +path: () => import("./icons/icon-zoom-in.js"), +},{ +name: "icon-zoom-out", +path: () => import("./icons/icon-zoom-out.js"), +},{ +name: "icon-star", +path: () => import("./icons/icon-star.js"), +},{ +name: "icon-database", +path: () => import("./icons/icon-database.js"), +},{ +name: "icon-umb-manifest", +hidden: true, +path: () => import("./icons/icon-umb-manifest.js"), +},{ +name: "icon-puzzle-piece", +path: () => import("./icons/icon-puzzle-piece.js"), +},{ +name: "icon-document-3d", +path: () => import("./icons/icon-document-3d.js"), +},{ +name: "icon-document-medal", +path: () => import("./icons/icon-document-medal.js"), +},{ +name: "icon-document-chart-bar", +path: () => import("./icons/icon-document-chart-bar.js"), +},{ +name: "icon-document-chart-graph", +path: () => import("./icons/icon-document-chart-graph.js"), +},{ +name: "icon-document-html", +path: () => import("./icons/icon-document-html.js"), +},{ +name: "icon-document-js", +path: () => import("./icons/icon-document-js.js"), +},{ +name: "icon-document-key", +path: () => import("./icons/icon-document-key.js"), +},{ +name: "icon-document-search", +path: () => import("./icons/icon-document-search.js"), +},{ +name: "icon-document-settings", +path: () => import("./icons/icon-document-settings.js"), +},{ +name: "icon-document-spreadsheet", +path: () => import("./icons/icon-document-spreadsheet.js"), +},{ +name: "icon-document-command", +path: () => import("./icons/icon-document-command.js"), +},{ +name: "icon-document-command", +path: () => import("./icons/icon-document-command.js"), +},{ +name: "icon-document-font", +path: () => import("./icons/icon-document-font.js"), +},{ +name: "icon-document-user", +path: () => import("./icons/icon-document-user.js"), +},{ +name: "icon-document-image", +path: () => import("./icons/icon-document-image.js"), +},{ +name: "icon-document-play", +path: () => import("./icons/icon-document-play.js"), +},{ +name: "icon-document-play", +path: () => import("./icons/icon-document-play.js"), +},{ +name: "icon-shared-value", +path: () => import("./icons/icon-shared-value.js"), +},{ +name: "icon-layout-masonry", +path: () => import("./icons/icon-layout-masonry.js"), +},{ +name: "icon-layout-grid", +path: () => import("./icons/icon-layout-grid.js"), +},{ +name: "icon-layout-list", +path: () => import("./icons/icon-layout-list.js"), +},{ +name: "icon-layout-panel-left", +path: () => import("./icons/icon-layout-panel-left.js"), +},{ +name: "icon-spray-can", +path: () => import("./icons/icon-spray-can.js"), +},{ +name: "icon-swatch-book", +path: () => import("./icons/icon-swatch-book.js"), +},{ +name: "icon-shape-cylinder", +path: () => import("./icons/icon-shape-cylinder.js"), +},{ +name: "icon-shape-triangle-right", +path: () => import("./icons/icon-shape-triangle-right.js"), +},{ +name: "icon-shape-triangle", +path: () => import("./icons/icon-shape-triangle.js"), +},{ +name: "icon-shape-circle", +path: () => import("./icons/icon-shape-circle.js"), +},{ +name: "icon-shape-square", +path: () => import("./icons/icon-shape-square.js"), +},{ +name: "icon-shape-hexagon", +path: () => import("./icons/icon-shape-hexagon.js"), +},{ +name: "icon-shape-rectangle-horizontal", +path: () => import("./icons/icon-shape-rectangle-horizontal.js"), +},{ +name: "icon-shape-rectangle-vertical", +path: () => import("./icons/icon-shape-rectangle-vertical.js"), +},{ +name: "icon-shapes", +path: () => import("./icons/icon-shapes.js"), +},{ +name: "icon-layout-dislocated", +path: () => import("./icons/icon-layout-dislocated.js"), +},{ +name: "icon-blend", +path: () => import("./icons/icon-blend.js"), +},{ +name: "icon-land-plot", +path: () => import("./icons/icon-land-plot.js"), +},{ +name: "icon-facebook", +path: () => import("./icons/icon-facebook.js"), +},{ +name: "icon-gitbook", +path: () => import("./icons/icon-gitbook.js"), +},{ +name: "icon-github", +path: () => import("./icons/icon-github.js"), +},{ +name: "icon-gitlab", +path: () => import("./icons/icon-gitlab.js"), +},{ +name: "icon-google", +path: () => import("./icons/icon-google.js"), +},{ +name: "icon-mastodon", +path: () => import("./icons/icon-mastodon.js"), +},{ +name: "icon-twitter-x", +path: () => import("./icons/icon-twitter-x.js"), +},{ +name: "icon-art-easel", +legacy: true, +hidden: true, +path: () => import("./icons/icon-art-easel.js"), +},{ +name: "icon-article", +legacy: true, +hidden: true, +path: () => import("./icons/icon-article.js"), +},{ +name: "icon-auction-hammer", +legacy: true, +hidden: true, +path: () => import("./icons/icon-auction-hammer.js"), +},{ +name: "icon-badge-count", +legacy: true, +hidden: true, +path: () => import("./icons/icon-badge-count.js"), +},{ +name: "icon-band-aid", +legacy: true, +hidden: true, +path: () => import("./icons/icon-band-aid.js"), +},{ +name: "icon-baby-stroller", +legacy: true, +hidden: true, +path: () => import("./icons/icon-baby-stroller.js"), +},{ +name: "icon-bill-dollar", +legacy: true, +hidden: true, +path: () => import("./icons/icon-bill-dollar.js"), +},{ +name: "icon-bill-euro", +legacy: true, +hidden: true, +path: () => import("./icons/icon-bill-euro.js"), +},{ +name: "icon-bill-pound", +legacy: true, +hidden: true, +path: () => import("./icons/icon-bill-pound.js"), +},{ +name: "icon-bill-yen", +legacy: true, +hidden: true, +path: () => import("./icons/icon-bill-yen.js"), +},{ +name: "icon-bill", +legacy: true, +hidden: true, +path: () => import("./icons/icon-bill.js"), +},{ +name: "icon-billboard", +legacy: true, +hidden: true, +path: () => import("./icons/icon-billboard.js"), +},{ +name: "icon-bills-dollar", +legacy: true, +hidden: true, +path: () => import("./icons/icon-bills-dollar.js"), +},{ +name: "icon-bills-euro", +legacy: true, +hidden: true, +path: () => import("./icons/icon-bills-euro.js"), +},{ +name: "icon-bills-pound", +legacy: true, +hidden: true, +path: () => import("./icons/icon-bills-pound.js"), +},{ +name: "icon-bills-yen", +legacy: true, +hidden: true, +path: () => import("./icons/icon-bills-yen.js"), +},{ +name: "icon-bills", +legacy: true, +hidden: true, +path: () => import("./icons/icon-bills.js"), +},{ +name: "icon-blueprint", +legacy: true, +hidden: true, +path: () => import("./icons/icon-blueprint.js"), +},{ +name: "icon-bomb", +legacy: true, +hidden: true, +path: () => import("./icons/icon-bomb.js"), +},{ +name: "icon-cash-register", +legacy: true, +hidden: true, +path: () => import("./icons/icon-cash-register.js"), +},{ +name: "icon-checkbox-dotted-active", +legacy: true, +hidden: true, +path: () => import("./icons/icon-checkbox-dotted-active.js"), +},{ +name: "icon-chess", +legacy: true, +hidden: true, +path: () => import("./icons/icon-chess.js"), +},{ +name: "icon-circus", +legacy: true, +hidden: true, +path: () => import("./icons/icon-circus.js"), +},{ +name: "icon-clothes-hanger", +legacy: true, +hidden: true, +path: () => import("./icons/icon-clothes-hanger.js"), +},{ +name: "icon-coin", +legacy: true, +hidden: true, +path: () => import("./icons/icon-coin.js"), +},{ +name: "icon-coins-dollar-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-coins-dollar-alt.js"), +},{ +name: "icon-coins-dollar", +legacy: true, +hidden: true, +path: () => import("./icons/icon-coins-dollar.js"), +},{ +name: "icon-coins-euro-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-coins-euro-alt.js"), +},{ +name: "icon-coins-euro", +legacy: true, +hidden: true, +path: () => import("./icons/icon-coins-euro.js"), +},{ +name: "icon-coins-pound-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-coins-pound-alt.js"), +},{ +name: "icon-coins-pound", +legacy: true, +hidden: true, +path: () => import("./icons/icon-coins-pound.js"), +},{ +name: "icon-coins-yen-alt", +legacy: true, +hidden: true, +path: () => import("./icons/icon-coins-yen-alt.js"), +},{ +name: "icon-coins-yen", +legacy: true, +hidden: true, +path: () => import("./icons/icon-coins-yen.js"), +},{ +name: "icon-comb", +legacy: true, +hidden: true, +path: () => import("./icons/icon-comb.js"), +},{ +name: "icon-desk", +legacy: true, +hidden: true, +path: () => import("./icons/icon-desk.js"), +},{ +name: "icon-dollar-bag", +legacy: true, +hidden: true, +path: () => import("./icons/icon-dollar-bag.js"), +},{ +name: "icon-eject", +legacy: true, +hidden: true, +path: () => import("./icons/icon-eject.js"), +},{ +name: "icon-euro-bag", +legacy: true, +hidden: true, +path: () => import("./icons/icon-euro-bag.js"), +},{ +name: "icon-female-symbol", +legacy: true, +hidden: true, +path: () => import("./icons/icon-female-symbol.js"), +},{ +name: "icon-firewall", +legacy: true, +hidden: true, +path: () => import("./icons/icon-firewall.js"), +},{ +name: "icon-folder-open", +legacy: true, +hidden: true, +path: () => import("./icons/icon-folder-open.js"), +},{ +name: "icon-folder-outline", +legacy: true, +hidden: true, +path: () => import("./icons/icon-folder-outline.js"), +},{ +name: "icon-handprint", +legacy: true, +hidden: true, +path: () => import("./icons/icon-handprint.js"), +},{ +name: "icon-hat", +legacy: true, +hidden: true, +path: () => import("./icons/icon-hat.js"), +},{ +name: "icon-hd", +legacy: true, +hidden: true, +path: () => import("./icons/icon-hd.js"), +},{ +name: "icon-inactive-line", +legacy: true, +hidden: true, +path: () => import("./icons/icon-inactive-line.js"), +},{ +name: "icon-keychain", +legacy: true, +hidden: true, +path: () => import("./icons/icon-keychain.js"), +},{ +name: "icon-keyhole", +legacy: true, +hidden: true, +path: () => import("./icons/icon-keyhole.js"), +},{ +name: "icon-linkedin", +legacy: true, +hidden: true, +path: () => import("./icons/icon-linkedin.js"), +},{ +name: "icon-linux-tux", +legacy: true, +hidden: true, +path: () => import("./icons/icon-linux-tux.js"), +},{ +name: "icon-male-and-female", +legacy: true, +hidden: true, +path: () => import("./icons/icon-male-and-female.js"), +},{ +name: "icon-male-symbol", +legacy: true, +hidden: true, +path: () => import("./icons/icon-male-symbol.js"), +},{ +name: "icon-molecular-network", +legacy: true, +hidden: true, +path: () => import("./icons/icon-molecular-network.js"), +},{ +name: "icon-molecular", +legacy: true, +hidden: true, +path: () => import("./icons/icon-molecular.js"), +},{ +name: "icon-umbraco", +path: () => import("./icons/icon-umbraco.js"), +},{ +name: "icon-azure", +legacy: true, +hidden: true, +path: () => import("./icons/icon-azure.js"), +},{ +name: "icon-microsoft", +legacy: true, +hidden: true, +path: () => import("./icons/icon-microsoft.js"), +},{ +name: "icon-os-x", +legacy: true, +hidden: true, +path: () => import("./icons/icon-os-x.js"), +},{ +name: "icon-pants", +legacy: true, +hidden: true, +path: () => import("./icons/icon-pants.js"), +},{ +name: "icon-parachute-drop", +legacy: true, +hidden: true, +path: () => import("./icons/icon-parachute-drop.js"), +},{ +name: "icon-parental-control", +legacy: true, +hidden: true, +path: () => import("./icons/icon-parental-control.js"), +},{ +name: "icon-path", +legacy: true, +hidden: true, +path: () => import("./icons/icon-path.js"), +},{ +name: "icon-piracy", +legacy: true, +hidden: true, +path: () => import("./icons/icon-piracy.js"), +},{ +name: "icon-poker-chip", +legacy: true, +hidden: true, +path: () => import("./icons/icon-poker-chip.js"), +},{ +name: "icon-pound-bag", +legacy: true, +hidden: true, +path: () => import("./icons/icon-pound-bag.js"), +},{ +name: "icon-receipt-dollar", +legacy: true, +hidden: true, +path: () => import("./icons/icon-receipt-dollar.js"), +},{ +name: "icon-receipt-euro", +legacy: true, +hidden: true, +path: () => import("./icons/icon-receipt-euro.js"), +},{ +name: "icon-receipt-pound", +legacy: true, +hidden: true, +path: () => import("./icons/icon-receipt-pound.js"), +},{ +name: "icon-receipt-yen", +legacy: true, +hidden: true, +path: () => import("./icons/icon-receipt-yen.js"), +},{ +name: "icon-road", +legacy: true, +hidden: true, +path: () => import("./icons/icon-road.js"), +},{ +name: "icon-safe", +legacy: true, +hidden: true, +path: () => import("./icons/icon-safe.js"), +},{ +name: "icon-safedial", +legacy: true, +hidden: true, +path: () => import("./icons/icon-safedial.js"), +},{ +name: "icon-sandbox-toys", +legacy: true, +hidden: true, +path: () => import("./icons/icon-sandbox-toys.js"), +},{ +name: "icon-security-camera", +legacy: true, +hidden: true, +path: () => import("./icons/icon-security-camera.js"), +},{ +name: "icon-settings-alt-2", +legacy: true, +hidden: true, +path: () => import("./icons/icon-settings-alt-2.js"), +},{ +name: "icon-share-alt-2", +legacy: true, +hidden: true, +path: () => import("./icons/icon-share-alt-2.js"), +},{ +name: "icon-shorts", +legacy: true, +hidden: true, +path: () => import("./icons/icon-shorts.js"), +},{ +name: "icon-simcard", +legacy: true, +hidden: true, +path: () => import("./icons/icon-simcard.js"), +},{ +name: "icon-tab", +legacy: true, +hidden: true, +path: () => import("./icons/icon-tab.js"), +},{ +name: "icon-tactics", +legacy: true, +hidden: true, +path: () => import("./icons/icon-tactics.js"), +},{ +name: "icon-theif", +legacy: true, +hidden: true, +path: () => import("./icons/icon-theif.js"), +},{ +name: "icon-thought-bubble", +legacy: true, +hidden: true, +path: () => import("./icons/icon-thought-bubble.js"), +},{ +name: "icon-twitter", +legacy: true, +hidden: true, +path: () => import("./icons/icon-twitter.js"), +},{ +name: "icon-umb-contour", +legacy: true, +hidden: true, +path: () => import("./icons/icon-umb-contour.js"), +},{ +name: "icon-umb-deploy", +legacy: true, +hidden: true, +path: () => import("./icons/icon-umb-deploy.js"), +},{ +name: "icon-umb-members", +legacy: true, +hidden: true, +path: () => import("./icons/icon-umb-members.js"), +},{ +name: "icon-universal", +legacy: true, +hidden: true, +path: () => import("./icons/icon-universal.js"), +},{ +name: "icon-war", +legacy: true, +hidden: true, +path: () => import("./icons/icon-war.js"), +},{ +name: "icon-windows", +legacy: true, +hidden: true, +path: () => import("./icons/icon-windows.js"), +},{ +name: "icon-yen-bag", +legacy: true, +hidden: true, +path: () => import("./icons/icon-yen-bag.js"), +}]; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-azure.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-azure.ts index dbb4c71663..a9fa4a7733 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-azure.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-azure.ts @@ -1 +1 @@ -export default ``; \ No newline at end of file +export default `Microsoft Azure`; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-facebook.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-facebook.ts index 3a694dd65c..d50f7ef036 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-facebook.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-facebook.ts @@ -1 +1 @@ -export default ``; \ No newline at end of file +export default `Facebook`; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-gitbook.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-gitbook.ts index 76f5e769fb..c098a56070 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-gitbook.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-gitbook.ts @@ -1 +1 @@ -export default ``; \ No newline at end of file +export default `GitBook`; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-github.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-github.ts index c9a0ca4670..84ca5c77da 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-github.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-github.ts @@ -1 +1 @@ -export default ``; \ No newline at end of file +export default `GitHub`; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-gitlab.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-gitlab.ts index 34de202aa0..8e86fe12a0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-gitlab.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-gitlab.ts @@ -1 +1 @@ -export default ``; \ No newline at end of file +export default `GitLab`; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-google.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-google.ts index 84e344b7b3..4c7fdec581 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-google.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-google.ts @@ -1 +1 @@ -export default ``; \ No newline at end of file +export default `Google`; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-mastodon.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-mastodon.ts index 9a44442b4f..6e33bb6c68 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-mastodon.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-mastodon.ts @@ -1 +1 @@ -export default ``; \ No newline at end of file +export default `Mastodon`; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-microsoft.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-microsoft.ts index 0659a2f186..bcef0848b1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-microsoft.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-microsoft.ts @@ -1 +1 @@ -export default ``; \ No newline at end of file +export default `Microsoft`; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-pictures.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-pictures.ts index c89d1c844b..7bd63c45ff 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-pictures.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-pictures.ts @@ -1 +1 @@ -export default ``; \ No newline at end of file +export default ``; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-twitter-x.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-twitter-x.ts index 1376c7d65b..1f457a8568 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-twitter-x.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-twitter-x.ts @@ -1 +1 @@ -export default ``; \ No newline at end of file +export default `X`; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-twitter.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-twitter.ts index 400c012ae9..854aca4e38 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-twitter.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-twitter.ts @@ -1 +1 @@ -export default ``; \ No newline at end of file +export default `Twitter`; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-umbrella.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-umbrella.ts index a6eb9d6fed..8238221d0a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-umbrella.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-umbrella.ts @@ -1 +1 @@ -export default ``; \ No newline at end of file +export default ``; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/package.json b/src/Umbraco.Web.UI.Client/src/packages/core/package.json index ea1d94d79a..e9ab5ca0c9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/package.json +++ b/src/Umbraco.Web.UI.Client/src/packages/core/package.json @@ -11,5 +11,10 @@ "diff": "^7.0.0", "uuid": "^11.1.0", "@hey-api/openapi-ts": "0.81.1" + }, + "devDependencies": { + "lucide-static": "^0.542.0", + "simple-icons": "^15.13.0", + "svgo": "^4.0.0" } -} \ No newline at end of file +} From ddf08191533c882e7dab0b639695aaf65fe66a6f Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Mon, 1 Sep 2025 13:06:51 +0200 Subject: [PATCH 31/33] chore(eslint): fixes --- .../menu-item/expansion/menu-item-expansion.manager.ts | 2 +- .../section-sidebar-menu.section-context.token.ts | 2 +- .../src/packages/media/media-types/menu/manifests.ts | 2 +- .../members/member/workspace/member/manifests.ts | 10 +++++----- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/expansion/menu-item-expansion.manager.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/expansion/menu-item-expansion.manager.ts index b02938e46f..5b96983adb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/expansion/menu-item-expansion.manager.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/expansion/menu-item-expansion.manager.ts @@ -47,7 +47,7 @@ export class UmbMenuItemExpansionManager extends UmbControllerBase { (itemsForMenuItem) => { this.#manager.setExpansion(itemsForMenuItem); }, - 'observeMenuExpension' + 'observeMenuExpension', ); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/section-sidebar-menu.section-context.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/section-sidebar-menu.section-context.token.ts index bdab53e799..d0ae6e6eba 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/section-sidebar-menu.section-context.token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/section-sidebar-menu/section-context/section-sidebar-menu.section-context.token.ts @@ -1,5 +1,5 @@ -import { UMB_SECTION_CONTEXT } from '@umbraco-cms/backoffice/section'; import type { UmbSectionSidebarMenuSectionContext } from './section-sidebar-menu.section-context.js'; +import { UMB_SECTION_CONTEXT } from '@umbraco-cms/backoffice/section'; import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; export const UMB_SECTION_SIDEBAR_MENU_SECTION_CONTEXT = new UmbContextToken( diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/menu/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/menu/manifests.ts index 9272a5fafd..b4ea0ec9b8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/menu/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/menu/manifests.ts @@ -1,6 +1,6 @@ import { UMB_MEDIA_TYPE_TREE_ALIAS } from '../constants.js'; -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_MEDIA_TYPE_MENU_ITEM_ALIAS } from './constants.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/manifests.ts index 7b72163b99..a16019ff71 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/manifests.ts @@ -1,4 +1,9 @@ import { UMB_MEMBER_ENTITY_TYPE } from '../../entity.js'; +import { + UMB_MEMBER_WORKSPACE_ALIAS, + UMB_MEMBER_WORKSPACE_VIEW_CONTENT_ALIAS, + UMB_MEMBER_WORKSPACE_VIEW_MEMBER_ALIAS, +} from './constants.js'; import type { ManifestWorkspaces, ManifestWorkspaceActions, @@ -6,11 +11,6 @@ import type { } from '@umbraco-cms/backoffice/workspace'; import { UmbSubmitWorkspaceAction, UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_CONTENT_HAS_PROPERTIES_WORKSPACE_CONDITION } from '@umbraco-cms/backoffice/content'; -import { - UMB_MEMBER_WORKSPACE_ALIAS, - UMB_MEMBER_WORKSPACE_VIEW_CONTENT_ALIAS, - UMB_MEMBER_WORKSPACE_VIEW_MEMBER_ALIAS, -} from './constants.js'; const workspace: ManifestWorkspaces = { type: 'workspace', From ae44f301cf520070c2fce623b3ca91ef88388fa4 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Mon, 1 Sep 2025 13:10:37 +0200 Subject: [PATCH 32/33] Removes 'rollup' and 'glob' from NOTICES.txt (#20043) * removes the mention of rollup in NOTICES.txt and makes it clear that the file only contains first-party mentions * removes the mention of 'glob' --- NOTICES.txt | 44 +++----------------------------------------- 1 file changed, 3 insertions(+), 41 deletions(-) diff --git a/NOTICES.txt b/NOTICES.txt index 1ea114b715..a3cb471492 100644 --- a/NOTICES.txt +++ b/NOTICES.txt @@ -3,7 +3,9 @@ Third-Party Notices This file contains notices and attributions for third-party software used in the Umbraco CMS project. -It is not a license and does not grant any rights to use the third-party software. +Third-party software may contain dependencies that are not explicitly listed here. + +This notice is not a license and does not grant any rights to use the third-party software. Umbraco CMS is licensed under the MIT License, which can be found in the LICENSE file. @@ -113,14 +115,6 @@ Copyright: 2023 Shannon Deminick --- -Glob: A library for matching file paths using glob patterns - -URL: https://github.com/isaacs/node-glob -License: ISC License -Copyright: 2009-2023 Isaac Z. Schlueter and Contributors - ---- - Globals: A library for managing global variables in JavaScript URL: https://github.com/sindresorhus/globals @@ -356,38 +350,6 @@ Copyright: Titus Wormer --- -Rollup: A module bundler for JavaScript - -URL: https://rollupjs.org/ -License: MIT License -Copyright: 2015-present Rollup contributors - ---- - -Rollup Plugins: A collection of Rollup plugins - -URL: https://github.com/rollup/plugins -License: MIT License -Copyright: 2019-present Rollup Plugins contributors - ---- - -Rollup-plugin-esbuild: A Rollup plugin for using esbuild - -URL: https://github.com/egoist/rollup-plugin-esbuild -License: MIT License -Copyright: 2020 EGOIST - ---- - -Rollup-plugin-import-css: A Rollup plugin for importing CSS files - -URL: https://github.com/jleeson/rollup-plugin-import-css -License: MIT License -Copyright: 2020 Jacob Leeson - ---- - rxjs: Reactive Extensions for JavaScript URL: https://rxjs.dev/ From 843344f06aa1332877f05d35a644fd6e57df8c4f Mon Sep 17 00:00:00 2001 From: Lee Kelleher Date: Mon, 1 Sep 2025 16:15:35 +0100 Subject: [PATCH 33/33] Tiptap RTE: Unbundled "Rich Text Essentials" - Toggle basics on/off per data type (#20042) * Tiptap RTE: Starter Kit separation - Created extensions for each Tiptap capability/extension - Deprecated native `StarterKit` Tiptap extension - Re-organized all Tiptap extensions into their own feature folders - Other minor amends/tweaks to improve accessibility * Update src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/view-source/manifests.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/toolbar-configuration/property-editor-ui-tiptap-toolbar-configuration.element.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/statusbar-configuration/property-editor-ui-tiptap-statusbar-configuration.element.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Minor lint * Mark the "external" Tiptap exports as deprecated --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/Umbraco.Web.UI.Client/package-lock.json | 19 + .../src/assets/lang/en.ts | 1 + .../extensions/tiptap-anchor.extension.ts | 1 + .../tiptap/extensions/tiptap-div.extension.ts | 2 + .../extensions/tiptap-figcaption.extension.ts | 2 + .../extensions/tiptap-figure.extension.ts | 2 + ...tiptap-html-global-attributes.extension.ts | 2 + .../extensions/tiptap-span.extension.ts | 2 + .../tiptap-text-direction-extension.ts | 2 + .../tiptap-text-indent-extension.ts | 2 + .../tiptap-trailing-node.extension.ts | 2 + .../tiptap-umb-bubble-menu.extension.ts | 5 + .../tiptap-umb-embedded-media.extension.ts | 2 + .../extensions/tiptap-umb-image.extension.ts | 2 + .../extensions/tiptap-umb-link.extension.ts | 4 + .../extensions/tiptap-umb-table.extension.ts | 5 + .../src/external/tiptap/index.ts | 152 +++- .../src/external/tiptap/package.json | 19 + .../menu-item/action/action-menu-item.api.ts | 5 + .../rte/components/rte-base.element.ts | 2 + .../components/anchor-modal/manifests.ts | 11 - .../cascading-menu-popover/index.ts | 1 + .../components/character-map/manifests.ts | 11 - .../src/packages/tiptap/components/index.ts | 4 +- .../input-tiptap/input-tiptap.element.ts | 21 +- .../packages/tiptap/components/manifests.ts | 4 - .../components/menu/tiptap-menu.element.ts | 4 +- .../tiptap-statusbar.element.ts | 2 +- .../toolbar/tiptap-toolbar-button.element.ts | 2 +- ...tap-toolbar-color-picker-button.element.ts | 13 +- .../toolbar/tiptap-toolbar-menu.element.ts | 15 +- .../tiptap-toolbar.element.ts | 2 +- .../src/packages/tiptap/constants.ts | 6 +- .../extensions/anchor/anchor.tiptap-api.ts | 23 + .../anchor.tiptap-toolbar-api.ts | 4 +- .../tiptap/extensions/anchor/constants.ts | 1 + .../tiptap/extensions/anchor/index.ts | 1 + .../tiptap/extensions/anchor/manifests.ts | 34 + .../anchor/modals}/anchor-modal.element.ts | 0 .../anchor/modals}/anchor-modal.token.ts | 0 .../anchor/modals}/constants.ts | 0 .../anchor/modals}/index.ts | 0 .../extensions/block/block.tipap-api.ts | 2 +- .../block/block.tiptap-toolbar-api.ts | 2 +- .../blockquote/blockquote.tiptap-api.ts | 15 + .../blockquote.tiptap-toolbar-api.ts | 2 +- .../tiptap/extensions/blockquote/manifests.ts | 26 + .../tiptap/extensions/bold/bold.tiptap-api.ts | 6 + .../bold.tiptap-toolbar-api.ts | 2 +- .../tiptap/extensions/bold/manifests.ts | 26 + .../bullet-list/bullet-list.tiptap-api.ts | 16 + .../bullet-list.tiptap-toolbar-api.ts | 2 +- .../extensions/bullet-list/manifests.ts | 26 + .../character-map.tiptap-toolbar-api.ts | 4 +- .../extensions/character-map/constants.ts | 1 + .../tiptap/extensions/character-map/index.ts | 1 + .../extensions/character-map/manifests.ts | 22 + .../modals}/character-map-modal.element.ts | 0 .../modals}/character-map-modal.token.ts | 0 .../character-map/modals}/constants.ts | 0 .../character-map/modals}/index.ts | 0 .../clear-formatting.tiptap-toolbar-api.ts | 2 +- .../extensions/clear-formatting/manifests.ts | 14 + .../code-block/code-block.tiptap-api.ts | 30 + .../code-block.tiptap-toolbar-api.ts | 2 +- .../tiptap/extensions/code-block/manifests.ts | 26 + .../packages/tiptap/extensions/constants.ts | 3 + .../tiptap/extensions/core/manifests.ts | 15 + .../core/rich-text-essentials.tiptap-api.ts | 111 +-- .../default-tiptap-toolbar-api.ts | 2 +- .../element-path.tiptap-statusbar-element.ts | 0 .../extensions/element-path/manifests.ts | 13 + .../embedded-media.tiptap-api.ts | 3 +- .../embedded-media.tiptap-toolbar-api.ts | 2 +- .../extensions/embedded-media/manifests.ts | 26 + .../{core => figure}/figure.tiptap-api.ts | 3 +- .../tiptap/extensions/figure/manifests.ts | 13 + .../font-family.tiptap-toolbar-api.ts | 2 +- .../extensions/font-family/manifests.ts | 35 + .../font-size.tiptap-toolbar-api.ts | 2 +- .../tiptap/extensions/font-size/manifests.ts | 39 + .../extensions/heading/heading.tiptap-api.ts | 19 + .../heading1.tiptap-toolbar-api.ts | 2 +- .../heading2.tiptap-toolbar-api.ts | 2 +- .../heading3.tiptap-toolbar-api.ts | 2 +- .../tiptap/extensions/heading/manifests.ts | 52 ++ .../horizontal-rule.tiptap-api.ts | 6 + .../horizontal-rule.tiptap-toolbar-api.ts | 2 +- .../extensions/horizontal-rule/manifests.ts | 25 + .../html-attr-class.tiptap-api.ts | 95 +++ .../extensions/html-attr-class/manifests.ts | 13 + .../html-attr-dataset.tiptap-api.ts | 115 +++ .../extensions/html-attr-dataset/manifests.ts | 13 + .../html-attr-id/html-attr-id.tiptap-api.ts | 93 +++ .../extensions/html-attr-id/manifests.ts | 13 + .../html-attr-style.tiptap-api.ts | 97 +++ .../extensions/html-attr-style/manifests.ts | 13 + .../html-tag-div/html-tag-div.tiptap-api.ts | 7 + .../extensions/html-tag-div/manifests.ts | 13 + .../html-tag-span/html-tag-span.tiptap-api.ts | 7 + .../extensions/html-tag-span/manifests.ts | 13 + .../{core => image}/image.tiptap-api.ts | 3 +- .../tiptap/extensions/image/manifests.ts | 13 + .../src/packages/tiptap/extensions/index.ts | 6 +- .../extensions/italic/italic.tiptap-api.ts | 7 + .../italic.tiptap-toolbar-api.ts | 2 +- .../tiptap/extensions/italic/manifests.ts | 26 + .../{core => link}/link.tiptap-api.ts | 3 +- .../link.tiptap-toolbar-api.ts | 2 +- .../tiptap/extensions/link/manifests.ts | 40 + .../unlink.tiptap-toolbar-api.ts | 2 +- .../packages/tiptap/extensions/manifests.ts | 762 ++---------------- .../extensions/media-picker/manifests.ts | 15 + .../media-picker.tiptap-toolbar-api.ts | 2 +- .../extensions/media-upload/manifests.ts | 13 + .../media-upload.tiptap-api.ts | 2 +- .../extensions/ordered-list/manifests.ts | 26 + .../ordered-list/ordered-list.tiptap-api.ts | 16 + .../ordered-list.tiptap-toolbar-api.ts | 2 +- .../tiptap/extensions/strike/manifests.ts | 26 + .../extensions/strike/strike.tiptap-api.ts | 6 + .../strike.tiptap-toolbar-api.ts | 2 +- .../extensions/style-menu/style-menu.kind.ts | 12 + .../style-menu.tiptap-toolbar-api.ts | 2 +- .../style-select.tiptap-toolbar-api.ts | 2 +- .../tiptap/extensions/subscript/manifests.ts | 27 + .../subscript.tiptap-api.ts | 2 +- .../subscript.tiptap-toolbar-api.ts | 2 +- .../extensions/superscript/manifests.ts | 27 + .../superscript.tiptap-api.ts | 2 +- .../superscript.tiptap-toolbar-api.ts | 2 +- .../table/actions/table-properties.action.ts | 2 +- .../components/table-column-menu.element.ts | 2 +- .../components/table-row-menu.element.ts | 2 +- .../tiptap/extensions/table/constants.ts | 1 + .../packages/tiptap/extensions/table/index.ts | 2 +- .../tiptap/extensions/table/manifests.ts | 4 +- .../table/{components => modals}/constants.ts | 0 .../tiptap/extensions/table/modals/index.ts | 1 + .../table-properties-modal.element.ts | 0 .../table-properties-modal.token.ts | 0 .../extensions/table/table.tiptap-api.ts | 3 +- .../table/table.tiptap-toolbar-api.ts | 6 +- .../tiptap/extensions/text-align/manifests.ts | 65 ++ .../text-align-center.tiptap-toolbar-api.ts | 2 +- .../text-align-justify.tiptap-toolbar-api.ts | 2 +- .../text-align-left.tiptap-toolbar-api.ts | 2 +- .../text-align-right.tiptap-toolbar-api.ts | 2 +- .../text-align.tiptap-api.ts | 2 +- .../tiptap/extensions/text-color/manifests.ts | 28 + ...ext-color-background.tiptap-toolbar-api.ts | 2 +- ...ext-color-foreground.tiptap-toolbar-api.ts | 2 +- .../extensions/text-direction/manifests.ts | 39 + .../text-direction-ltr.tiptap-toolbar-api.ts | 2 +- .../text-direction-rtl.tiptap-toolbar-api.ts | 2 +- .../text-direction.tiptap-api.ts | 3 +- .../extensions/text-indent/manifests.ts | 39 + .../text-indent.tiptap-api.ts | 3 +- .../text-indent.tiptap-toolbar-api.ts | 2 +- .../text-outdent.tiptap-toolbar-api.ts | 2 +- .../extensions/tiptap-extension-api-base.ts | 35 + .../extensions/tiptap-toolbar-button.kind.ts | 11 + ...tiptap-toolbar-color-picker-button.kind.ts | 11 + ....ts => tiptap-toolbar-element-api-base.ts} | 42 +- .../extensions/tiptap-toolbar-menu.kind.ts | 11 + .../extensions/trailing-node/manifests.ts | 13 + .../trailing-node/trailing-node.tiptap-api.ts | 7 + .../tiptap/extensions/underline/manifests.ts | 27 + .../underline.tiptap-api.ts | 2 +- .../underline.tiptap-toolbar-api.ts | 2 +- .../tiptap/extensions/undo-redo/manifests.ts | 28 + .../redo.tiptap-toolbar-api.ts | 2 +- .../undo.tiptap-toolbar-api.ts | 2 +- .../extensions/view-source/manifests.ts | 14 + .../source-editor.tiptap-toolbar-api.ts | 2 +- .../{statusbar => word-count}/manifests.ts | 50 +- .../word-count.tiptap-api.ts | 2 +- .../word-count.tiptap-statusbar-element.ts | 0 .../src/packages/tiptap/manifests.ts | 7 +- .../tiptap/property-editors/constants.ts | 2 + .../extensions-configuration/manifests.ts | 15 + ...tiptap-extensions-configuration.element.ts | 13 +- .../tiptap/property-editors/manifests.ts | 13 +- .../statusbar-configuration/manifests.ts | 15 + ...-tiptap-statusbar-configuration.element.ts | 8 +- ...p-statusbar-configuration.context-token.ts | 0 .../tiptap-statusbar-configuration.context.ts | 2 +- .../{tiptap => tiptap-rte}/manifests.ts | 33 - .../property-editor-ui-tiptap.element.ts | 1 + .../property-editor-ui-tiptap.stories.ts | 6 + .../property-editor-ui-tiptap.test.ts | 0 .../property-editors/tiptap/constants.ts | 2 - .../toolbar-configuration/manifests.ts | 15 + ...ui-tiptap-toolbar-configuration.element.ts | 8 +- ...tap-toolbar-configuration.context-token.ts | 0 .../tiptap-toolbar-configuration.context.ts | 2 +- ...tap-toolbar-group-configuration.element.ts | 2 +- .../property-editors/{tiptap => }/types.ts | 0 198 files changed, 2129 insertions(+), 1042 deletions(-) delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/components/anchor-modal/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/components/cascading-menu-popover/index.ts delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/components/character-map/manifests.ts delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/components/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/components/{input-tiptap => statusbar}/tiptap-statusbar.element.ts (98%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/components/{input-tiptap => toolbar}/tiptap-toolbar.element.ts (98%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/anchor/anchor.tiptap-api.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => anchor}/anchor.tiptap-toolbar-api.ts (85%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/anchor/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/anchor/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/anchor/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/{components/anchor-modal => extensions/anchor/modals}/anchor-modal.element.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/{components/anchor-modal => extensions/anchor/modals}/anchor-modal.token.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/{components/anchor-modal => extensions/anchor/modals}/constants.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/{components/anchor-modal => extensions/anchor/modals}/index.ts (100%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/blockquote/blockquote.tiptap-api.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => blockquote}/blockquote.tiptap-toolbar-api.ts (75%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/blockquote/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/bold/bold.tiptap-api.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => bold}/bold.tiptap-toolbar-api.ts (74%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/bold/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/bullet-list/bullet-list.tiptap-api.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => bullet-list}/bullet-list.tiptap-toolbar-api.ts (75%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/bullet-list/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => character-map}/character-map.tiptap-toolbar-api.ts (81%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/character-map/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/character-map/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/character-map/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/{components/character-map => extensions/character-map/modals}/character-map-modal.element.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/{components/character-map => extensions/character-map/modals}/character-map-modal.token.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/{components/character-map => extensions/character-map/modals}/constants.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/{components/character-map => extensions/character-map/modals}/index.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => clear-formatting}/clear-formatting.tiptap-toolbar-api.ts (78%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/clear-formatting/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/code-block/code-block.tiptap-api.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => code-block}/code-block.tiptap-toolbar-api.ts (78%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/code-block/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/core/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/{components/toolbar => extensions}/default-tiptap-toolbar-api.ts (60%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{statusbar => element-path}/element-path.tiptap-statusbar-element.ts (100%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/element-path/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{core => embedded-media}/embedded-media.tiptap-api.ts (84%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => embedded-media}/embedded-media.tiptap-toolbar-api.ts (92%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/embedded-media/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{core => figure}/figure.tiptap-api.ts (60%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/figure/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => font-family}/font-family.tiptap-toolbar-api.ts (87%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/font-family/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => font-size}/font-size.tiptap-toolbar-api.ts (87%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/font-size/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/heading/heading.tiptap-api.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => heading}/heading1.tiptap-toolbar-api.ts (81%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => heading}/heading2.tiptap-toolbar-api.ts (81%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => heading}/heading3.tiptap-toolbar-api.ts (81%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/heading/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/horizontal-rule/horizontal-rule.tiptap-api.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => horizontal-rule}/horizontal-rule.tiptap-toolbar-api.ts (75%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/horizontal-rule/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/html-attr-class/html-attr-class.tiptap-api.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/html-attr-class/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/html-attr-dataset/html-attr-dataset.tiptap-api.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/html-attr-dataset/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/html-attr-id/html-attr-id.tiptap-api.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/html-attr-id/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/html-attr-style/html-attr-style.tiptap-api.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/html-attr-style/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/html-tag-div/html-tag-div.tiptap-api.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/html-tag-div/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/html-tag-span/html-tag-span.tiptap-api.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/html-tag-span/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{core => image}/image.tiptap-api.ts (81%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/image/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/italic/italic.tiptap-api.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => italic}/italic.tiptap-toolbar-api.ts (74%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/italic/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{core => link}/link.tiptap-api.ts (62%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => link}/link.tiptap-toolbar-api.ts (98%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/link/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => link}/unlink.tiptap-toolbar-api.ts (82%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/media-picker/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => media-picker}/media-picker.tiptap-toolbar-api.ts (98%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/media-upload/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{core => media-upload}/media-upload.tiptap-api.ts (98%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/ordered-list/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/ordered-list/ordered-list.tiptap-api.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => ordered-list}/ordered-list.tiptap-toolbar-api.ts (82%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/strike/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/strike/strike.tiptap-api.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => strike}/strike.tiptap-toolbar-api.ts (74%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/style-menu/style-menu.kind.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/{components/toolbar => extensions/style-menu}/style-menu.tiptap-toolbar-api.ts (96%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/subscript/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{core => subscript}/subscript.tiptap-api.ts (71%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => subscript}/subscript.tiptap-toolbar-api.ts (75%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/superscript/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{core => superscript}/superscript.tiptap-api.ts (72%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => superscript}/superscript.tiptap-toolbar-api.ts (75%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/table/constants.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/table/{components => modals}/constants.ts (100%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/table/modals/index.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/table/{components => modals}/table-properties-modal.element.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/table/{components => modals}/table-properties-modal.token.ts (100%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/text-align/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => text-align}/text-align-center.tiptap-toolbar-api.ts (84%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => text-align}/text-align-justify.tiptap-toolbar-api.ts (84%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => text-align}/text-align-left.tiptap-toolbar-api.ts (84%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => text-align}/text-align-right.tiptap-toolbar-api.ts (84%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{core => text-align}/text-align.tiptap-api.ts (80%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/text-color/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => text-color}/text-color-background.tiptap-toolbar-api.ts (79%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => text-color}/text-color-foreground.tiptap-toolbar-api.ts (78%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/text-direction/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => text-direction}/text-direction-ltr.tiptap-toolbar-api.ts (85%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => text-direction}/text-direction-rtl.tiptap-toolbar-api.ts (84%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{core => text-direction}/text-direction.tiptap-api.ts (69%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/text-indent/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{core => text-indent}/text-indent.tiptap-api.ts (69%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => text-indent}/text-indent.tiptap-toolbar-api.ts (74%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => text-indent}/text-outdent.tiptap-toolbar-api.ts (74%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/tiptap-extension-api-base.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/tiptap-toolbar-button.kind.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/tiptap-toolbar-color-picker-button.kind.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{base.ts => tiptap-toolbar-element-api-base.ts} (66%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/tiptap-toolbar-menu.kind.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/trailing-node/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/trailing-node/trailing-node.tiptap-api.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/underline/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{core => underline}/underline.tiptap-api.ts (72%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => underline}/underline.tiptap-toolbar-api.ts (75%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/undo-redo/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => undo-redo}/redo.tiptap-toolbar-api.ts (81%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => undo-redo}/undo.tiptap-toolbar-api.ts (81%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/view-source/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{toolbar => view-source}/source-editor.tiptap-toolbar-api.ts (90%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{statusbar => word-count}/manifests.ts (57%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{core => word-count}/word-count.tiptap-api.ts (80%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/{statusbar => word-count}/word-count.tiptap-statusbar-element.ts (100%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/extensions-configuration/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/{tiptap/components => extensions-configuration}/property-editor-ui-tiptap-extensions-configuration.element.ts (94%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/statusbar-configuration/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/{tiptap/components => statusbar-configuration}/property-editor-ui-tiptap-statusbar-configuration.element.ts (97%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/{tiptap/contexts => statusbar-configuration}/tiptap-statusbar-configuration.context-token.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/{tiptap/contexts => statusbar-configuration}/tiptap-statusbar-configuration.context.ts (98%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/{tiptap => tiptap-rte}/manifests.ts (75%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/{tiptap => tiptap-rte}/property-editor-ui-tiptap.element.ts (99%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/{tiptap => tiptap-rte}/property-editor-ui-tiptap.stories.ts (93%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/{tiptap => tiptap-rte}/property-editor-ui-tiptap.test.ts (100%) delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/toolbar-configuration/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/{tiptap/components => toolbar-configuration}/property-editor-ui-tiptap-toolbar-configuration.element.ts (98%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/{tiptap/contexts => toolbar-configuration}/tiptap-toolbar-configuration.context-token.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/{tiptap/contexts => toolbar-configuration}/tiptap-toolbar-configuration.context.ts (99%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/{tiptap/components => toolbar-configuration}/tiptap-toolbar-group-configuration.element.ts (97%) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/{tiptap => }/types.ts (100%) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 1e44328da8..d3ed09bef3 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -17064,17 +17064,36 @@ "name": "@umbraco-backoffice/external-tiptap", "dependencies": { "@tiptap/core": "2.26.1", + "@tiptap/extension-blockquote": "2.26.1", + "@tiptap/extension-bold": "2.26.1", + "@tiptap/extension-bullet-list": "2.26.1", "@tiptap/extension-character-count": "2.26.1", + "@tiptap/extension-code": "2.26.1", + "@tiptap/extension-code-block": "2.26.1", + "@tiptap/extension-document": "2.26.1", + "@tiptap/extension-dropcursor": "2.26.1", + "@tiptap/extension-gapcursor": "2.26.1", + "@tiptap/extension-hard-break": "2.26.1", + "@tiptap/extension-heading": "2.26.1", + "@tiptap/extension-history": "2.26.1", + "@tiptap/extension-horizontal-rule": "2.26.1", "@tiptap/extension-image": "2.26.1", + "@tiptap/extension-italic": "2.26.1", "@tiptap/extension-link": "2.26.1", + "@tiptap/extension-list-item": "2.26.1", + "@tiptap/extension-ordered-list": "2.26.1", + "@tiptap/extension-paragraph": "2.26.1", "@tiptap/extension-placeholder": "2.26.1", + "@tiptap/extension-strike": "2.26.1", "@tiptap/extension-subscript": "2.26.1", "@tiptap/extension-superscript": "2.26.1", "@tiptap/extension-table": "2.26.1", "@tiptap/extension-table-cell": "2.26.1", "@tiptap/extension-table-header": "2.26.1", "@tiptap/extension-table-row": "2.26.1", + "@tiptap/extension-text": "2.26.1", "@tiptap/extension-text-align": "2.26.1", + "@tiptap/extension-text-style": "2.26.1", "@tiptap/extension-underline": "2.26.1", "@tiptap/pm": "2.26.1", "@tiptap/starter-kit": "2.26.1" diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts index d4806a5f1b..4fd053f152 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts @@ -2792,6 +2792,7 @@ export default { config_statusbar: 'Statusbar', config_toolbar: 'Toolbar', extGroup_formatting: 'Text formatting', + extGroup_html: 'HTML', extGroup_interactive: 'Interactive elements', extGroup_media: 'Embeds and media', extGroup_structure: 'Content structure', diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-anchor.extension.ts b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-anchor.extension.ts index 12c5a2b0ec..fda5a77bfc 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-anchor.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-anchor.extension.ts @@ -1,5 +1,6 @@ import { Node, mergeAttributes } from '@tiptap/core'; +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const Anchor = Node.create({ name: 'anchor', diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-div.extension.ts b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-div.extension.ts index e7855d4288..374acf2557 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-div.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-div.extension.ts @@ -1,5 +1,6 @@ import { Node, mergeAttributes } from '@tiptap/core'; +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export interface DivOptions { /** * HTML attributes to add to the element. @@ -9,6 +10,7 @@ export interface DivOptions { HTMLAttributes: Record; } +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const Div = Node.create({ name: 'div', diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-figcaption.extension.ts b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-figcaption.extension.ts index ea2f2ab83e..8a1bce8d40 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-figcaption.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-figcaption.extension.ts @@ -1,5 +1,6 @@ import { Node } from '@tiptap/core'; +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export interface FigcaptionOptions { /** * HTML attributes to add to the image element. @@ -9,6 +10,7 @@ export interface FigcaptionOptions { HTMLAttributes: Record; } +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const Figcaption = Node.create({ name: 'figcaption', diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-figure.extension.ts b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-figure.extension.ts index 49a89606df..4e4b67a308 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-figure.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-figure.extension.ts @@ -1,5 +1,6 @@ import { mergeAttributes, Node } from '@tiptap/core'; +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export interface FigureOptions { /** * HTML attributes to add to the image element. @@ -9,6 +10,7 @@ export interface FigureOptions { HTMLAttributes: Record; } +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const Figure = Node.create({ name: 'figure', group: 'block', diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-html-global-attributes.extension.ts b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-html-global-attributes.extension.ts index 69c0cbdd1f..06454f82b9 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-html-global-attributes.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-html-global-attributes.extension.ts @@ -10,6 +10,7 @@ function camelCaseToKebabCase(str: string): string { return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, ($, ofs) => (ofs ? '-' : '') + $.toLowerCase()); } +/** @deprecated No longer used internally. This will be removed in Umbraco 17. [LK] */ export interface HtmlGlobalAttributesOptions { /** * The types where the text align attribute can be applied. @@ -19,6 +20,7 @@ export interface HtmlGlobalAttributesOptions { types: Array; } +/** @deprecated No longer used internally. This will be removed in Umbraco 17. [LK] */ export const HtmlGlobalAttributes = Extension.create({ name: 'htmlGlobalAttributes', diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-span.extension.ts b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-span.extension.ts index e0adabf8af..bee0cd8632 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-span.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-span.extension.ts @@ -1,5 +1,6 @@ import { Mark, mergeAttributes } from '@tiptap/core'; +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export interface SpanOptions { /** * HTML attributes to add to the span element. @@ -34,6 +35,7 @@ function serializeStyles(items: Record): string { ); } +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const Span = Mark.create({ name: 'span', diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-text-direction-extension.ts b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-text-direction-extension.ts index 914d151cd1..96727e9dae 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-text-direction-extension.ts +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-text-direction-extension.ts @@ -1,10 +1,12 @@ import { Extension } from '@tiptap/core'; +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export interface TextDirectionOptions { directions: Array<'auto' | 'ltr' | 'rtl'>; types: Array; } +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const TextDirection = Extension.create({ name: 'textDirection', diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-text-indent-extension.ts b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-text-indent-extension.ts index 7df5d4043e..a39c10605d 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-text-indent-extension.ts +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-text-indent-extension.ts @@ -11,12 +11,14 @@ import type { EditorState, Transaction } from '@tiptap/pm/state'; import { Extension } from '@tiptap/core'; import { AllSelection, TextSelection } from '@tiptap/pm/state'; +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export interface TextIndentOptions { minLevel: number; maxLevel: number; types: Array; } +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const TextIndent = Extension.create({ name: 'textIndent', diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-trailing-node.extension.ts b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-trailing-node.extension.ts index f76956fa90..ec7f4144f1 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-trailing-node.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-trailing-node.extension.ts @@ -13,11 +13,13 @@ function nodeEqualsType({ types, node }) { return (Array.isArray(types) && types.includes(node.type)) || node.type === types; } +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export interface TrailingNodeOptions { node: string; notAfter: string[]; } +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const TrailingNode = Extension.create({ name: 'trailingNode', diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-bubble-menu.extension.ts b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-bubble-menu.extension.ts index f2b080c42e..a34064ae9c 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-bubble-menu.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-bubble-menu.extension.ts @@ -5,11 +5,13 @@ import { EditorState, Plugin, PluginKey } from '@tiptap/pm/state'; import { EditorView } from '@tiptap/pm/view'; import type { PluginView } from '@tiptap/pm/state'; +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export interface UmbTiptapBubbleMenuElement extends HTMLElement { editor?: Editor; menuAlias?: string; } +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export type UmbBubbleMenuPluginProps = { unique: string; placement?: UUIPopoverContainerElement['placement']; @@ -20,8 +22,10 @@ export type UmbBubbleMenuPluginProps = { | null; }; +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export type UmbBubbleMenuOptions = UmbBubbleMenuPluginProps; +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const UmbBubbleMenu = Extension.create({ name: 'umbBubbleMenu', @@ -104,6 +108,7 @@ class UmbBubbleMenuPluginView implements PluginView { } } +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const UmbBubbleMenuPlugin = (editor: Editor, props: UmbBubbleMenuPluginProps) => { return new Plugin({ view(editorView) { diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-embedded-media.extension.ts b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-embedded-media.extension.ts index daecec2468..fce7c67a48 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-embedded-media.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-embedded-media.extension.ts @@ -1,9 +1,11 @@ import { mergeAttributes, Node } from '@tiptap/core'; +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export interface UmbEmbeddedMediaOptions { inline: boolean; } +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const umbEmbeddedMedia = Node.create({ name: 'umbEmbeddedMedia', group() { diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-image.extension.ts b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-image.extension.ts index 84acd5b11d..1f91f7e958 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-image.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-image.extension.ts @@ -1,5 +1,6 @@ import Image from '@tiptap/extension-image'; +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export interface UmbImageAttributes { src: string; alt?: string; @@ -13,6 +14,7 @@ export interface UmbImageAttributes { 'data-udi'?: string; } +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const UmbImage = Image.extend({ addAttributes() { return { diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-link.extension.ts b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-link.extension.ts index 9ba9433993..ef7e66617e 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-link.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-link.extension.ts @@ -1,5 +1,6 @@ import Link from '@tiptap/extension-link'; +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const UmbLink = Link.extend({ name: 'umbLink', @@ -12,6 +13,9 @@ export const UmbLink = Link.extend({ }; }, + // TODO: [LK] Look to use a NodeView to render the link + // https://tiptap.dev/docs/editor/extensions/custom-extensions/node-views/javascript + addOptions() { return { ...this.parent?.(), diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-table.extension.ts b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-table.extension.ts index df5ec8a8fb..a06850f076 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-table.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/extensions/tiptap-umb-table.extension.ts @@ -12,6 +12,7 @@ import type { Rect } from '@tiptap/pm/tables'; // NOTE: Custom TableView, to allow for custom styles to be applied to the element. [LK] // ref: https://github.com/ueberdosis/tiptap/blob/v2.11.5/packages/extension-table/src/TableView.ts +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export class UmbTableView extends TableView { constructor(node: ProseMirrorNode, cellMinWidth: number) { super(node, cellMinWidth); @@ -34,13 +35,16 @@ export class UmbTableView extends TableView { } } +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const UmbTable = Table.configure({ resizable: true, View: UmbTableView }); +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const UmbTableRow = TableRow.extend({ allowGapCursor: false, content: '(tableCell | tableHeader)*', }); +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const UmbTableHeader = TableHeader.extend({ addAttributes() { return { @@ -122,6 +126,7 @@ export const UmbTableHeader = TableHeader.extend({ }, }); +/** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ export const UmbTableCell = TableCell.extend({ addAttributes() { return { diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/index.ts b/src/Umbraco.Web.UI.Client/src/external/tiptap/index.ts index 9bb1aedd28..1cfd0f26bd 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/index.ts +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/index.ts @@ -1,32 +1,134 @@ // REQUIRED EXTENSIONS export * from '@tiptap/core'; -export { StarterKit } from '@tiptap/starter-kit'; -export { Placeholder } from '@tiptap/extension-placeholder'; -export { TextStyle } from '@tiptap/extension-text-style'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Document, +} from '@tiptap/extension-document'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Dropcursor, +} from '@tiptap/extension-dropcursor'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Gapcursor, +} from '@tiptap/extension-gapcursor'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + HardBreak, +} from '@tiptap/extension-hard-break'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + History, +} from '@tiptap/extension-history'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Paragraph, +} from '@tiptap/extension-paragraph'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Placeholder, +} from '@tiptap/extension-placeholder'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Text, +} from '@tiptap/extension-text'; // OPTIONAL EXTENSIONS -export { Blockquote } from '@tiptap/extension-blockquote'; -export { Bold } from '@tiptap/extension-bold'; -export { BulletList } from '@tiptap/extension-bullet-list'; -export { CharacterCount } from '@tiptap/extension-character-count'; -export { Code } from '@tiptap/extension-code'; -export { CodeBlock } from '@tiptap/extension-code-block'; -export { Heading } from '@tiptap/extension-heading'; -export { HorizontalRule } from '@tiptap/extension-horizontal-rule'; -export { Image } from '@tiptap/extension-image'; -export { Italic } from '@tiptap/extension-italic'; -export { Link } from '@tiptap/extension-link'; -export { ListItem } from '@tiptap/extension-list-item'; -export { OrderedList } from '@tiptap/extension-ordered-list'; -export { Strike } from '@tiptap/extension-strike'; -export { Subscript } from '@tiptap/extension-subscript'; -export { Superscript } from '@tiptap/extension-superscript'; -export { Table } from '@tiptap/extension-table'; -export { TableCell } from '@tiptap/extension-table-cell'; -export { TableHeader } from '@tiptap/extension-table-header'; -export { TableRow } from '@tiptap/extension-table-row'; -export { TextAlign } from '@tiptap/extension-text-align'; -export { Underline } from '@tiptap/extension-underline'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Blockquote, +} from '@tiptap/extension-blockquote'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Bold, +} from '@tiptap/extension-bold'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + BulletList, +} from '@tiptap/extension-bullet-list'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + CharacterCount, +} from '@tiptap/extension-character-count'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Code, +} from '@tiptap/extension-code'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + CodeBlock, +} from '@tiptap/extension-code-block'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Heading, +} from '@tiptap/extension-heading'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + HorizontalRule, +} from '@tiptap/extension-horizontal-rule'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Image, +} from '@tiptap/extension-image'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Italic, +} from '@tiptap/extension-italic'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Link, +} from '@tiptap/extension-link'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + ListItem, +} from '@tiptap/extension-list-item'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + OrderedList, +} from '@tiptap/extension-ordered-list'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Strike, +} from '@tiptap/extension-strike'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Subscript, +} from '@tiptap/extension-subscript'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Superscript, +} from '@tiptap/extension-superscript'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Table, +} from '@tiptap/extension-table'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + TableCell, +} from '@tiptap/extension-table-cell'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + TableHeader, +} from '@tiptap/extension-table-header'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + TableRow, +} from '@tiptap/extension-table-row'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + TextAlign, +} from '@tiptap/extension-text-align'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + TextStyle, +} from '@tiptap/extension-text-style'; +export { + /** @deprecated This will be relocated in Umbraco 17 to the "@umbraco-cms/backoffice/tiptap" module. [LK] */ + Underline, +} from '@tiptap/extension-underline'; + +/** @deprecated No longer used internally. This will be removed in Umbraco 18. [LK] */ +export { StarterKit } from '@tiptap/starter-kit'; // CUSTOM EXTENSIONS export * from './extensions/tiptap-anchor.extension.js'; diff --git a/src/Umbraco.Web.UI.Client/src/external/tiptap/package.json b/src/Umbraco.Web.UI.Client/src/external/tiptap/package.json index 11938ce31a..61a34ee1c9 100644 --- a/src/Umbraco.Web.UI.Client/src/external/tiptap/package.json +++ b/src/Umbraco.Web.UI.Client/src/external/tiptap/package.json @@ -7,10 +7,27 @@ }, "dependencies": { "@tiptap/core": "2.26.1", + "@tiptap/extension-blockquote": "2.26.1", + "@tiptap/extension-bold": "2.26.1", + "@tiptap/extension-bullet-list": "2.26.1", "@tiptap/extension-character-count": "2.26.1", + "@tiptap/extension-code-block": "2.26.1", + "@tiptap/extension-code": "2.26.1", + "@tiptap/extension-document": "2.26.1", + "@tiptap/extension-dropcursor": "2.26.1", + "@tiptap/extension-gapcursor": "2.26.1", + "@tiptap/extension-hard-break": "2.26.1", + "@tiptap/extension-heading": "2.26.1", + "@tiptap/extension-history": "2.26.1", + "@tiptap/extension-horizontal-rule": "2.26.1", "@tiptap/extension-image": "2.26.1", + "@tiptap/extension-italic": "2.26.1", "@tiptap/extension-link": "2.26.1", + "@tiptap/extension-list-item": "2.26.1", + "@tiptap/extension-ordered-list": "2.26.1", + "@tiptap/extension-paragraph": "2.26.1", "@tiptap/extension-placeholder": "2.26.1", + "@tiptap/extension-strike": "2.26.1", "@tiptap/extension-subscript": "2.26.1", "@tiptap/extension-superscript": "2.26.1", "@tiptap/extension-table": "2.26.1", @@ -18,6 +35,8 @@ "@tiptap/extension-table-header": "2.26.1", "@tiptap/extension-table-row": "2.26.1", "@tiptap/extension-text-align": "2.26.1", + "@tiptap/extension-text-style": "2.26.1", + "@tiptap/extension-text": "2.26.1", "@tiptap/extension-underline": "2.26.1", "@tiptap/pm": "2.26.1", "@tiptap/starter-kit": "2.26.1" diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/action/action-menu-item.api.ts b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/action/action-menu-item.api.ts index fc355cb98e..ea8daf3344 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/action/action-menu-item.api.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/menu/components/menu-item/action/action-menu-item.api.ts @@ -5,6 +5,11 @@ export abstract class UmbMenuItemActionApiBase extends UmbActionBase> implements UmbMenuItemActionApi { + /** + * By specifying the `execute` method, the action will act as a button. + * @abstract + * @returns {Promise} + */ public execute(): Promise { return Promise.resolve(); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts b/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts index de1c417a04..ef841b82fc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/rte/components/rte-base.element.ts @@ -34,6 +34,8 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbFormControlMixin(UmbLitElement) implements UmbPropertyEditorUiElement { + public name?: string; + public set config(config: UmbPropertyEditorConfigCollection | undefined) { if (!config) return; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/anchor-modal/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/anchor-modal/manifests.ts deleted file mode 100644 index 99bbb4a2b5..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/anchor-modal/manifests.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { UMB_TIPTAP_ANCHOR_MODAL_ALIAS } from './constants.js'; -import type { ManifestModal } from '@umbraco-cms/backoffice/modal'; - -export const manifests: Array = [ - { - type: 'modal', - alias: UMB_TIPTAP_ANCHOR_MODAL_ALIAS, - name: 'Tiptap Anchor Modal', - element: () => import('./anchor-modal.element.js'), - }, -]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/cascading-menu-popover/index.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/cascading-menu-popover/index.ts new file mode 100644 index 0000000000..ec606adf12 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/cascading-menu-popover/index.ts @@ -0,0 +1 @@ +export * from './cascading-menu-popover.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/character-map/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/character-map/manifests.ts deleted file mode 100644 index a238e84eb3..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/character-map/manifests.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { UMB_TIPTAP_CHARACTER_MAP_MODAL_ALIAS } from './constants.js'; -import type { ManifestModal } from '@umbraco-cms/backoffice/modal'; - -export const manifests: Array = [ - { - type: 'modal', - alias: UMB_TIPTAP_CHARACTER_MAP_MODAL_ALIAS, - name: 'Character Map Modal', - element: () => import('./character-map-modal.element.js'), - }, -]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/index.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/index.ts index 56491b08d4..cc425ff2d0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/index.ts @@ -1,5 +1,3 @@ +export * from './cascading-menu-popover/index.js'; export * from './input-tiptap/index.js'; -export * from './anchor-modal/index.js'; -export * from './cascading-menu-popover/cascading-menu-popover.element.js'; -export * from './character-map/index.js'; export * from './menu/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/input-tiptap.element.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/input-tiptap.element.ts index 0bb9fdbc66..03ef568b09 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/input-tiptap.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/input-tiptap.element.ts @@ -21,8 +21,8 @@ import type { CSSResultGroup } from '@umbraco-cms/backoffice/external/lit'; import type { Extensions } from '@umbraco-cms/backoffice/external/tiptap'; import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; -import './tiptap-toolbar.element.js'; -import './tiptap-statusbar.element.js'; +import '../toolbar/tiptap-toolbar.element.js'; +import '../statusbar/tiptap-statusbar.element.js'; const TIPTAP_CORE_EXTENSION_ALIAS = 'Umb.Tiptap.RichTextEssentials'; @@ -56,6 +56,9 @@ export class UmbInputTiptapElement extends UmbFormControlMixin stylesheet, - (stylesheet) => html``, + (stylesheet) => html``, )}