From 6e9c6c6f2ec7c7d21088fefe7a9750ec3c68127f Mon Sep 17 00:00:00 2001 From: Jin Yi Date: Wed, 21 Jan 2026 13:13:47 +0900 Subject: [PATCH] fix: when clear queue button clicked, initialized tasks are not cleared --- src/components/queue/QueueProgressOverlay.vue | 20 ++++++++++++++++++- .../sidebar/tabs/AssetsSidebarTab.vue | 8 ++++++++ src/composables/queue/useJobMenu.ts | 10 +++++++++- src/stores/executionStore.ts | 14 +++++++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/components/queue/QueueProgressOverlay.vue b/src/components/queue/QueueProgressOverlay.vue index d6b3edcd8..626709593 100644 --- a/src/components/queue/QueueProgressOverlay.vue +++ b/src/components/queue/QueueProgressOverlay.vue @@ -200,7 +200,13 @@ const onCancelItem = wrapWithErrorHandlingAsync(async (item: JobListItem) => { if (item.state === 'running' || item.state === 'initialization') { // Running/initializing jobs: interrupt execution - await api.interrupt(promptId) + // Cloud backend uses deleteItem, local uses interrupt + if (isCloud) { + await api.deleteItem('queue', promptId) + } else { + await api.interrupt(promptId) + } + executionStore.clearInitializationByPromptId(promptId) await queueStore.update() } else if (item.state === 'pending') { // Pending jobs: remove from queue @@ -268,7 +274,15 @@ const inspectJobAsset = wrapWithErrorHandlingAsync( ) const cancelQueuedWorkflows = wrapWithErrorHandlingAsync(async () => { + // Capture pending promptIds before clearing + const pendingPromptIds = queueStore.pendingTasks + .map((task) => task.promptId) + .filter((id): id is string => typeof id === 'string' && id.length > 0) + await commandStore.execute('Comfy.ClearPendingTasks') + + // Clear initialization state for removed prompts + executionStore.clearInitializationByPromptIds(pendingPromptIds) }) const interruptAll = wrapWithErrorHandlingAsync(async () => { @@ -284,10 +298,14 @@ const interruptAll = wrapWithErrorHandlingAsync(async () => { // on cloud to ensure we cancel the workflow the user clicked. if (isCloud) { await Promise.all(promptIds.map((id) => api.deleteItem('queue', id))) + executionStore.clearInitializationByPromptIds(promptIds) + await queueStore.update() return } await Promise.all(promptIds.map((id) => api.interrupt(id))) + executionStore.clearInitializationByPromptIds(promptIds) + await queueStore.update() }) const showClearHistoryDialog = () => { diff --git a/src/components/sidebar/tabs/AssetsSidebarTab.vue b/src/components/sidebar/tabs/AssetsSidebarTab.vue index d481b0b9a..8db99e96f 100644 --- a/src/components/sidebar/tabs/AssetsSidebarTab.vue +++ b/src/components/sidebar/tabs/AssetsSidebarTab.vue @@ -244,6 +244,7 @@ import { useSettingStore } from '@/platform/settings/settingStore' import { getJobDetail } from '@/services/jobOutputCache' import { useCommandStore } from '@/stores/commandStore' import { useDialogStore } from '@/stores/dialogStore' +import { useExecutionStore } from '@/stores/executionStore' import { ResultItemImpl, useQueueStore } from '@/stores/queueStore' import { formatDuration, getMediaTypeFromFilename } from '@/utils/formatUtil' import { cn } from '@/utils/tailwindUtil' @@ -257,6 +258,7 @@ interface JobOutputItem { const { t, n } = useI18n() const commandStore = useCommandStore() const queueStore = useQueueStore() +const executionStore = useExecutionStore() const settingStore = useSettingStore() const activeTab = ref<'input' | 'output'>('output') @@ -511,7 +513,13 @@ const handleBulkDelete = async (assets: AssetItem[]) => { } const handleClearQueue = async () => { + const pendingPromptIds = queueStore.pendingTasks + .map((task) => task.promptId) + .filter((id): id is string => typeof id === 'string' && id.length > 0) + await commandStore.execute('Comfy.ClearPendingTasks') + + executionStore.clearInitializationByPromptIds(pendingPromptIds) } const handleBulkAddToWorkflow = async (assets: AssetItem[]) => { diff --git a/src/composables/queue/useJobMenu.ts b/src/composables/queue/useJobMenu.ts index b4208304e..b50a24846 100644 --- a/src/composables/queue/useJobMenu.ts +++ b/src/composables/queue/useJobMenu.ts @@ -6,6 +6,7 @@ import { useCopyToClipboard } from '@/composables/useCopyToClipboard' import { st, t } from '@/i18n' import { mapTaskOutputToAssetItem } from '@/platform/assets/composables/media/assetMappers' import { useMediaAssetActions } from '@/platform/assets/composables/useMediaAssetActions' +import { isCloud } from '@/platform/distribution/types' import { useSettingStore } from '@/platform/settings/settingStore' import { useWorkflowService } from '@/platform/workflow/core/services/workflowService' import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore' @@ -15,6 +16,7 @@ import { downloadBlob } from '@/scripts/utils' import { useDialogService } from '@/services/dialogService' import { getJobWorkflow } from '@/services/jobOutputCache' import { useLitegraphService } from '@/services/litegraphService' +import { useExecutionStore } from '@/stores/executionStore' import { useNodeDefStore } from '@/stores/nodeDefStore' import { useQueueStore } from '@/stores/queueStore' import type { ResultItemImpl, TaskItemImpl } from '@/stores/queueStore' @@ -44,6 +46,7 @@ export function useJobMenu( const workflowStore = useWorkflowStore() const workflowService = useWorkflowService() const queueStore = useQueueStore() + const executionStore = useExecutionStore() const { copyToClipboard } = useCopyToClipboard() const litegraphService = useLitegraphService() const nodeDefStore = useNodeDefStore() @@ -72,10 +75,15 @@ export function useJobMenu( const target = resolveItem(item) if (!target) return if (target.state === 'running' || target.state === 'initialization') { - await api.interrupt(target.id) + if (isCloud) { + await api.deleteItem('queue', target.id) + } else { + await api.interrupt(target.id) + } } else if (target.state === 'pending') { await api.deleteItem('queue', target.id) } + executionStore.clearInitializationByPromptId(target.id) await queueStore.update() } diff --git a/src/stores/executionStore.ts b/src/stores/executionStore.ts index 429adb807..dda732af5 100644 --- a/src/stores/executionStore.ts +++ b/src/stores/executionStore.ts @@ -425,6 +425,18 @@ export const useExecutionStore = defineStore('execution', () => { initializingPromptIds.value = next } + function clearInitializationByPromptIds(promptIds: string[]) { + if (!promptIds.length) return + const current = initializingPromptIds.value + const toRemove = promptIds.filter((id) => current.has(id)) + if (!toRemove.length) return + const next = new Set(current) + for (const id of toRemove) { + next.delete(id) + } + initializingPromptIds.value = next + } + function isPromptInitializing( promptId: string | number | undefined ): boolean { @@ -650,6 +662,8 @@ export const useExecutionStore = defineStore('execution', () => { runningWorkflowCount, initializingPromptIds, isPromptInitializing, + clearInitializationByPromptId, + clearInitializationByPromptIds, bindExecutionEvents, unbindExecutionEvents, storePrompt,