From 734ba7bb7c5a2659a8428e639bf4c27cc943de76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 19 Nov 2025 17:08:21 +0100 Subject: [PATCH 1/8] initial name example --- .../workspace-context-initial-name/README.md | 3 ++ .../workspace-context-initial-name/index.ts | 16 ++++++++ .../workspace-context.ts | 41 +++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/README.md create mode 100644 src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/index.ts create mode 100644 src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts diff --git a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/README.md b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/README.md new file mode 100644 index 000000000000..3c679efbc9a0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/README.md @@ -0,0 +1,3 @@ +# Workspace Context for setting an Initial Name + +This example of a Workspace Context demonstrates how to manipulate the name of the workspaces entity. diff --git a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/index.ts b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/index.ts new file mode 100644 index 000000000000..89d435a58829 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/index.ts @@ -0,0 +1,16 @@ +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; + +export const manifests: Array = [ + { + type: 'workspaceContext', + name: 'Example Name Manipulation Workspace Context', + alias: 'example.workspaceContext.nameManipulation', + api: () => import('./workspace-context.js'), + conditions: [ + { + alias: UMB_WORKSPACE_CONDITION_ALIAS, + match: 'Umb.Workspace.Document', + }, + ], + }, +]; diff --git a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts new file mode 100644 index 000000000000..1d9b7c4cb51d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts @@ -0,0 +1,41 @@ +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 { UMB_DOCUMENT_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/document'; +import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; + +// The Example Workspace Context Controller: +export class WorkspaceContextNameManipulation extends UmbContextBase { + constructor(host: UmbControllerHost) { + super(host, MANIPULATE_NAME_WORKSPACE_CONTEXT); + + this.consumeContext(UMB_DOCUMENT_WORKSPACE_CONTEXT, (workspace) => { + this.observe(workspace?.loading.isOn, (isLoading) => { + // Only manipulate the name when we are not loading: + if (isLoading) return; + // Get if new: + const isNew = workspace?.getIsNew() ?? false; + if (isNew) { + // Set the name if its already empty( We do not want to overwrite if its a Blueprint) + // Notice we can but a ! on the workspace, if the Document is new, then we also know we have a workspace. + // Notice we need to provide a Variant-ID to getName, as Document names are variant specific. Here we get the Invariant name — this will need to be extended if you are looking to support multiple variants. + const variantId = UmbVariantId.CreateInvariant(); + const name = workspace!.getName(variantId); + if (name === undefined) { + const manipulatedName = `New Document - ${new Date().toLocaleDateString('en-Gb')}`; + workspace!.setName(manipulatedName, variantId); + } + } + }); + }); + } +} + +// Declare a api export, so Extension Registry can initialize this class: +export const api = WorkspaceContextNameManipulation; + +// Declare a Context Token that other elements can use to request the WorkspaceContextCounter: +export const MANIPULATE_NAME_WORKSPACE_CONTEXT = new UmbContextToken( + 'UmbWorkspaceContext', + 'example.workspaceContext.initialName', +); From 3545397afe8058f5dabec8d940e2683e7922a113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 19 Nov 2025 17:25:16 +0100 Subject: [PATCH 2/8] Update src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../workspace-context-initial-name/workspace-context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts index 1d9b7c4cb51d..6627232acc55 100644 --- a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts +++ b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts @@ -34,7 +34,7 @@ export class WorkspaceContextNameManipulation extends UmbContextBase { // Declare a api export, so Extension Registry can initialize this class: export const api = WorkspaceContextNameManipulation; -// Declare a Context Token that other elements can use to request the WorkspaceContextCounter: +// Declare a Context Token that other elements can use to request the WorkspaceContextNameManipulation: export const MANIPULATE_NAME_WORKSPACE_CONTEXT = new UmbContextToken( 'UmbWorkspaceContext', 'example.workspaceContext.initialName', From b6f5cac1d2f17387b35744d3cbe0f34e19f4924c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 19 Nov 2025 17:25:25 +0100 Subject: [PATCH 3/8] Update src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../workspace-context-initial-name/workspace-context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts index 6627232acc55..612ca461c5b4 100644 --- a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts +++ b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts @@ -22,7 +22,7 @@ export class WorkspaceContextNameManipulation extends UmbContextBase { const variantId = UmbVariantId.CreateInvariant(); const name = workspace!.getName(variantId); if (name === undefined) { - const manipulatedName = `New Document - ${new Date().toLocaleDateString('en-Gb')}`; + const manipulatedName = `New Document - ${new Date().toLocaleDateString('en-GB')}`; workspace!.setName(manipulatedName, variantId); } } From 06496d76db7a83399638ecf4889fb3421d167c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 19 Nov 2025 17:25:30 +0100 Subject: [PATCH 4/8] Update src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../workspace-context-initial-name/workspace-context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts index 612ca461c5b4..a9e00f50c96f 100644 --- a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts +++ b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts @@ -16,7 +16,7 @@ export class WorkspaceContextNameManipulation extends UmbContextBase { // Get if new: const isNew = workspace?.getIsNew() ?? false; if (isNew) { - // Set the name if its already empty( We do not want to overwrite if its a Blueprint) + // Set the name if it's already empty (We do not want to overwrite if it's a Blueprint) // Notice we can but a ! on the workspace, if the Document is new, then we also know we have a workspace. // Notice we need to provide a Variant-ID to getName, as Document names are variant specific. Here we get the Invariant name — this will need to be extended if you are looking to support multiple variants. const variantId = UmbVariantId.CreateInvariant(); From 7d38665dd2e6d47fe6def47e04ec7d38bf9ef247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 19 Nov 2025 17:25:37 +0100 Subject: [PATCH 5/8] Update src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../workspace-context-initial-name/workspace-context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts index a9e00f50c96f..4e32ed7156ba 100644 --- a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts +++ b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts @@ -17,7 +17,7 @@ export class WorkspaceContextNameManipulation extends UmbContextBase { const isNew = workspace?.getIsNew() ?? false; if (isNew) { // Set the name if it's already empty (We do not want to overwrite if it's a Blueprint) - // Notice we can but a ! on the workspace, if the Document is new, then we also know we have a workspace. + // Notice we can put a ! on the workspace, if the Document is new, then we also know we have a workspace. // Notice we need to provide a Variant-ID to getName, as Document names are variant specific. Here we get the Invariant name — this will need to be extended if you are looking to support multiple variants. const variantId = UmbVariantId.CreateInvariant(); const name = workspace!.getName(variantId); From 7752d85f3ef2847052e99c518f6237be8baf69ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 21 Nov 2025 16:23:04 +0100 Subject: [PATCH 6/8] update example --- .../workspace-context-initial-name/index.ts | 8 +++- .../workspace-context.ts | 37 +++++++------------ 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/index.ts b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/index.ts index 89d435a58829..bd81e0ae4ee2 100644 --- a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/index.ts +++ b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/index.ts @@ -1,4 +1,7 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; +import { + UMB_WORKSPACE_CONDITION_ALIAS, + UMB_WORKSPACE_ENTITY_IS_NEW_CONDITION_ALIAS, +} from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { @@ -11,6 +14,9 @@ export const manifests: Array = [ alias: UMB_WORKSPACE_CONDITION_ALIAS, match: 'Umb.Workspace.Document', }, + { + alias: UMB_WORKSPACE_ENTITY_IS_NEW_CONDITION_ALIAS, + }, ], }, ]; diff --git a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts index 4e32ed7156ba..251e8387a683 100644 --- a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts +++ b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts @@ -1,30 +1,27 @@ -import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; -import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/document'; import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; // The Example Workspace Context Controller: -export class WorkspaceContextNameManipulation extends UmbContextBase { +export class ExampleWorkspaceContextNameManipulation extends UmbControllerBase { constructor(host: UmbControllerHost) { - super(host, MANIPULATE_NAME_WORKSPACE_CONTEXT); + super(host); + + console.log('Hello'); this.consumeContext(UMB_DOCUMENT_WORKSPACE_CONTEXT, (workspace) => { this.observe(workspace?.loading.isOn, (isLoading) => { // Only manipulate the name when we are not loading: if (isLoading) return; - // Get if new: - const isNew = workspace?.getIsNew() ?? false; - if (isNew) { - // Set the name if it's already empty (We do not want to overwrite if it's a Blueprint) - // Notice we can put a ! on the workspace, if the Document is new, then we also know we have a workspace. - // Notice we need to provide a Variant-ID to getName, as Document names are variant specific. Here we get the Invariant name — this will need to be extended if you are looking to support multiple variants. - const variantId = UmbVariantId.CreateInvariant(); - const name = workspace!.getName(variantId); - if (name === undefined) { - const manipulatedName = `New Document - ${new Date().toLocaleDateString('en-GB')}`; - workspace!.setName(manipulatedName, variantId); - } + // Set the name if it's already empty (We do not want to overwrite if it's a Blueprint) + // Notice we can put a ! on the workspace, if the Document is new, then we also know we have a workspace. + // Notice we need to provide a Variant-ID to getName, as Document names are variant specific. Here we get the Invariant name — this will need to be extended if you are looking to support multiple variants. + const variantId = UmbVariantId.CreateInvariant(); + const name = workspace!.getName(variantId); + if (name === undefined) { + const manipulatedName = `New Document - ${new Date().toLocaleDateString('en-GB')}`; + workspace!.setName(manipulatedName, variantId); } }); }); @@ -32,10 +29,4 @@ export class WorkspaceContextNameManipulation extends UmbContextBase { } // Declare a api export, so Extension Registry can initialize this class: -export const api = WorkspaceContextNameManipulation; - -// Declare a Context Token that other elements can use to request the WorkspaceContextNameManipulation: -export const MANIPULATE_NAME_WORKSPACE_CONTEXT = new UmbContextToken( - 'UmbWorkspaceContext', - 'example.workspaceContext.initialName', -); +export { ExampleWorkspaceContextNameManipulation as api }; From daa95311d2c89eb13b713e1295a0c374585408e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 21 Nov 2025 16:23:25 +0100 Subject: [PATCH 7/8] remove log --- .../workspace-context-initial-name/workspace-context.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts index 251e8387a683..e69e97e268d1 100644 --- a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts +++ b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts @@ -8,8 +8,6 @@ export class ExampleWorkspaceContextNameManipulation extends UmbControllerBase { constructor(host: UmbControllerHost) { super(host); - console.log('Hello'); - this.consumeContext(UMB_DOCUMENT_WORKSPACE_CONTEXT, (workspace) => { this.observe(workspace?.loading.isOn, (isLoading) => { // Only manipulate the name when we are not loading: From 7cf85859a81c21aa911e69c5d45c0ae5684bc1ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 24 Nov 2025 12:55:11 +0100 Subject: [PATCH 8/8] switch to use promise for awaiting load --- .../workspace-context.ts | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts index e69e97e268d1..91e30d19871a 100644 --- a/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts +++ b/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/workspace-context.ts @@ -1,6 +1,6 @@ import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/document'; +import { UMB_CONTENT_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/content'; import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; // The Example Workspace Context Controller: @@ -8,20 +8,17 @@ export class ExampleWorkspaceContextNameManipulation extends UmbControllerBase { constructor(host: UmbControllerHost) { super(host); - this.consumeContext(UMB_DOCUMENT_WORKSPACE_CONTEXT, (workspace) => { - this.observe(workspace?.loading.isOn, (isLoading) => { - // Only manipulate the name when we are not loading: - if (isLoading) return; - // Set the name if it's already empty (We do not want to overwrite if it's a Blueprint) - // Notice we can put a ! on the workspace, if the Document is new, then we also know we have a workspace. - // Notice we need to provide a Variant-ID to getName, as Document names are variant specific. Here we get the Invariant name — this will need to be extended if you are looking to support multiple variants. - const variantId = UmbVariantId.CreateInvariant(); - const name = workspace!.getName(variantId); - if (name === undefined) { - const manipulatedName = `New Document - ${new Date().toLocaleDateString('en-GB')}`; - workspace!.setName(manipulatedName, variantId); - } - }); + this.consumeContext(UMB_CONTENT_WORKSPACE_CONTEXT, async (workspace) => { + if (!workspace) return; + await workspace.isLoaded(); + // Set the name if it's already empty (We do not want to overwrite if it's a Blueprint) + // Notice we need to provide a Variant-ID to getName, as Document names are variant specific. Here we get the Invariant name — this will need to be extended if you are looking to support multiple variants. + const variantId = UmbVariantId.CreateInvariant(); + const name = workspace.getName(variantId); + if (name === undefined) { + const manipulatedName = `New Document - ${new Date().toLocaleDateString('en-GB')}`; + workspace.setName(manipulatedName, variantId); + } }); } }