Is there a way to add a message before the properties on a content node?

I am wanting to see if there is a nice way or a built in way to extend V15 Content/Document Workspace view before the list of properties in each tab, by displaying some kind of alert/message/warning to the user.

I would love to know if its possible to achieve this with the current extensions or WebComponent slots that may be available for me to insert this message?

If not my current hack and thought is for my Workspace Context that is loaded in alongside the document/content workspace context, is to try and find the element <umb-content-workspace-view-edit-tab> in the DOM of the page and then insert my element before it.

Not ideal as obviously fragile and prone to breaking if the DOM was to change in Umbraco.

Open to any thoughts or ideas on how to solve this problem?

You are probably further along than me when it comes to understanding the new Umbraco backoffice. But isn’t it possible to take an existing workspace and extend in it? Something like export default class MyWorkspace extends UmbDocumentWorkspace? And then make your workspace the active workspace for documents?

I did not think of that, but I think my concern is if I do I would need to reimplement a lot of things out of the box.

Will try it at lunch time to see what I can do/hack, unless anyone else any alternative suggestions ?

OK I have hacked something by using some DOM traversal and it works, but I am not sure if I like it.

Hoping someone from the core swings by and might be able to chip in with some thoughts.

:warning: Warning: There be dragons ahead

Many people hacking

dom.nodes.ts

export class DomNodeUtils {
    static findInShadowRoot(node: ShadowRoot | Document | null, selector: string): HTMLElement | null {
        if(!node)
        {
            return null;
        }

        // Check if the current node contains the element we are looking for
        const targetElement = node.querySelector(selector) as HTMLElement;
        if(targetElement){
            console.log('found targetElement', targetElement);
            return targetElement;
        }

        // Recursively search through all the shadow roots of the children
        const elements = node.querySelectorAll('*');
        for(const element of elements){
            if(element.shadowRoot){
                const tryFindElement = this.findInShadowRoot(element.shadowRoot, selector);
                if(tryFindElement){
                    console.log('found tryFindElement', tryFindElement);
                    return tryFindElement;
                }
            }
        }

        return null;
    }
}

contentlock.workspace.context.ts


	constructor(host: UmbControllerHost) {
		super(host, CONTENTLOCK_WORKSPACE_CONTEXT.toString());
		this.provideContext(CONTENTLOCK_WORKSPACE_CONTEXT, this);

		// truncated...

        // Add an event listener into the window for the navigation success router event
        // Why? - well the findInShadowRoot() util method won't find the DOM elements until all the items been loaded in from router slots
        window.addEventListener('navigationsuccess', this._navigationSuccessHandler);
	}


    private _navigationSuccessHandler() {
        // Check to see if we have our NODE in the DOM
        // As it fires as we change from tab to tab in the document workspace
        // And dont want to duplicate the notice over and over
        const tryFindNotice = DomNodeUtils.findInShadowRoot(document, '#locked-by-notice');
        if(!tryFindNotice){
            const tryFindInsertBefore = DomNodeUtils.findInShadowRoot(document, 'umb-content-workspace-view-edit-tab');
            if(tryFindInsertBefore){
                tryFindInsertBefore.insertAdjacentHTML('beforebegin', `<div id="locked-by-notice" style="margin-bottom: var(--uui-size-4); padding: var(--uui-size-5); background: var(--uui-color-current);">This node is locked by Emma</div>`)
            }
        }
    }

    ...

Result

It works, but I kinda feel dirty that I needed to do this. Is there a better/nicer way to achieve what I am trying to do?

OK well that logic is flawed when using the navigationsuccess event, as there is no way for me to know the difference between navigating to a brand new content node vs the tabs on the content node changing and the URL/route changing.

Back to the drawing board

Just because we have the Shadow-DOM to encapsulate Components, it does not mean that the DOM cant be manipulated. Its a little harder, but it is possible.

Surely not something I would recommend, as it could break, also in minors. Cause going this way you are going off road and unless we freeze the code base we cannot be sure not to break it.

So doing so then just please be aware, and if I see any topic regarding this on the tracker then you owe me a cup of coffee.

To do this the proper way my suggestion would be to reconsider how you show this information. Could you inject this on the Workspace level, something Static/floating on top? Add a thin yellow colored border on the whole workspace and then a tiny message in the bottom left corner?

1 Like

Yep totally agree its too fragile and could break if you rename or move DOM elements about. Hence my big warning with it.

That’s an interesting idea to perhaps override your Workspace view with my own, which in turn calls the workspace view from core.

I will try that approach out later on and see how it goes & update this thread…

Also I probably owe you many cups of coffee or beer mate for my crimes to code & hacks & workarounds :see_no_evil_monkey:

Snow White drinking endless Coffee

2 Likes