feat: adapt panel styling to Nodes 2.0 (Modern Node Design)

Detects the Comfy.VueNodes.Enabled setting via addEventListener and
toggles a `distributed-panel--nodes2` class on the panel root element.
CSS visual properties (backgrounds, borders, border-radius) are migrated
from inline JS styles to CSS classes, enabling clean theme overrides for
Nodes 2.0 using PrimeVue surface variables (--p-surface-*, --p-text-*).
This commit is contained in:
Robert Wojciechowski
2026-02-28 04:52:59 +00:00
parent d8095cddb6
commit 2565f5aece
4 changed files with 149 additions and 19 deletions
+9 -9
View File
@@ -134,17 +134,17 @@ export const UI_STYLES = {
controlsDiv: "padding: 0 12px 12px 12px; display: flex; gap: 6px;",
formGroup: "display: flex; flex-direction: column; gap: 5px;",
formLabel: "font-size: 12px; color: #ccc; font-weight: 500;",
formInput: "padding: 6px 10px; background: #2a2a2a; border: 1px solid #444; color: white; font-size: 12px; border-radius: 4px; transition: border-color 0.2s;",
formInput: "padding: 6px 10px; color: white; font-size: 12px; transition: border-color 0.2s;",
// Card styles
cardBase: "margin-bottom: 12px; border-radius: 6px; overflow: hidden; display: flex;",
workerCard: "margin-bottom: 12px; border-radius: 6px; overflow: hidden; display: flex; background: #2a2a2a;",
cardBlueprint: "border: 2px dashed #555; cursor: pointer; transition: all 0.2s ease; background: rgba(255, 255, 255, 0.02);",
cardAdd: "border: 1px dashed #444; cursor: pointer; transition: all 0.2s ease; background: transparent;",
cardBase: "margin-bottom: 12px; overflow: hidden; display: flex;",
workerCard: "margin-bottom: 12px; overflow: hidden; display: flex;",
cardBlueprint: "cursor: pointer; transition: all 0.2s ease;",
cardAdd: "cursor: pointer; transition: all 0.2s ease;",
// Column styles
columnBase: "display: flex; align-items: center; justify-content: center;",
checkboxColumn: "flex: 0 0 44px; display: flex; align-items: center; justify-content: center; border-right: 1px solid #3a3a3a; cursor: default; background: rgba(0,0,0,0.1);",
checkboxColumn: "flex: 0 0 44px; display: flex; align-items: center; justify-content: center; cursor: default;",
contentColumn: "flex: 1; display: flex; flex-direction: column; transition: background-color 0.2s ease;",
iconColumn: "width: 44px; flex-shrink: 0; font-size: 20px; color: #666;",
@@ -162,8 +162,8 @@ export const UI_STYLES = {
// Existing styles
settingsArrow: "font-size: 12px; color: #888; transition: all 0.2s ease; margin-left: auto; padding: 4px;",
infoBox: "background-color: #333; color: #999; padding: 5px 14px; border-radius: 4px; font-size: 11px; text-align: center; flex: 1; font-weight: 500;",
workerSettings: "margin: 0 12px; padding: 0 12px; background: #1e1e1e; border-radius: 4px; border: 1px solid #2a2a2a;"
infoBox: "color: #999; padding: 5px 14px; font-size: 11px; text-align: center; flex: 1; font-weight: 500;",
workerSettings: "margin: 0 12px; padding: 0 12px;"
};
export const TIMEOUTS = {
+106
View File
@@ -107,6 +107,112 @@
background-color: var(--tunnel-disable) !important;
}
/* ---- Themeable card/column/input defaults (Classic) ---- */
.dist-card {
background: #2a2a2a;
border-radius: 6px;
}
.dist-card--blueprint {
border: 2px dashed #555;
background: rgba(255, 255, 255, 0.02);
}
.dist-card--add {
border: 1px dashed #444;
background: transparent;
}
.dist-card__left-col {
border-right: 1px solid #3a3a3a;
background: rgba(0, 0, 0, 0.1);
}
.dist-info-box {
background-color: #333;
border-radius: 4px;
}
.dist-form-input {
background: #2a2a2a;
border: 1px solid #444;
border-radius: 4px;
}
.worker-settings {
background: #1e1e1e;
border: 1px solid #2a2a2a;
border-radius: 4px;
}
/* ---- Nodes 2.0 Theme ---- */
.distributed-panel--nodes2 .dist-card {
background: var(--p-surface-800, #1e1e1e);
border: 1px solid var(--p-surface-700, #2c2c2c);
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.distributed-panel--nodes2 .dist-card--blueprint {
border: 2px dashed var(--p-surface-600, #404040);
background: rgba(255, 255, 255, 0.015);
box-shadow: none;
}
.distributed-panel--nodes2 .dist-card--add {
border: 1px dashed var(--p-surface-600, #404040);
background: transparent;
box-shadow: none;
}
.distributed-panel--nodes2 .dist-card__left-col {
border-right-color: var(--p-surface-700, #2c2c2c);
background: var(--p-surface-900, #131313);
}
.distributed-panel--nodes2 .dist-info-box {
background-color: var(--p-surface-700, #2c2c2c);
color: var(--p-text-muted-color, #9e9e9e);
border-radius: 6px;
}
.distributed-panel--nodes2 .dist-form-input {
background: var(--p-surface-800, #1e1e1e);
border-color: var(--p-surface-600, #404040);
border-radius: 6px;
color: var(--p-text-color, #ffffff);
}
.distributed-panel--nodes2 .worker-settings {
background: var(--p-surface-900, #131313);
border-color: var(--p-surface-700, #2c2c2c);
border-radius: 6px;
}
.distributed-panel--nodes2 .entity-card-content--hovered {
background-color: var(--p-surface-700, #2c2c2c) !important;
}
.distributed-panel--nodes2 .placeholder-card--blueprint {
border-color: var(--p-surface-600, #404040) !important;
}
.distributed-panel--nodes2 .placeholder-card--blueprint.is-hovered {
border-color: var(--p-surface-500, #555555) !important;
}
.distributed-panel--nodes2 .placeholder-card--add {
border-color: var(--p-surface-600, #404040) !important;
}
.distributed-panel--nodes2 .placeholder-card--add.is-hovered {
border-color: var(--p-surface-500, #555555) !important;
}
/* ---- End Nodes 2.0 Theme ---- */
.is-hidden {
display: none !important;
}
+25 -7
View File
@@ -49,6 +49,8 @@ class DistributedExtension {
loadManagedWorkers(this);
// Detect master IP after everything is set up
this.detectMasterIP();
// Listen for Nodes 2.0 setting changes (once, for the lifetime of the extension)
this._setupNodes2Listener();
});
}
@@ -260,7 +262,8 @@ class DistributedExtension {
render: (el) => {
this.panelElement = el;
this.onPanelOpen();
return renderSidebarContent(this, el);
renderSidebarContent(this, el);
this._applyNodes2Style();
},
destroy: () => {
this.onPanelClose();
@@ -274,25 +277,40 @@ class DistributedExtension {
checkAllWorkerStatuses(this);
}
}
onPanelClose() {
this.log("Panel closed - stopping status polling", "debug");
// Cancel any pending status checks
if (this.statusCheckAbortController) {
this.statusCheckAbortController.abort();
this.statusCheckAbortController = null;
}
// Clear the timeout
if (this.statusCheckTimeout) {
clearTimeout(this.statusCheckTimeout);
this.statusCheckTimeout = null;
}
this.panelElement = null;
}
_applyNodes2Style() {
if (!this.panelElement) return;
const enabled = app.ui.settings.getSettingValue("Comfy.VueNodes.Enabled") ?? false;
this.panelElement.classList.toggle('distributed-panel--nodes2', Boolean(enabled));
}
_setupNodes2Listener() {
app.ui.settings.addEventListener("Comfy.VueNodes.Enabled.change", (e) => {
const enabled = e.detail?.value ?? false;
if (this.panelElement) {
this.panelElement.classList.toggle('distributed-panel--nodes2', Boolean(enabled));
}
});
}
// --- Core Logic & Execution ---
setupInterceptor() {
@@ -311,12 +329,12 @@ class DistributedExtension {
clearInterval(this.logAutoRefreshInterval);
this.logAutoRefreshInterval = null;
}
if (this.statusCheckTimeout) {
clearTimeout(this.statusCheckTimeout);
this.statusCheckTimeout = null;
}
this.log("Cleaned up intervals", "debug");
}
+9 -3
View File
@@ -201,6 +201,7 @@ export class DistributedUI {
input.id = id;
input.value = value;
input.placeholder = placeholder;
input.classList.add('dist-form-input');
input.style.cssText = this.styles.formInput;
group.appendChild(labelEl);
@@ -211,6 +212,7 @@ export class DistributedUI {
createInfoBox(text) {
const box = document.createElement("div");
box.classList.add('dist-info-box');
box.style.cssText = this.styles.infoBox;
box.textContent = text;
return box;
@@ -223,18 +225,21 @@ export class DistributedUI {
createCard(type = 'worker', options = {}) {
const card = document.createElement("div");
card.classList.add('dist-card');
switch(type) {
case 'master':
case 'worker':
card.style.cssText = this.styles.workerCard;
break;
case 'blueprint':
card.classList.add('dist-card--blueprint');
card.style.cssText = this.styles.cardBase + this.styles.cardBlueprint;
if (options.onClick) card.onclick = options.onClick;
if (options.title) card.title = options.title;
break;
case 'add':
card.classList.add('dist-card--add');
card.style.cssText = this.styles.cardBase + this.styles.cardAdd;
if (options.onClick) card.onclick = options.onClick;
if (options.title) card.title = options.title;
@@ -253,9 +258,10 @@ export class DistributedUI {
createCardColumn(type = 'checkbox', options = {}) {
const column = document.createElement("div");
switch(type) {
case 'checkbox':
column.classList.add('dist-card__left-col');
column.style.cssText = this.styles.checkboxColumn;
if (options.title) column.title = options.title;
break;
@@ -562,8 +568,8 @@ export class DistributedUI {
const fallbackActive = extension.isMasterFallbackActive();
let message;
const badge = document.createElement("div");
badge.classList.add("dist-info-box", "master-info-badge");
badge.style.cssText = this.styles.infoBox;
badge.classList.add("master-info-badge");
if (fallbackActive) {
message = "No workers selected. Master fallback execution active.";
badge.textContent = message;