Skip to content

Commit d09f948

Browse files
authored
Merge branch 'main' into drjkl/first-things-first
2 parents 69efc65 + 75fd4f0 commit d09f948

File tree

123 files changed

+6792
-1635
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+6792
-1635
lines changed

browser_tests/tests/colorPalette.spec.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,25 @@ test.describe('Node Color Adjustments', () => {
232232
}) => {
233233
await comfyPage.setSetting('Comfy.Node.Opacity', 0.5)
234234
await comfyPage.setSetting('Comfy.ColorPalette', 'light')
235-
const saveWorkflowInterval = 1000
236-
const workflow = await comfyPage.page.evaluate(() => {
237-
return localStorage.getItem('workflow')
238-
})
239-
for (const node of JSON.parse(workflow ?? '{}').nodes) {
235+
await comfyPage.nextFrame()
236+
const parsed = await (
237+
await comfyPage.page.waitForFunction(
238+
() => {
239+
const workflow = localStorage.getItem('workflow')
240+
if (!workflow) return null
241+
try {
242+
const data = JSON.parse(workflow)
243+
return Array.isArray(data?.nodes) ? data : null
244+
} catch {
245+
return null
246+
}
247+
},
248+
{ timeout: 3000 }
249+
)
250+
).jsonValue()
251+
expect(parsed.nodes).toBeDefined()
252+
expect(Array.isArray(parsed.nodes)).toBe(true)
253+
for (const node of parsed.nodes) {
240254
if (node.bgcolor) expect(node.bgcolor).not.toMatch(/hsla/)
241255
if (node.color) expect(node.color).not.toMatch(/hsla/)
242256
}
-1006 Bytes
Loading

eslint.config.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,20 @@ export default defineConfig([
240240
]
241241
}
242242
},
243+
{
244+
files: ['**/*.test.ts'],
245+
rules: {
246+
'no-restricted-properties': [
247+
'error',
248+
{
249+
object: 'vi',
250+
property: 'doMock',
251+
message:
252+
'Use vi.mock() with vi.hoisted() instead of vi.doMock(). See docs/testing/vitest-patterns.md'
253+
}
254+
]
255+
}
256+
},
243257
{
244258
files: ['scripts/**/*.js'],
245259
languageOptions: {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@comfyorg/comfyui-frontend",
33
"private": true,
4-
"version": "1.38.10",
4+
"version": "1.38.12",
55
"type": "module",
66
"repository": "https://github.com/Comfy-Org/ComfyUI_frontend",
77
"homepage": "https://comfy.org",

src/components/dialog/content/setting/CurrentUserMessage.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
severity="info"
66
icon="pi pi-user"
77
pt:text="w-full"
8+
data-testid="current-user-indicator"
89
>
910
<div class="flex items-center justify-between">
10-
<div data-testid="current-user-indicator">
11+
<div class="tabular-nums">
1112
{{ $t('g.currentUser') }}: {{ userStore.currentUser?.username }}
1213
</div>
1314
<Button

src/components/graph/selectionToolbox/BypassButton.test.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,10 @@ describe('BypassButton', () => {
8585
})
8686

8787
it('should show bypassed styling when node is bypassed', async () => {
88-
const bypassedNode: Partial<LGraphNode> = {
89-
...getMockLGraphNode(),
88+
const bypassedNode = Object.assign(getMockLGraphNode(), {
9089
mode: LGraphEventMode.BYPASS
91-
}
92-
canvasStore.selectedItems = [bypassedNode as LGraphNode]
90+
})
91+
canvasStore.selectedItems = [bypassedNode]
9392
vi.spyOn(commandStore, 'execute').mockResolvedValue()
9493
const wrapper = mountComponent()
9594

src/components/rightSidePanel/settings/LayoutField.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@ defineProps<{
2525
"
2626
:class="
2727
cn(
28-
'text-sm text-muted-foreground truncate',
28+
'text-sm text-muted-foreground truncate group',
2929
tooltip ? 'cursor-help' : '',
3030
singleline ? 'flex-1' : ''
3131
)
3232
"
3333
>
3434
{{ label }}
35+
36+
<i
37+
v-if="tooltip"
38+
class="icon-[lucide--info] ml-0.5 size-3 relative top-[1px] group-hover:text-primary"
39+
/>
3540
</span>
3641
<slot />
3742
</div>

src/components/rightSidePanel/settings/TabGlobalSettings.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,17 @@ function openFullSettings() {
107107
<FieldSwitch
108108
v-model="showAdvancedParameters"
109109
:label="t('rightSidePanel.globalSettings.showAdvanced')"
110-
:tooltip="t('rightSidePanel.globalSettings.showAdvancedTooltip')"
110+
:tooltip="t('settings.Comfy_Node_AlwaysShowAdvancedWidgets.tooltip')"
111111
/>
112112
<FieldSwitch
113113
v-model="showToolbox"
114114
:label="t('rightSidePanel.globalSettings.showToolbox')"
115+
:tooltip="t('settings.Comfy_Canvas_SelectionToolbox.tooltip')"
115116
/>
116117
<FieldSwitch
117118
v-model="nodes2Enabled"
118119
:label="t('rightSidePanel.globalSettings.nodes2')"
120+
:tooltip="t('settings.Comfy_VueNodes_Enabled.tooltip')"
119121
/>
120122
</div>
121123
</PropertiesAccordionItem>
@@ -156,6 +158,7 @@ function openFullSettings() {
156158
<FieldSwitch
157159
v-model="snapToGrid"
158160
:label="t('rightSidePanel.globalSettings.snapNodesToGrid')"
161+
:tooltip="t('settings.pysssss_SnapToGrid.tooltip')"
159162
/>
160163
</div>
161164
</PropertiesAccordionItem>
@@ -187,6 +190,7 @@ function openFullSettings() {
187190
<FieldSwitch
188191
v-model="showConnectedLinks"
189192
:label="t('rightSidePanel.globalSettings.showConnectedLinks')"
193+
:tooltip="t('settings.Comfy_LinkRenderMode.tooltip')"
190194
/>
191195
</div>
192196
</PropertiesAccordionItem>

src/components/topbar/CurrentUserButton.test.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,24 @@ vi.mock('firebase/auth', () => ({
2525
}))
2626

2727
// Mock pinia
28-
vi.mock('pinia')
28+
vi.mock('pinia', () => ({
29+
storeToRefs: vi.fn((store) => store)
30+
}))
31+
32+
// Mock the useFeatureFlags composable
33+
vi.mock('@/composables/useFeatureFlags', () => ({
34+
useFeatureFlags: vi.fn(() => ({
35+
flags: { teamWorkspacesEnabled: false }
36+
}))
37+
}))
38+
39+
// Mock the useTeamWorkspaceStore
40+
vi.mock('@/platform/workspace/stores/teamWorkspaceStore', () => ({
41+
useTeamWorkspaceStore: vi.fn(() => ({
42+
workspaceName: { value: '' },
43+
initState: { value: 'idle' }
44+
}))
45+
}))
2946

3047
// Mock the useCurrentUser composable
3148
vi.mock('@/composables/auth/useCurrentUser', () => ({

src/components/topbar/CurrentUserButton.vue

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,18 @@
1212
:class="
1313
cn(
1414
'flex items-center gap-1 rounded-full hover:bg-interface-button-hover-surface justify-center',
15-
compact && 'size-full aspect-square'
15+
compact && 'size-full '
1616
)
1717
"
1818
>
19+
<Skeleton
20+
v-if="showWorkspaceSkeleton"
21+
shape="circle"
22+
width="32px"
23+
height="32px"
24+
/>
1925
<WorkspaceProfilePic
20-
v-if="showWorkspaceIcon"
26+
v-else-if="showWorkspaceIcon"
2127
:workspace-name="workspaceName"
2228
:class="compact && 'size-full'"
2329
/>
@@ -40,20 +46,24 @@
4046
}
4147
}"
4248
>
43-
<!-- Workspace mode: workspace-aware popover -->
49+
<!-- Workspace mode: workspace-aware popover (only when ready) -->
4450
<CurrentUserPopoverWorkspace
45-
v-if="teamWorkspacesEnabled"
51+
v-if="teamWorkspacesEnabled && initState === 'ready'"
4652
@close="closePopover"
4753
/>
4854
<!-- Legacy mode: original popover -->
49-
<CurrentUserPopover v-else @close="closePopover" />
55+
<CurrentUserPopover
56+
v-else-if="!teamWorkspacesEnabled"
57+
@close="closePopover"
58+
/>
5059
</Popover>
5160
</div>
5261
</template>
5362

5463
<script setup lang="ts">
5564
import { storeToRefs } from 'pinia'
5665
import Popover from 'primevue/popover'
66+
import Skeleton from 'primevue/skeleton'
5767
import { computed, defineAsyncComponent, ref } from 'vue'
5868
5969
import UserAvatar from '@/components/common/UserAvatar.vue'
@@ -85,12 +95,20 @@ const photoURL = computed<string | undefined>(
8595
() => userPhotoUrl.value ?? undefined
8696
)
8797
88-
const showWorkspaceIcon = computed(() => isCloud && teamWorkspacesEnabled.value)
98+
const { workspaceName: teamWorkspaceName, initState } = storeToRefs(
99+
useTeamWorkspaceStore()
100+
)
101+
102+
const showWorkspaceSkeleton = computed(
103+
() => isCloud && teamWorkspacesEnabled.value && initState.value === 'loading'
104+
)
105+
const showWorkspaceIcon = computed(
106+
() => isCloud && teamWorkspacesEnabled.value && initState.value === 'ready'
107+
)
89108
90109
const workspaceName = computed(() => {
91110
if (!showWorkspaceIcon.value) return ''
92-
const { workspaceName } = storeToRefs(useTeamWorkspaceStore())
93-
return workspaceName.value
111+
return teamWorkspaceName.value
94112
})
95113
96114
const popover = ref<InstanceType<typeof Popover> | null>(null)

0 commit comments

Comments
 (0)