diff --git a/src/components/dialog/content/LoadWorkflowWarning.vue b/src/components/dialog/content/LoadWorkflowWarning.vue index 543965a8b..43ab5cb60 100644 --- a/src/components/dialog/content/LoadWorkflowWarning.vue +++ b/src/components/dialog/content/LoadWorkflowWarning.vue @@ -51,6 +51,7 @@ import Button from 'primevue/button' import ListBox from 'primevue/listbox' import { computed, onMounted, ref } from 'vue' +import { useI18n } from 'vue-i18n' import NoResultsPlaceholder from '@/components/common/NoResultsPlaceholder.vue' import MissingCoreNodesMessage from '@/components/dialog/content/MissingCoreNodesMessage.vue' @@ -58,6 +59,12 @@ import { useMissingNodes } from '@/composables/nodePack/useMissingNodes' import { useComfyManagerService } from '@/services/comfyManagerService' import { useDialogService } from '@/services/dialogService' import { useComfyManagerStore } from '@/stores/comfyManagerStore' +import { useCommandStore } from '@/stores/commandStore' +import { + ManagerUIState, + useManagerStateStore +} from '@/stores/managerStateStore' +import { useToastStore } from '@/stores/toastStore' import type { MissingNodeType } from '@/types/comfy' import { ManagerTab } from '@/types/comfyManagerTypes' @@ -103,10 +110,37 @@ const uniqueNodes = computed(() => { }) }) -const openManager = () => { - useDialogService().showManagerDialog({ - initialTab: ManagerTab.Missing - }) +const managerStateStore = useManagerStateStore() + +const openManager = async () => { + const state = managerStateStore.managerUIState + + switch (state) { + case ManagerUIState.DISABLED: + useDialogService().showSettingsDialog('extension') + break + + case ManagerUIState.LEGACY_UI: + try { + await useCommandStore().execute('Comfy.Manager.Menu.ToggleVisibility') + } catch { + // If legacy command doesn't exist, show toast + const { t } = useI18n() + useToastStore().add({ + severity: 'error', + summary: t('g.error'), + detail: t('manager.legacyMenuNotAvailable'), + life: 3000 + }) + } + break + + case ManagerUIState.NEW_UI: + useDialogService().showManagerDialog({ + initialTab: ManagerTab.Missing + }) + break + } } onMounted(async () => { diff --git a/src/components/topbar/CommandMenubar.vue b/src/components/topbar/CommandMenubar.vue index d64cf92e5..56e06ac10 100644 --- a/src/components/topbar/CommandMenubar.vue +++ b/src/components/topbar/CommandMenubar.vue @@ -107,9 +107,12 @@ import SubgraphBreadcrumb from '@/components/breadcrumb/SubgraphBreadcrumb.vue' import SettingDialogContent from '@/components/dialog/content/SettingDialogContent.vue' import SettingDialogHeader from '@/components/dialog/header/SettingDialogHeader.vue' import { useDialogService } from '@/services/dialogService' -import { useAboutPanelStore } from '@/stores/aboutPanelStore' import { useCommandStore } from '@/stores/commandStore' import { useDialogStore } from '@/stores/dialogStore' +import { + ManagerUIState, + useManagerStateStore +} from '@/stores/managerStateStore' import { useMenuItemStore } from '@/stores/menuItemStore' import { useSettingStore } from '@/stores/settingStore' import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore' @@ -121,7 +124,6 @@ const colorPaletteStore = useColorPaletteStore() const menuItemsStore = useMenuItemStore() const commandStore = useCommandStore() const dialogStore = useDialogStore() -const aboutPanelStore = useAboutPanelStore() const settingStore = useSettingStore() const { t } = useI18n() @@ -157,23 +159,28 @@ const showSettings = (defaultPanel?: string) => { }) } -// Temporary duplicated from LoadWorkflowWarning.vue -// Determines if ComfyUI-Manager is installed by checking for its badge in the about panel -// This allows us to conditionally show the Manager button only when the extension is available -// TODO: Remove this check when Manager functionality is fully migrated into core -const isManagerInstalled = computed(() => { - return aboutPanelStore.badges.some( - (badge) => - badge.label.includes('ComfyUI-Manager') || - badge.url.includes('ComfyUI-Manager') - ) -}) +const managerStateStore = useManagerStateStore() -const showManageExtensions = () => { - if (isManagerInstalled.value) { - useDialogService().showManagerDialog() - } else { - showSettings('extension') +const showManageExtensions = async () => { + const state = managerStateStore.managerUIState + + switch (state) { + case ManagerUIState.DISABLED: + showSettings('extension') + break + + case ManagerUIState.LEGACY_UI: + try { + await commandStore.execute('Comfy.Manager.Menu.ToggleVisibility') + } catch { + // If legacy command doesn't exist, fall back to extensions panel + showSettings('extension') + } + break + + case ManagerUIState.NEW_UI: + useDialogService().showManagerDialog() + break } } diff --git a/src/composables/useCoreCommands.ts b/src/composables/useCoreCommands.ts index 2ad3e5653..e0509586d 100644 --- a/src/composables/useCoreCommands.ts +++ b/src/composables/useCoreCommands.ts @@ -760,12 +760,8 @@ export function useCoreCommands(): ComfyCommand[] { useCommandStore() .execute('Comfy.Manager.Menu.ToggleVisibility') .catch(() => { - toastStore.add({ - severity: 'error', - summary: t('g.error'), - detail: t('manager.legacyMenuNotAvailable'), - life: 3000 - }) + // If legacy command doesn't exist, fall back to extensions panel + dialogService.showSettingsDialog('extension') }) break @@ -780,10 +776,32 @@ export function useCoreCommands(): ComfyCommand[] { icon: 'pi pi-sync', label: 'Check for Custom Node Updates', versionAdded: '1.17.0', - function: () => { - dialogService.showManagerDialog({ - initialTab: ManagerTab.UpdateAvailable - }) + function: async () => { + const managerStore = useManagerStateStore() + const state = managerStore.managerUIState + + switch (state) { + case ManagerUIState.DISABLED: + dialogService.showSettingsDialog('extension') + break + + case ManagerUIState.LEGACY_UI: + try { + await useCommandStore().execute( + 'Comfy.Manager.Menu.ToggleVisibility' + ) + } catch { + // If legacy command doesn't exist, fall back to extensions panel + dialogService.showSettingsDialog('extension') + } + break + + case ManagerUIState.NEW_UI: + dialogService.showManagerDialog({ + initialTab: ManagerTab.UpdateAvailable + }) + break + } } }, { @@ -791,10 +809,33 @@ export function useCoreCommands(): ComfyCommand[] { icon: 'pi pi-exclamation-circle', label: 'Install Missing Custom Nodes', versionAdded: '1.17.0', - function: () => { - dialogService.showManagerDialog({ - initialTab: ManagerTab.Missing - }) + function: async () => { + const managerStore = useManagerStateStore() + const state = managerStore.managerUIState + + switch (state) { + case ManagerUIState.DISABLED: + // When manager is disabled, open the extensions panel in settings + dialogService.showSettingsDialog('extension') + break + + case ManagerUIState.LEGACY_UI: + try { + await useCommandStore().execute( + 'Comfy.Manager.Menu.ToggleVisibility' + ) + } catch { + // If legacy command doesn't exist, fall back to extensions panel + dialogService.showSettingsDialog('extension') + } + break + + case ManagerUIState.NEW_UI: + dialogService.showManagerDialog({ + initialTab: ManagerTab.Missing + }) + break + } } }, { diff --git a/src/services/comfyManagerService.ts b/src/services/comfyManagerService.ts index 330d5dd0f..bed1f9eed 100644 --- a/src/services/comfyManagerService.ts +++ b/src/services/comfyManagerService.ts @@ -1,6 +1,7 @@ import axios, { AxiosError, AxiosResponse } from 'axios' import { ref } from 'vue' +import { ServerFeatureFlag } from '@/composables/useFeatureFlags' import { api } from '@/scripts/api' import { type InstallPackParams, @@ -35,8 +36,12 @@ enum ManagerRoute { IS_LEGACY_MANAGER_UI = 'manager/is_legacy_manager_ui' } +// Create axios client with conditional v2 prefix based on manager v4 support +const supportsV4 = api.getServerFeature(ServerFeatureFlag.MANAGER_SUPPORTS_V4) +const baseURL = supportsV4 ? api.apiURL('/v2/') : api.apiURL('/') + const managerApiClient = axios.create({ - baseURL: api.apiURL('/v2/'), + baseURL, headers: { 'Content-Type': 'application/json' }