Admin option: ComfyUI Manager in its own sidebar tab

A Manager tab in the left bar opens the Manager menu or the Custom Nodes
Manager, for accounts with the manager permission, and the top-bar button
is hidden. Off by default (manager_tab).
This commit is contained in:
Edouard Durand
2026-09-27 01:16:47 +00:00
parent 27e4fd37f1
commit 02dfd79523
8 changed files with 71 additions and 0 deletions
+4
View File
@@ -2,6 +2,10 @@
## Unreleased
### Added
- Admin option *ComfyUI Manager in its own sidebar tab*: a **Manager** tab in the left bar (Open Manager, Custom Nodes Manager) replaces the top-bar button, for accounts with the *Manager* permission
### Changed
- Other plugins' top-bar buttons (rgthree-comfy, Crystools...) are hidden without the *Manager* permission, like ComfyUI Manager's. Their settings kept on the server, which apply to everyone, need *Manager* too
+1
View File
@@ -28,6 +28,7 @@ Admins change these under **Admin → Server settings**. They are stored in `rig
| `broadcast_execution` | `true` | Send progress and previews to everyone, not only whoever queued |
| `hide_comfy_account` | `false` | Hide ComfyUI's Comfy.org sign-in button and dialog |
| `hide_comfy_file_tabs` | `true` | Hide other workflow browsers: ComfyUI's Workflows and Apps sidebar tabs and Pixaroma's Workflows panel. RigShare's Files tab replaces them and their shortcuts open it |
| `manager_tab` | `false` | Show ComfyUI Manager as a Manager tab in the left sidebar instead of a top-bar button (only for accounts with *Manager*) |
| `hide_api_templates` | `false` | Remove templates that need paid API nodes from the template browser |
| `api_protection.enabled` | `true` | Server-side checks on queue, interrupt, free and upload calls |
| `api_protection.trusted_ips` | `["127.0.0.1", "::1"]` | Addresses or networks that skip login and checks |
+1
View File
@@ -417,6 +417,7 @@ class Hub:
return {"name": cfg.get("server_name"), "allow_guests": cfg.get("allow_guests"),
"hide_comfy_account": bool(cfg.get("hide_comfy_account")),
"hide_comfy_file_tabs": bool(cfg.get("hide_comfy_file_tabs", True)),
"manager_tab": bool(cfg.get("manager_tab")),
"hide_api_templates": bool(cfg.get("hide_api_templates"))}
async def broadcast_server(self):
+2
View File
@@ -49,6 +49,8 @@ DEFAULT_CONFIG = {
"hide_comfy_account": False,
# ComfyUI's own Workflows and Apps sidebar tabs duplicate RigShare's Files tab.
"hide_comfy_file_tabs": True,
# ComfyUI Manager in its own sidebar tab instead of the top-bar button.
"manager_tab": False,
# Remove templates that need paid API nodes from the template browser.
"hide_api_templates": False,
# Rooms nobody opened for this many days are forgotten.
+13
View File
@@ -579,3 +579,16 @@ def test_other_plugins_server_routes(run):
assert await status("GET", "/pixaroma/api/workflows/index", admin) == 200
assert await status("GET", "/pixaroma/api/fonts/list", alice) == 200, "the rest of Pixaroma works"
run(scenario())
def test_manager_tab_option(run):
async def scenario():
async with rig_server() as rig:
admin = await rig.setup_admin()
sock = await rig.ws("boss")
assert rig.hub.server_info()["manager_tab"] is False, "off by default"
r = await rig.http.patch(rig.url("/rigshare/api/config"), json={"manager_tab": True}, headers=admin)
assert r.status == 200
assert (await sock.until("server"))["server"]["manager_tab"] is True
await sock.close()
run(scenario())
+43
View File
@@ -104,6 +104,48 @@ function installManagerGuard(client) {
setInterval(tagPluginButtons, 1000);
}
// ComfyUI Manager in its own sidebar tab (admin option): its menu and the custom
// nodes manager open from there, and the top-bar button goes away.
const MANAGER_TAB_ID = "rigshare-manager";
function installManagerTab(client) {
let registered = false;
const run = (id) => app.extensionManager?.command?.execute(id);
const panel = h("div", { class: "rs-panel rs-manager-panel" },
h("div", { class: "rs-header" },
h("div", { class: "rs-title" }, h("i", { class: "pi pi-th-large rs-files-logo" }),
h("div", { class: "rs-title-text" }, h("div", { class: "rs-title-name" }, "ComfyUI Manager"),
h("div", { class: "rs-status" }, "Custom nodes, models, updates")))),
h("div", { class: "rs-body" },
h("section", { class: "rs-section" },
h("button", { class: "rs-btn rs-btn-primary rs-block-btn", onclick: () => run("Comfy.Manager.Menu.ToggleVisibility") },
h("i", { class: "pi pi-th-large" }), "Open Manager"),
h("p", { class: "rs-muted rs-small" }, "Install missing nodes, update everything, the model manager, snapshots and restart."),
h("button", { class: "rs-btn rs-block-btn", onclick: () => run("Comfy.Manager.CustomNodesManager.ToggleVisibility") },
h("i", { class: "pi pi-server" }), "Custom Nodes Manager"),
h("p", { class: "rs-muted rs-small" }, "Browse, install, update, disable or remove custom nodes."))));
const apply = () => {
const manager = app.extensionManager;
const hasManager = (manager?.command?.commands ?? []).some((c) => c.id === "Comfy.Manager.Menu.ToggleVisibility");
const want = !!client.server?.manager_tab && client.online && !!client.perms.manager && hasManager;
document.body.classList.toggle("rs-manager-tab", !!client.server?.manager_tab);
if (want && !registered) {
manager.registerSidebarTab({
id: MANAGER_TAB_ID, icon: "pi pi-th-large", title: "Manager", tooltip: "ComfyUI Manager",
label: "Manager", type: "custom",
render: (el) => { el.classList.add("rs-host"); el.replaceChildren(panel); },
});
registered = true;
} else if (!want && registered) {
(manager.unregisterSidebarTab ?? manager.sidebarTab?.unregisterSidebarTab)?.(MANAGER_TAB_ID);
registered = false;
}
};
client.on("server", apply);
client.on("self", apply);
client.on("status", apply);
setTimeout(apply, 2500); // Manager registers its commands during setup
}
// Comfy.org account: hide the top-bar sign-in button and refuse the sign-in
// dialogs when the admin turned it off.
const SIGNIN_DIALOGS = ["global-signin", "api-nodes-signin"];
@@ -330,6 +372,7 @@ app.registerExtension({
installManagerGuard(client);
installComfyAccountGuard(client);
installFileTabsGuard(client);
installManagerTab(client);
installSaveDialog(app, api, client, sync);
presence.install();
+3
View File
@@ -834,6 +834,7 @@ export class RigSharePanel {
protect: box(cfg.api_protection?.enabled),
hideAccount: box(cfg.hide_comfy_account),
hideFileTabs: box(cfg.hide_comfy_file_tabs ?? true),
managerTab: box(cfg.manager_tab),
hideApiTemplates: box(cfg.hide_api_templates),
trusted: text((cfg.api_protection?.trusted_ips || []).join(", "), "127.0.0.1, 172.17.0.0/16"),
interval: h("input", { class: "rs-input rs-num", type: "number", min: 0, value: Math.round((cfg.snapshot_interval_sec ?? 300) / 60) }),
@@ -852,6 +853,7 @@ export class RigSharePanel {
broadcast_execution: f.broadcast.checked,
hide_comfy_account: f.hideAccount.checked,
hide_comfy_file_tabs: f.hideFileTabs.checked,
manager_tab: f.managerTab.checked,
hide_api_templates: f.hideApiTemplates.checked,
api_protection: { enabled: f.protect.checked, trusted_ips: f.trusted.value.split(/[\s,]+/).filter(Boolean) },
snapshot_interval_sec: Math.max(0, +f.interval.value || 0) * 60,
@@ -866,6 +868,7 @@ export class RigSharePanel {
line(f.broadcast, "Share execution progress", "Everyone sees progress and previews, not only whoever queued"),
line(f.protect, "Enforce permissions on the ComfyUI API", "Blocks queueing, interrupting and uploads for users without permission"),
line(f.hideAccount, "Hide the Comfy.org account login", "Removes ComfyUI's own sign-in button and dialog (used for paid API nodes)"),
line(f.managerTab, "ComfyUI Manager in its own sidebar tab", "A Manager tab in the left bar replaces the top-bar button, for accounts with the Manager permission"),
line(f.hideFileTabs, "Hide other workflow browsers", "ComfyUI's Workflows and Apps tabs, and Pixaroma's Workflows panel: RigShare's Files tab replaces them and their shortcuts open Files"),
line(f.hideApiTemplates, "Hide API templates", "Removes templates that need paid API nodes from the template browser"),
h("label", { class: "rs-label" }, "Trusted IPs / networks (skip login and checks)"), f.trusted,
+4
View File
@@ -111,6 +111,10 @@ body.rs-hide-comfy-account [data-testid="login-button-popover"] { display: none
body.rs-no-manager .rs-plugin-bar { display: none !important; }
/* Pixaroma's workflow browser button: RigShare's Files tab replaces it */
body.rs-hide-file-browsers .pixwb-group-btn { display: none !important; }
/* ComfyUI Manager moved to its own sidebar tab (admin option): no top-bar button */
body.rs-manager-tab .comfyui-button-group:has(> [title="ComfyUI Manager"]),
body.rs-manager-tab [title="ComfyUI Manager"] { display: none !important; }
.rs-block-btn { width: 100%; justify-content: center; padding: 9px 12px; margin-top: 4px; }
/* ComfyUI Manager hidden for accounts without the "manager" permission */
body.rs-no-manager .comfyui-button-group:has(> [title="ComfyUI Manager"]),
body.rs-no-manager [title="ComfyUI Manager"],