feat: vue nodes onboarding toggle in menu

This commit is contained in:
--list
2025-11-12 21:35:03 -08:00
parent f0f554392d
commit f6122397e4
5 changed files with 94 additions and 10 deletions

View File

@@ -1,5 +1,6 @@
<template>
<div
ref="menuButtonRef"
v-tooltip="{
value: t('sideToolbar.labels.menu'),
showDelay: 300,
@@ -29,6 +30,7 @@
>
<template #item="{ item, props }">
<a
v-if="item.key !== 'nodes-2.0-toggle'"
class="p-menubar-item-link px-4 py-2"
v-bind="props.action"
:href="item.url"
@@ -65,6 +67,34 @@
</span>
<i v-if="item.items" class="pi pi-angle-right ml-auto" />
</a>
<div
v-else
class="flex items-center justify-between px-4 py-2"
@click.stop="handleNodes2ToggleClick"
>
<span class="p-menubar-item-label text-nowrap">{{ item.label }}</span>
<ToggleSwitch
v-model="nodes2Enabled"
class="ml-4"
:aria-label="item.label"
:pt="{
root: {
style: {
width: '38px',
height: '20px'
}
},
handle: {
style: {
width: '16px',
height: '16px'
}
}
}"
@click.stop
@update:model-value="onNodes2ToggleChange"
/>
</div>
</template>
</TieredMenu>
</template>
@@ -73,13 +103,16 @@
import type { MenuItem } from 'primevue/menuitem'
import TieredMenu from 'primevue/tieredmenu'
import type { TieredMenuMethods, TieredMenuState } from 'primevue/tieredmenu'
import { computed, nextTick, ref } from 'vue'
import ToggleSwitch from 'primevue/toggleswitch'
import { computed, nextTick, onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import SettingDialogHeader from '@/components/dialog/header/SettingDialogHeader.vue'
import ComfyLogo from '@/components/icons/ComfyLogo.vue'
import { useComfyMenu } from '@/composables/useComfyMenu'
import { useWorkflowTemplateSelectorDialog } from '@/composables/useWorkflowTemplateSelectorDialog'
import SettingDialogContent from '@/platform/settings/components/SettingDialogContent.vue'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useTelemetry } from '@/platform/telemetry'
import { useColorPaletteService } from '@/services/colorPaletteService'
import { useCommandStore } from '@/stores/commandStore'
@@ -98,10 +131,20 @@ const colorPaletteStore = useColorPaletteStore()
const colorPaletteService = useColorPaletteService()
const dialogStore = useDialogStore()
const managerState = useManagerState()
const settingStore = useSettingStore()
const { registerMenuButton } = useComfyMenu()
const menuRef = ref<
({ dirty: boolean } & TieredMenuMethods & TieredMenuState) | null
>(null)
const menuButtonRef = ref<HTMLElement | null>(null)
const nodes2Enabled = computed({
get: () => settingStore.get('Comfy.VueNodes.Enabled') ?? false,
set: async (value: boolean) => {
await settingStore.set('Comfy.VueNodes.Enabled', value)
}
})
const telemetry = useTelemetry()
@@ -112,6 +155,10 @@ function onLogoMenuClick(event: MouseEvent) {
menuRef.value?.toggle(event)
}
onMounted(() => {
registerMenuButton(menuButtonRef.value)
})
const translateMenuItem = (item: MenuItem): MenuItem => {
const label = typeof item.label === 'function' ? item.label() : item.label
const translatedLabel = label
@@ -164,6 +211,10 @@ const extraMenuItems = computed(() => [
label: t('menu.theme'),
items: themeMenuItems.value
},
{
key: 'nodes-2.0-toggle',
label: 'Nodes 2.0'
},
{ separator: true },
{
key: 'browse-templates',
@@ -281,6 +332,17 @@ const hasActiveStateSiblings = (item: MenuItem): boolean => {
menuItemStore.menuItemHasActiveStateChildren[item.parentPath])
)
}
const handleNodes2ToggleClick = () => {
return false
}
const onNodes2ToggleChange = async (value: boolean) => {
await settingStore.set('Comfy.VueNodes.Enabled', value)
telemetry?.trackUiButtonClicked({
button_id: `menu_nodes_2.0_toggle_${value ? 'enabled' : 'disabled'}`
})
}
</script>
<style scoped>

View File

@@ -28,16 +28,16 @@ import Button from 'primevue/button'
import Toast from 'primevue/toast'
import { useI18n } from 'vue-i18n'
import { useComfyMenu } from '@/composables/useComfyMenu'
import { useVueNodesMigrationDismissed } from '@/composables/useVueNodesMigrationDismissed'
import { useDialogService } from '@/services/dialogService'
const { t } = useI18n()
const toast = useToast()
const dialogService = useDialogService()
const { openMenu } = useComfyMenu()
const isDismissed = useVueNodesMigrationDismissed()
const handleOpenSettings = () => {
dialogService.showSettingsDialog()
openMenu()
toast.removeGroup('vue-nodes-migration')
isDismissed.value = true
}

View File

@@ -4,8 +4,8 @@
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"
>
<div class="flex items-center">
<i class="icon-[lucide--sparkles]"></i>
<span class="pl-2">{{ $t('vueNodesBanner.message') }}</span>
<i class="icon-[lucide--rocket]"></i>
<span class="pl-2 text-sm">{{ $t('vueNodesBanner.message') }}</span>
<Button
class="cursor-pointer bg-transparent rounded h-7 px-3 border border-white text-white ml-4 text-xs"
@click="handleTryItOut"

View File

@@ -0,0 +1,22 @@
/**
* Composable for programmatically controlling the ComfyUI main menu
*/
import { ref } from 'vue'
const menuButtonRef = ref<HTMLElement | null>(null)
export function useComfyMenu() {
const registerMenuButton = (el: HTMLElement | null) => {
menuButtonRef.value = el
}
const openMenu = () => {
menuButtonRef.value?.click()
}
return {
registerMenuButton,
openMenu
}
}

View File

@@ -2043,11 +2043,11 @@
}
},
"vueNodesMigration": {
"message": "Prefer the classic node design?",
"button": "Open Settings"
"message": "Want to switch back? Toggle 'Nodes 2.0' off in settings",
"button": "Open main menu"
},
"vueNodesBanner": {
"message": "Nodes just got a new look and feel",
"message": "Introducing Nodes 2.0 More flexible workflows, powerful new widgets, built for extensibility",
"tryItOut": "Try it out"
},
"cloud": {
@@ -2062,4 +2062,4 @@
"cannotRun": "Workflow contains unsupported nodes (highlighted red). Remove these to run the workflow. "
}
}
}
}