diff --git a/Directory.Build.props b/Directory.Build.props
index 1cc761932c17..03d2eae22708 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -33,8 +33,8 @@
false
- false
- 14.0.0
+ true
+ 15.0.0
true
true
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/ClientCredentials/ClientCredentialsUserControllerBase.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/ClientCredentials/ClientCredentialsUserControllerBase.cs
index 1751564b3745..deeb8d8f0d36 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/User/ClientCredentials/ClientCredentialsUserControllerBase.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/User/ClientCredentials/ClientCredentialsUserControllerBase.cs
@@ -20,7 +20,7 @@ protected IActionResult BackOfficeUserClientCredentialsOperationStatusResult(Bac
.Build()),
BackOfficeUserClientCredentialsOperationStatus.InvalidClientId => BadRequest(problemDetailsBuilder
.WithTitle("Invalid client ID")
- .WithDetail("The specified client ID is invalid. A valid client ID can only contain [a-z], [A-Z], [0-9], and [-._~].")
+ .WithDetail("The specified client ID is invalid. A valid client ID can only contain [a-z], [A-Z], [0-9], and [-._~]. Furthermore, including the prefix it cannot be longer than 255 characters.")
.Build()),
_ => StatusCode(StatusCodes.Status500InternalServerError, problemDetailsBuilder
.WithTitle("Unknown client credentials operation status.")
diff --git a/src/Umbraco.Core/Services/UserService.cs b/src/Umbraco.Core/Services/UserService.cs
index 2ed91f31cf34..657507f17b3d 100644
--- a/src/Umbraco.Core/Services/UserService.cs
+++ b/src/Umbraco.Core/Services/UserService.cs
@@ -2675,7 +2675,7 @@ private static void AddAdditionalPermissions(ISet assignedPermissions, I
}
}
- [GeneratedRegex(@"^[\w\d\-\._~]*$")]
+ [GeneratedRegex(@"^[\w\d\-\._~]{1,255}$")]
private static partial Regex ValidClientId();
#endregion
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts
index f9f15b699a81..f381f7d00b76 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts
@@ -8,7 +8,6 @@ import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router';
import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property';
-import type { UmbVariantId } from '@umbraco-cms/backoffice/variant';
export class UmbBlockListEntriesContext extends UmbBlockEntriesContext<
typeof UMB_BLOCK_LIST_MANAGER_CONTEXT,
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 19a097678460..dc7f737b0e76 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
@@ -25,6 +25,7 @@ import {
UMB_BLOCK_ENTRY_CONTEXT,
} from '@umbraco-cms/backoffice/block';
import { UmbVariantId } from '@umbraco-cms/backoffice/variant';
+import type { UUIModalSidebarSize } from '@umbraco-cms/backoffice/external/uui';
export type UmbBlockWorkspaceElementManagerNames = 'content' | 'settings';
export class UmbBlockWorkspaceContext
@@ -44,6 +45,7 @@ export class UmbBlockWorkspaceContext {
+ this.#modalContext = context;
this.#originData = context?.data.originData;
context.onSubmit().catch(this.#modalRejected);
}).asPromise();
@@ -116,7 +119,7 @@ export class UmbBlockWorkspaceContext {
+ this.observe(
+ contentTypeId ? manager.blockTypeOf(contentTypeId) : undefined,
+ (blockType) => {
+ if (blockType?.editorSize) {
+ this.setEditorSize(blockType.editorSize);
+ }
+ },
+ 'observeBlockType',
+ );
+ },
+ 'observeContentTypeId',
+ );
});
this.#retrieveBlockEntries = this.consumeContext(UMB_BLOCK_ENTRIES_CONTEXT, (context) => {
@@ -197,6 +216,10 @@ export class UmbBlockWorkspaceContext {
+ sidebarElement.size = size as UUIModalSidebarSize;
+ },
+ 'observeSize',
+ );
return sidebarElement;
}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal-manager.context.ts
index 41c35e2f3fb2..2cd0dcbc21e8 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal-manager.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal-manager.context.ts
@@ -1,29 +1,9 @@
import type { UmbModalToken } from '../token/modal-token.js';
import { UmbModalContext, type UmbModalContextClassArgs } from './modal.context.js';
-import type { UUIModalElement, UUIModalSidebarSize } from '@umbraco-cms/backoffice/external/uui';
import { UmbBasicState, appendToFrozenArray } from '@umbraco-cms/backoffice/observable-api';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
-import type { ElementLoaderProperty } from '@umbraco-cms/backoffice/extension-api';
-
-export type UmbModalType = 'dialog' | 'sidebar' | 'custom';
-
-export interface UmbModalConfig {
- key?: string;
- type?: UmbModalType;
- size?: UUIModalSidebarSize;
-
- /**
- * Used to provide a custom modal element to replace the default uui-modal-dialog or uui-modal-sidebar
- */
- element?: ElementLoaderProperty;
-
- /**
- * Set the background property of the modal backdrop
- */
- backdropBackground?: string;
-}
export class UmbModalManagerContext extends UmbContextBase {
// TODO: Investigate if we can get rid of HTML elements in our store, so we can use one of our states.
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts
index 395dc1ad2210..67559025ed85 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts
@@ -1,10 +1,10 @@
import { UmbModalToken } from '../token/modal-token.js';
-import type { UmbModalConfig, UmbModalType } from './modal-manager.context.js';
+import type { UmbModalConfig, UmbModalType } from '../types.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import type { IRouterSlot } from '@umbraco-cms/backoffice/external/router-slot';
import type { UUIModalElement, UUIModalSidebarSize } from '@umbraco-cms/backoffice/external/uui';
import { UmbId } from '@umbraco-cms/backoffice/id';
-import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
+import { UmbObjectState, UmbStringState } from '@umbraco-cms/backoffice/observable-api';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import { type UmbDeepPartialObject, umbDeepMerge } from '@umbraco-cms/backoffice/utils';
import type { ElementLoaderProperty } from '@umbraco-cms/backoffice/extension-api';
@@ -38,8 +38,7 @@ export class UmbModalContext<
public readonly key: string;
public readonly data: ModalData;
public readonly type: UmbModalType = 'dialog';
- public readonly size: UUIModalSidebarSize = 'small';
- public element?: ElementLoaderProperty;
+ public readonly element?: ElementLoaderProperty;
public readonly backdropBackground?: string;
public readonly router: IRouterSlot | null = null;
public readonly alias: string | UmbModalToken;
@@ -47,6 +46,9 @@ export class UmbModalContext<
#value;
public readonly value;
+ #size = new UmbStringState('small');
+ public readonly size = this.#size.asObservable();
+
constructor(
host: UmbControllerHost,
modalAlias: string | UmbModalToken,
@@ -57,18 +59,24 @@ export class UmbModalContext<
this.router = args.router ?? null;
this.alias = modalAlias;
+ let size = 'small';
+
if (this.alias instanceof UmbModalToken) {
this.type = this.alias.getDefaultModal()?.type || this.type;
- this.size = this.alias.getDefaultModal()?.size || this.size;
+ size = this.alias.getDefaultModal()?.size ?? size;
this.element = this.alias.getDefaultModal()?.element || this.element;
this.backdropBackground = this.alias.getDefaultModal()?.backdropBackground || this.backdropBackground;
}
this.type = args.modal?.type || this.type;
- this.size = args.modal?.size || this.size;
+ size = args.modal?.size ?? size;
this.element = args.modal?.element || this.element;
this.backdropBackground = args.modal?.backdropBackground || this.backdropBackground;
+ console.log('size', size);
+
+ this.#size.setValue(size);
+
const defaultData = this.alias instanceof UmbModalToken ? this.alias.getDefaultData() : undefined;
this.data = Object.freeze(
// If we have both data and defaultData perform a deep merge
@@ -153,6 +161,16 @@ export class UmbModalContext<
this.#value.update(partialValue);
}
+ /**
+ * Updates the size this modal.
+ * @param size
+ * @public
+ * @memberof UmbModalContext
+ */
+ setModalSize(size: UUIModalSidebarSize) {
+ this.#size.setValue(size);
+ }
+
public override destroy(): void {
this.dispatchEvent(new CustomEvent('umb:destroy'));
this.#value.destroy();
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts
index 9087982eb7cf..c82741c4c1d3 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts
@@ -1,4 +1,4 @@
-import type { UmbModalConfig } from '../context/modal-manager.context.js';
+import type { UmbModalConfig } from '../types.js';
export interface UmbModalTokenDefaults<
ModalDataType extends { [key: string]: any } = { [key: string]: any },
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/types.ts
index a1c61b09c0c0..ce18bc606e50 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/types.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/types.ts
@@ -1,3 +1,6 @@
+import type { UUIModalElement, UUIModalSidebarSize } from '@umbraco-cms/backoffice/external/uui';
+import type { ElementLoaderProperty } from '@umbraco-cms/backoffice/extension-api';
+
export type * from './extensions/index.js';
export interface UmbPickerModalData {
@@ -15,3 +18,21 @@ export interface UmbPickerModalSearchConfig {
export interface UmbPickerModalValue {
selection: Array;
}
+
+export type UmbModalType = 'dialog' | 'sidebar' | 'custom';
+
+export interface UmbModalConfig {
+ key?: string;
+ type?: UmbModalType;
+ size?: UUIModalSidebarSize;
+
+ /**
+ * Used to provide a custom modal element to replace the default uui-modal-dialog or uui-modal-sidebar
+ */
+ element?: ElementLoaderProperty;
+
+ /**
+ * Set the background property of the modal backdrop
+ */
+ backdropBackground?: string;
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/overlay-size/property-editor-ui-overlay-size.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/overlay-size/property-editor-ui-overlay-size.element.ts
index 849edf5b93de..cce59c656358 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/overlay-size/property-editor-ui-overlay-size.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/overlay-size/property-editor-ui-overlay-size.element.ts
@@ -15,9 +15,11 @@ export class UmbPropertyEditorUIOverlaySizeElement extends UmbLitElement impleme
@property()
value: UUIModalSidebarSize | string = '';
+ // TODO: Stop having global type of the UUI-SELECT element. And make it possible to have undefined as an option.
@state()
private _list: Array