Skip to content

Commit a8fbb97

Browse files
committed
feat: vue nodes onboarding toggle in menu
1 parent 63ca4a3 commit a8fbb97

File tree

5 files changed

+94
-10
lines changed

5 files changed

+94
-10
lines changed

src/components/sidebar/ComfyMenuButton.vue

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<template>
22
<div
3+
ref="menuButtonRef"
34
v-tooltip="{
45
value: t('sideToolbar.labels.menu'),
56
showDelay: 300,
@@ -29,6 +30,7 @@
2930
>
3031
<template #item="{ item, props }">
3132
<a
33+
v-if="item.key !== 'nodes-2.0-toggle'"
3234
class="p-menubar-item-link px-4 py-2"
3335
v-bind="props.action"
3436
:href="item.url"
@@ -65,6 +67,34 @@
6567
</span>
6668
<i v-if="item.items" class="pi pi-angle-right ml-auto" />
6769
</a>
70+
<div
71+
v-else
72+
class="flex items-center justify-between px-4 py-2"
73+
@click.stop="handleNodes2ToggleClick"
74+
>
75+
<span class="p-menubar-item-label text-nowrap">{{ item.label }}</span>
76+
<ToggleSwitch
77+
v-model="nodes2Enabled"
78+
class="ml-4"
79+
:aria-label="item.label"
80+
:pt="{
81+
root: {
82+
style: {
83+
width: '38px',
84+
height: '20px'
85+
}
86+
},
87+
handle: {
88+
style: {
89+
width: '16px',
90+
height: '16px'
91+
}
92+
}
93+
}"
94+
@click.stop
95+
@update:model-value="onNodes2ToggleChange"
96+
/>
97+
</div>
6898
</template>
6999
</TieredMenu>
70100
</template>
@@ -73,13 +103,16 @@
73103
import type { MenuItem } from 'primevue/menuitem'
74104
import TieredMenu from 'primevue/tieredmenu'
75105
import type { TieredMenuMethods, TieredMenuState } from 'primevue/tieredmenu'
76-
import { computed, nextTick, ref } from 'vue'
106+
import ToggleSwitch from 'primevue/toggleswitch'
107+
import { computed, nextTick, onMounted, ref } from 'vue'
77108
import { useI18n } from 'vue-i18n'
78109
79110
import SettingDialogHeader from '@/components/dialog/header/SettingDialogHeader.vue'
80111
import ComfyLogo from '@/components/icons/ComfyLogo.vue'
112+
import { useComfyMenu } from '@/composables/useComfyMenu'
81113
import { useWorkflowTemplateSelectorDialog } from '@/composables/useWorkflowTemplateSelectorDialog'
82114
import SettingDialogContent from '@/platform/settings/components/SettingDialogContent.vue'
115+
import { useSettingStore } from '@/platform/settings/settingStore'
83116
import { useTelemetry } from '@/platform/telemetry'
84117
import { useColorPaletteService } from '@/services/colorPaletteService'
85118
import { useCommandStore } from '@/stores/commandStore'
@@ -98,10 +131,20 @@ const colorPaletteStore = useColorPaletteStore()
98131
const colorPaletteService = useColorPaletteService()
99132
const dialogStore = useDialogStore()
100133
const managerState = useManagerState()
134+
const settingStore = useSettingStore()
135+
const { registerMenuButton } = useComfyMenu()
101136
102137
const menuRef = ref<
103138
({ dirty: boolean } & TieredMenuMethods & TieredMenuState) | null
104139
>(null)
140+
const menuButtonRef = ref<HTMLElement | null>(null)
141+
142+
const nodes2Enabled = computed({
143+
get: () => settingStore.get('Comfy.VueNodes.Enabled') ?? false,
144+
set: async (value: boolean) => {
145+
await settingStore.set('Comfy.VueNodes.Enabled', value)
146+
}
147+
})
105148
106149
const telemetry = useTelemetry()
107150
@@ -112,6 +155,10 @@ function onLogoMenuClick(event: MouseEvent) {
112155
menuRef.value?.toggle(event)
113156
}
114157
158+
onMounted(() => {
159+
registerMenuButton(menuButtonRef.value)
160+
})
161+
115162
const translateMenuItem = (item: MenuItem): MenuItem => {
116163
const label = typeof item.label === 'function' ? item.label() : item.label
117164
const translatedLabel = label
@@ -164,6 +211,10 @@ const extraMenuItems = computed(() => [
164211
label: t('menu.theme'),
165212
items: themeMenuItems.value
166213
},
214+
{
215+
key: 'nodes-2.0-toggle',
216+
label: 'Nodes 2.0'
217+
},
167218
{ separator: true },
168219
{
169220
key: 'browse-templates',
@@ -281,6 +332,17 @@ const hasActiveStateSiblings = (item: MenuItem): boolean => {
281332
menuItemStore.menuItemHasActiveStateChildren[item.parentPath])
282333
)
283334
}
335+
336+
const handleNodes2ToggleClick = () => {
337+
return false
338+
}
339+
340+
const onNodes2ToggleChange = async (value: boolean) => {
341+
await settingStore.set('Comfy.VueNodes.Enabled', value)
342+
telemetry?.trackUiButtonClicked({
343+
button_id: `menu_nodes_2.0_toggle_${value ? 'enabled' : 'disabled'}`
344+
})
345+
}
284346
</script>
285347

286348
<style scoped>

src/components/toast/VueNodesMigrationToast.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,16 @@ import Button from 'primevue/button'
2828
import Toast from 'primevue/toast'
2929
import { useI18n } from 'vue-i18n'
3030
31+
import { useComfyMenu } from '@/composables/useComfyMenu'
3132
import { useVueNodesMigrationDismissed } from '@/composables/useVueNodesMigrationDismissed'
32-
import { useDialogService } from '@/services/dialogService'
3333
3434
const { t } = useI18n()
3535
const toast = useToast()
36-
const dialogService = useDialogService()
36+
const { openMenu } = useComfyMenu()
3737
const isDismissed = useVueNodesMigrationDismissed()
3838
3939
const handleOpenSettings = () => {
40-
dialogService.showSettingsDialog()
40+
openMenu()
4141
toast.removeGroup('vue-nodes-migration')
4242
isDismissed.value = true
4343
}

src/components/topbar/TryVueNodeBanner.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
class="pointer-events-auto relative w-full h-10 bg-gradient-to-r from-blue-600 to-blue-700 flex items-center justify-center px-4"
55
>
66
<div class="flex items-center">
7-
<i class="icon-[lucide--sparkles]"></i>
8-
<span class="pl-2">{{ $t('vueNodesBanner.message') }}</span>
7+
<i class="icon-[lucide--rocket]"></i>
8+
<span class="pl-2 text-sm">{{ $t('vueNodesBanner.message') }}</span>
99
<Button
1010
class="cursor-pointer bg-transparent rounded h-7 px-3 border border-white text-white ml-4 text-xs"
1111
@click="handleTryItOut"

src/composables/useComfyMenu.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Composable for programmatically controlling the ComfyUI main menu
3+
*/
4+
5+
import { ref } from 'vue'
6+
7+
const menuButtonRef = ref<HTMLElement | null>(null)
8+
9+
export function useComfyMenu() {
10+
const registerMenuButton = (el: HTMLElement | null) => {
11+
menuButtonRef.value = el
12+
}
13+
14+
const openMenu = () => {
15+
menuButtonRef.value?.click()
16+
}
17+
18+
return {
19+
registerMenuButton,
20+
openMenu
21+
}
22+
}

src/locales/en/main.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2043,11 +2043,11 @@
20432043
}
20442044
},
20452045
"vueNodesMigration": {
2046-
"message": "Prefer the classic node design?",
2047-
"button": "Open Settings"
2046+
"message": "Want to switch back? Toggle 'Nodes 2.0' off in settings",
2047+
"button": "Open main menu"
20482048
},
20492049
"vueNodesBanner": {
2050-
"message": "Nodes just got a new look and feel",
2050+
"message": "Introducing Nodes 2.0 – More flexible workflows, powerful new widgets, built for extensibility",
20512051
"tryItOut": "Try it out"
20522052
},
20532053
"cloud": {
@@ -2062,4 +2062,4 @@
20622062
"cannotRun": "Workflow contains unsupported nodes (highlighted red). Remove these to run the workflow. "
20632063
}
20642064
}
2065-
}
2065+
}

0 commit comments

Comments
 (0)