-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Open
Description
Which Umbraco version are you using?
16.3.0
Bug summary
I have a custom workspace context trying to set a node name for certain new nodes created.
I am having to use a hacky approach of wrapping a method call in a timeout set to 0ms in order for the code to work and set the node name.
My assumption would be if that I have awaited the isLoaded() method/promise on the Content Workspace that everything has been initialized that it needs and I could use and set what I need to do.
Specifics
No response
Steps to reproduce
Workspace context
import { UmbControllerBase } from "@umbraco-cms/backoffice/class-api";
import { UmbContentWorkspaceContext } from "@umbraco-cms/backoffice/content";
import { UmbControllerHost } from "@umbraco-cms/backoffice/controller-api";
import { UMB_CONTENT_WORKSPACE_CONTEXT } from "@umbraco-cms/backoffice/content";
import { UmbVariantId } from "@umbraco-cms/backoffice/variant";
import { UMB_APP_LANGUAGE_CONTEXT } from "@umbraco-cms/backoffice/language";
import type { UmbLanguageDetailModel } from '@umbraco-cms/backoffice/language';
export class SetDashForNodeName extends UmbControllerBase {
#workspaceContext?: UmbContentWorkspaceContext;
#languages?: Array<UmbLanguageDetailModel>;
#isNew: boolean = false;
/**
* We use this to set the node name to a dash for all languages when creating a new content item
* The conditions for this workspace context is set in the manifest to only apply to specific content types
* Such as Tweet etc...
*
* WHY: We use a dash as a node name placeholder and when the node is saved a C# Saving event/notification
* Then runs logic to determine the default node name based on properties and other values from the node
*/
constructor(host: UmbControllerHost) {
super(host);
this.consumeContext(UMB_APP_LANGUAGE_CONTEXT, (appLanguageContext) => {
this.observe(appLanguageContext?.languages, (languages) => {
this.#languages = languages;
});
});
this.consumeContext(UMB_CONTENT_WORKSPACE_CONTEXT, async (contentWorkspaceCtx) => {
this.#workspaceContext = contentWorkspaceCtx;
if(!this.#workspaceContext){
return;
}
// Wait for the workspace to be fully loaded before observing
await this.#workspaceContext.isLoaded();
this.observe(this.#workspaceContext.isNew, (isNew) => {
this.#isNew = isNew ?? false;
// Throws an error if we try this without a timeout wrapped around it
//this.#updateNodeName();
// YUK - why we do need a timeout to wrap the updateNodeName method ?
// Without it the setName on the workspace complains with this error
// I would have thought that by awaiting the isLoaded above
// That everything would have been initialized and ready to use
/*
reportUnhandledError.js:10
Uncaught Error: Data is missing
at #e (content-data-manager.ts:90:27)
at Mt.updateVariantData (content-data-manager.ts:65:9)
at Ut.setName (content-detail-workspace-base.ts:502:14)
at #o (set-dash-for-node-name.ts:77:31)
at Object.next (set-dash-for-node-name.ts:46:14)
*/
setTimeout(() => {
this.#updateNodeName();
}, 0); // 0ms delay
});
});
}
#updateNodeName(){
// Check we have workspace context & all languages from observable set
if (!this.#workspaceContext || !this.#languages){
return;
}
if(!this.#isNew){
console.log('[Set Dash For Node Name] - Node is NOT a new node, skipping setting node name to dash');
return;
}
const defaultLang = this.#languages.find(lang => lang.isDefault);
if(!defaultLang){
console.warn('[Set Dash For Node Name] - No default language found, cannot set node name to dash');
return;
}
// We only need to set the dash for the default language
this.#workspaceContext?.setName('-', new UmbVariantId(defaultLang.unique));
}
}
export default SetDashForNodeName;Manifest
import { UMB_WORKSPACE_CONTENT_TYPE_ALIAS_CONDITION_ALIAS } from "@umbraco-cms/backoffice/content-type";
export const manifests: Array<UmbExtensionManifest> = [
{
type: "workspaceContext",
name: "[Consilium] - Set dash for node name",
alias: "Consilium.WorkspaceContext.SetDashForNodeName",
api: () => import('./set-dash-for-node-name'),
conditions: [
{
alias: UMB_WORKSPACE_CONTENT_TYPE_ALIAS_CONDITION_ALIAS,
oneOf: [
"pressMaterialPage",
"meetingPage",
"informalMeetingPage",
"tweet",
"presidentNewsPage"
]
}
]
}
];Expected result / actual result
That I am able to set the nodeName for new content nodes without having to do a hacky workaround of using a timeout.