Skip to content

Commit bb83b01

Browse files
fix Vue node border styles in different states (executing, error, selected) (#6018)
- Use exact tokens from Figma - Fix issue in which node is stuck in `executing` state after it errors ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6018-fix-Vue-node-border-styles-in-different-states-executing-error-selected-2896d73d365081f39000fc3e42811f0d) by [Unito](https://www.unito.io)
1 parent a0c02df commit bb83b01

File tree

5 files changed

+42
-24
lines changed

5 files changed

+42
-24
lines changed

browser_tests/fixtures/ComfyPage.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { APIRequestContext, Locator, Page } from '@playwright/test'
2-
import { expect } from '@playwright/test'
3-
import { test as base } from '@playwright/test'
2+
import { test as base, expect } from '@playwright/test'
43
import dotenv from 'dotenv'
54
import * as fs from 'fs'
65

@@ -130,7 +129,8 @@ export class ComfyPage {
130129

131130
// Buttons
132131
public readonly resetViewButton: Locator
133-
public readonly queueButton: Locator
132+
public readonly queueButton: Locator // Run button in Legacy UI
133+
public readonly runButton: Locator // Run button (renamed "Queue" -> "Run")
134134

135135
// Inputs
136136
public readonly workflowUploadInput: Locator
@@ -165,6 +165,9 @@ export class ComfyPage {
165165
this.widgetTextBox = page.getByPlaceholder('text').nth(1)
166166
this.resetViewButton = page.getByRole('button', { name: 'Reset View' })
167167
this.queueButton = page.getByRole('button', { name: 'Queue Prompt' })
168+
this.runButton = page
169+
.getByTestId('queue-button')
170+
.getByRole('button', { name: 'Run' })
168171
this.workflowUploadInput = page.locator('#comfy-file-input')
169172
this.visibleToasts = page.locator('.p-toast-message:visible')
170173

@@ -1086,12 +1089,6 @@ export class ComfyPage {
10861089

10871090
const targetPosition = await targetSlot.getPosition()
10881091

1089-
// Debug: Log the positions we're trying to use
1090-
console.log('Drag positions:', {
1091-
source: sourcePosition,
1092-
target: targetPosition
1093-
})
1094-
10951092
await this.dragAndDrop(sourcePosition, targetPosition)
10961093
await this.nextFrame()
10971094
}

browser_tests/tests/vueNodes/nodeStates/error.spec.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
comfyPageFixture as test
44
} from '../../../fixtures/ComfyPage'
55

6-
const ERROR_CLASS = /border-error/
6+
const ERROR_CLASS = /border-node-stroke-error/
77

88
test.describe('Vue Node Error', () => {
99
test.beforeEach(async ({ comfyPage }) => {
@@ -17,16 +17,21 @@ test.describe('Vue Node Error', () => {
1717
await comfyPage.setup()
1818
await comfyPage.loadWorkflow('missing/missing_nodes')
1919

20-
// Close missing nodes warning dialog
21-
await comfyPage.page.getByRole('button', { name: 'Close' }).click()
22-
await comfyPage.page.waitForSelector('.comfy-missing-nodes', {
23-
state: 'hidden'
24-
})
25-
2620
// Expect error state on missing unknown node
2721
const unknownNode = comfyPage.page.locator('[data-node-id]').filter({
2822
hasText: 'UNKNOWN NODE'
2923
})
3024
await expect(unknownNode).toHaveClass(ERROR_CLASS)
3125
})
26+
27+
test('should display error state when node causes execution error', async ({
28+
comfyPage
29+
}) => {
30+
await comfyPage.setup()
31+
await comfyPage.loadWorkflow('nodes/execution_error')
32+
await comfyPage.runButton.click()
33+
34+
const raiseErrorNode = comfyPage.vueNodes.getNodeByTitle('Raise Error')
35+
await expect(raiseErrorNode).toHaveClass(ERROR_CLASS)
36+
})
3237
})

packages/design-system/src/css/style.css

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129

130130
/* --- */
131131

132+
--accent-primary: var(--color-charcoal-700);
132133
--backdrop: var(--color-white);
133134
--dialog-surface: var(--color-neutral-200);
134135
--node-component-border: var(--color-gray-400);
@@ -154,13 +155,20 @@
154155
from var(--color-zinc-500) r g b / 10%
155156
);
156157
--node-component-widget-skeleton-surface: var(--color-zinc-300);
157-
--node-stroke: var(--color-stone-100);
158+
--node-stroke: var(--color-gray-400);
159+
--node-stroke-selected: var(--color-accent-primary);
160+
--node-stroke-error: var(--color-error);
161+
--node-stroke-executing: var(--color-blue-100);
158162
}
159163

160164
.dark-theme {
165+
--accent-primary: var(--color-pure-white);
161166
--backdrop: var(--color-neutral-900);
162167
--dialog-surface: var(--color-neutral-700);
163168
--node-component-border: var(--color-stone-200);
169+
--node-component-border-error: var(--color-danger-100);
170+
--node-component-border-executing: var(--color-blue-500);
171+
--node-component-border-selected: var(--color-charcoal-200);
164172
--node-component-header-icon: var(--color-slate-300);
165173
--node-component-header-surface: var(--color-charcoal-800);
166174
--node-component-outline: var(--color-white);
@@ -176,7 +184,10 @@
176184
--node-component-tooltip-border: var(--color-slate-300);
177185
--node-component-tooltip-surface: var(--color-charcoal-800);
178186
--node-component-widget-skeleton-surface: var(--color-zinc-800);
179-
--node-stroke: var(--color-slate-100);
187+
--node-stroke: var(--color-stone-200);
188+
--node-stroke-selected: var(--color-pure-white);
189+
--node-stroke-error: var(--color-error);
190+
--node-stroke-executing: var(--color-blue-100);
180191
}
181192

182193
@theme inline {
@@ -214,6 +225,9 @@
214225
--node-component-widget-skeleton-surface
215226
);
216227
--color-node-stroke: var(--node-stroke);
228+
--color-node-stroke-selected: var(--node-stroke-selected);
229+
--color-node-stroke-error: var(--node-stroke-error);
230+
--color-node-stroke-executing: var(--node-stroke-executing);
217231
}
218232

219233
@custom-variant dark-theme {

src/renderer/extensions/vueNodes/components/LGraphNode.vue

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,9 @@ const { latestPreviewUrl, shouldShowPreviewImg } = useNodePreviewState(
319319
)
320320
321321
const borderClass = computed(() => {
322-
return (
323-
(hasAnyError.value && 'border-error') ||
324-
(executing.value && 'border-node-executing')
325-
)
322+
if (hasAnyError.value) return 'border-node-stroke-error'
323+
if (executing.value) return 'border-node-stroke-executing'
324+
return 'border-node-stroke'
326325
})
327326
328327
const outlineClass = computed(() => {

src/renderer/extensions/vueNodes/execution/useNodeExecutionState.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@ export const useNodeExecutionState = (
1717
nodeLocatorIdMaybe: MaybeRefOrGetter<string | undefined>
1818
) => {
1919
const locatorId = computed(() => toValue(nodeLocatorIdMaybe) ?? '')
20-
const { nodeLocationProgressStates } = storeToRefs(useExecutionStore())
20+
const { nodeLocationProgressStates, isIdle } =
21+
storeToRefs(useExecutionStore())
2122

2223
const progressState = computed(() => {
2324
const id = locatorId.value
2425
return id ? nodeLocationProgressStates.value[id] : undefined
2526
})
2627

27-
const executing = computed(() => progressState.value?.state === 'running')
28+
const executing = computed(
29+
() => !isIdle.value && progressState.value?.state === 'running'
30+
)
2831

2932
const progress = computed(() => {
3033
const state = progressState.value

0 commit comments

Comments
 (0)