mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
feat: add Update ComfyUI option to Help Center for non-desktop environments (#7578)
## Summary - Adds "Update ComfyUI" menu item to Help Center for portable/localhost environments - Wires existing `/v2/manager/queue/update_comfyui` endpoint to the frontend - Only visible in non-desktop, non-cloud distributions (where Electron update mechanism isn't available) ## Changes 1. **Service layer**: Added `updateComfyUI()` method to `comfyManagerService.ts` 2. **UI**: Added menu item with download icon to `HelpCenterMenuContent.vue` 3. **i18n**: Added translation key for the new menu item ## Context The new Manager UI (v4) lost the ability to update ComfyUI core in non-desktop environments. This restores that functionality by integrating the existing manager endpoint into the Help Center menu. ## Test plan - [ ] Verify menu item appears in portable/localhost environments - [ ] Verify menu item does NOT appear in desktop (Electron) environments - [ ] Verify menu item does NOT appear in cloud environments - [ ] Test clicking the menu item triggers update and reboot ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7578-feat-add-Update-ComfyUI-option-to-Help-Center-for-non-desktop-environments-2cc6d73d3650811e9e4fe55515f50333) by [Unito](https://www.unito.io)
This commit is contained in:
committed by
GitHub
parent
3e111bd75c
commit
890ab2019f
@@ -152,6 +152,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useToast } from 'primevue/usetoast'
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import type { CSSProperties, Component } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
@@ -168,6 +169,7 @@ import { electronAPI, isElectron } from '@/utils/envUtil'
|
||||
import { formatVersionAnchor } from '@/utils/formatUtil'
|
||||
import { useConflictAcknowledgment } from '@/workbench/extensions/manager/composables/useConflictAcknowledgment'
|
||||
import { useManagerState } from '@/workbench/extensions/manager/composables/useManagerState'
|
||||
import { useComfyManagerService } from '@/workbench/extensions/manager/services/comfyManagerService'
|
||||
import { ManagerTab } from '@/workbench/extensions/manager/types/comfyManagerTypes'
|
||||
|
||||
// Types
|
||||
@@ -201,6 +203,7 @@ const SUBMENU_CONFIG = {
|
||||
|
||||
// Composables
|
||||
const { t } = useI18n()
|
||||
const toast = useToast()
|
||||
const { staticUrls, buildDocsUrl } = useExternalLink()
|
||||
const releaseStore = useReleaseStore()
|
||||
const commandStore = useCommandStore()
|
||||
@@ -230,6 +233,7 @@ const showVersionUpdates = computed(() =>
|
||||
// Use conflict acknowledgment state from composable
|
||||
const { shouldShowRedDot: shouldShowManagerRedDot } =
|
||||
useConflictAcknowledgment()
|
||||
const { isNewManagerUI } = useManagerState()
|
||||
|
||||
const moreItems = computed<MenuItem[]>(() => {
|
||||
const allMoreItems: MenuItem[] = [
|
||||
@@ -369,6 +373,19 @@ const menuItems = computed<MenuItem[]>(() => {
|
||||
}
|
||||
})
|
||||
}
|
||||
// Update ComfyUI - only for non-desktop, non-cloud with new manager UI
|
||||
if (!isElectron() && !isCloud && isNewManagerUI.value) {
|
||||
items.push({
|
||||
key: 'update-comfyui',
|
||||
type: 'item',
|
||||
icon: 'icon-[lucide--download]',
|
||||
label: t('helpCenter.updateComfyUI'),
|
||||
action: () => {
|
||||
onUpdateComfyUI()
|
||||
emit('close')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
items.push({
|
||||
key: 'more',
|
||||
@@ -545,6 +562,47 @@ const onReinstall = (): void => {
|
||||
}
|
||||
}
|
||||
|
||||
const onUpdateComfyUI = async (): Promise<void> => {
|
||||
const { updateComfyUI, rebootComfyUI, error } = useComfyManagerService()
|
||||
|
||||
toast.add({
|
||||
severity: 'info',
|
||||
summary: t('helpCenter.updateComfyUIStarted'),
|
||||
detail: t('helpCenter.updateComfyUIStartedDetail'),
|
||||
life: 3000
|
||||
})
|
||||
|
||||
try {
|
||||
const result = await updateComfyUI({ is_stable: true })
|
||||
|
||||
if (result === null || error.value) {
|
||||
toast.add({
|
||||
severity: 'error',
|
||||
summary: t('g.error'),
|
||||
detail: error.value || t('helpCenter.updateComfyUIFailed'),
|
||||
life: 5000
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
toast.add({
|
||||
severity: 'success',
|
||||
summary: t('helpCenter.updateComfyUISuccess'),
|
||||
detail: t('helpCenter.updateComfyUISuccessDetail'),
|
||||
life: 3000
|
||||
})
|
||||
|
||||
await rebootComfyUI()
|
||||
} catch (err) {
|
||||
toast.add({
|
||||
severity: 'error',
|
||||
summary: t('g.error'),
|
||||
detail: err instanceof Error ? err.message : t('g.unknownError'),
|
||||
life: 5000
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const onReleaseClick = (release: ReleaseNote): void => {
|
||||
trackResourceClick('release_notes', true)
|
||||
void releaseStore.handleShowChangelog(release.version)
|
||||
|
||||
@@ -775,7 +775,13 @@
|
||||
"updateAvailable": "Update",
|
||||
"desktopUserGuide": "Desktop User Guide",
|
||||
"openDevTools": "Open Dev Tools",
|
||||
"reinstall": "Re-Install"
|
||||
"reinstall": "Re-Install",
|
||||
"updateComfyUI": "Update ComfyUI",
|
||||
"updateComfyUIStarted": "Update Started",
|
||||
"updateComfyUIStartedDetail": "ComfyUI update has been queued. Please wait...",
|
||||
"updateComfyUISuccess": "Update Complete",
|
||||
"updateComfyUISuccessDetail": "ComfyUI has been updated. Rebooting...",
|
||||
"updateComfyUIFailed": "Failed to update ComfyUI. Please try again."
|
||||
},
|
||||
"releaseToast": {
|
||||
"newVersionAvailable": "New update is out!",
|
||||
|
||||
@@ -12,6 +12,7 @@ type ManagerQueueStatus = components['schemas']['QueueStatus']
|
||||
type InstallPackParams = components['schemas']['InstallPackParams']
|
||||
type InstalledPacksResponse = components['schemas']['InstalledPacksResponse']
|
||||
type UpdateAllPacksParams = components['schemas']['UpdateAllPacksParams']
|
||||
type UpdateComfyUIParams = components['schemas']['UpdateComfyUIParams']
|
||||
type ManagerTaskHistory = components['schemas']['HistoryResponse']
|
||||
type QueueTaskItem = components['schemas']['QueueTaskItem']
|
||||
|
||||
@@ -26,6 +27,7 @@ enum ManagerRoute {
|
||||
RESET_QUEUE = 'manager/queue/reset',
|
||||
QUEUE_STATUS = 'manager/queue/status',
|
||||
UPDATE_ALL = 'manager/queue/update_all',
|
||||
UPDATE_COMFYUI = 'manager/queue/update_comfyui',
|
||||
LIST_INSTALLED = 'customnode/installed',
|
||||
GET_NODES = 'customnode/getmappings',
|
||||
IMPORT_FAIL_INFO = 'customnode/import_fail_info',
|
||||
@@ -271,6 +273,33 @@ export const useComfyManagerService = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const updateComfyUI = async (
|
||||
params: UpdateComfyUIParams = { is_stable: true },
|
||||
ui_id?: string,
|
||||
signal?: AbortSignal
|
||||
) => {
|
||||
const errorContext = 'Updating ComfyUI'
|
||||
const routeSpecificErrors = {
|
||||
400: 'Bad Request: Missing required parameters',
|
||||
403: 'Forbidden: To use this action, a security_level of `middle or below` is required'
|
||||
}
|
||||
|
||||
const queryParams = {
|
||||
client_id: api.clientId ?? api.initialClientId ?? 'unknown',
|
||||
ui_id: ui_id || uuidv4(),
|
||||
...params
|
||||
}
|
||||
|
||||
return executeRequest<null>(
|
||||
() =>
|
||||
managerApiClient.get(ManagerRoute.UPDATE_COMFYUI, {
|
||||
params: queryParams,
|
||||
signal
|
||||
}),
|
||||
{ errorContext, routeSpecificErrors, isQueueOperation: true }
|
||||
)
|
||||
}
|
||||
|
||||
const rebootComfyUI = async (signal?: AbortSignal) => {
|
||||
const errorContext = 'Rebooting ComfyUI'
|
||||
const routeSpecificErrors = {
|
||||
@@ -335,6 +364,7 @@ export const useComfyManagerService = () => {
|
||||
updateAllPacks,
|
||||
|
||||
// System operations
|
||||
updateComfyUI,
|
||||
rebootComfyUI,
|
||||
isLegacyManagerUI
|
||||
}
|
||||
|
||||
@@ -95,6 +95,7 @@ describe('useComfyManagerStore', () => {
|
||||
disablePack: vi.fn().mockResolvedValue(null),
|
||||
updatePack: vi.fn().mockResolvedValue(null),
|
||||
updateAllPacks: vi.fn().mockResolvedValue(null),
|
||||
updateComfyUI: vi.fn().mockResolvedValue(null),
|
||||
rebootComfyUI: vi.fn().mockResolvedValue(null),
|
||||
isLegacyManagerUI: vi.fn().mockResolvedValue(false)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user