How to hide Create Workspace from certain user roles?

Hi @avc

when i login as normal user, i dont see the buttons but if i click on a button like sales invoice and on the browser click on return then the Create Workspace button becomes visible

This is one headache i have experienced with most custom js functions lately. i find that some functions perform inconsistently due to caching, this forces me to implement location.reload in most cases (which is terrible UX i know) to ensure that the js functions always refresh and reapply their conditional states. I am yet to find a way to prevent caching of states and would love to hear any suggestions on how to handle this.

As far as the actual thread topic goes - @avc is right. If you have the latest version leaving Workspace Manager un-checked will mean that create workspace is not visible for that user. This means no custom code is required

image

off topic (1) - How can I actually tell which version of erpnext I am using? If I do bench version I just get erpnext 14.x.x-develop which I actually don’t think is correct?

ERPNext: v15.30.0 (version-15)
Frappe Framework: v15.35.0 (version-15)

Yes, working fine.

Thanks

offtopic (2)

@flexy2ky From my somewhat limited experience I don’t believe there is an out of the box way to reliably execute javascript code when the user views a page in frappe framework. Once the onload event fires once then caching kicks in and the event won’t fire again, unless the user specifically refreshes the browser (or you do it for them using location.reload or whatever).

I would love to be proved wrong but I haven’t found a way

If you are say adding buttons its not a problem as the buttons just stay on the page (no idea why). But if you are hiding elements then it is a problem as they will simply re-appear with the next page draw

I am currently using a hack which detects if the url changes. I have found this to be reliable, with the caveats that

  1. It is not ‘exactly once’ execution, i.e. it may execute twice for a single page (it does seem to always execute though)
  2. You don’t have access to the frappe page model, so you have to do everything in the DOM directly using jquery or vanilla javascript :hammer: :pick: :carpentry_saw:

Anyway here is the code, I’d be interested to know if it works for you :slight_smile:

async function observeUrlChange() {

    let oldHref = document.location.href;
    const body = document.querySelector("body");
    const observer = new MutationObserver(async mutations => {

        for (const mutation of mutations) {

            if (oldHref !== document.location.href) {
                // user has navigated to a new page
                setupPage()
                oldHref = document.location.href
            }
        } // next mutation
    });

    observer.observe(body, { childList: true, subtree: true });
};

window.addEventListener("load", observeUrlChange)

window.addEventListener("load", setupPage)

async function setupPage() {

        // get and parse current URL
        let url = new URL(document.location.href);
        let lastPart = url.pathname.split('/').filter(segment => segment !== "").pop();
    
        console.log(`setting up page for ${url.pathname} page ${lastPart}`)

        // do various things to the DOM based on the page (lastPart)
}

Create Workspace button will reappear if you visit any document and back,

add custom CSS will work,

for this JS script, it can work by:

document.addEventListener('DOMContentLoaded', function () {
    if (!frappe.user.has_role("Workspace Manager")) {
        console.log("Hide actions");
        var intervalId = setInterval(function () {
            $("#page-Workspaces  .page-head-content > .page-actions > .custom-actions").css('display', 'none');
            $("#page-Workspaces  .page-head-content > .page-actions > .standard-actions").css('display', 'none');
            clearInterval(intervalId);
        }, 5);
    }
});