mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-13 11:11:00 +00:00
Compare commits
2 Commits
dev/remote
...
fix/clear-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d00db2143 | ||
|
|
6e9c6c6f2e |
@@ -200,7 +200,13 @@ const onCancelItem = wrapWithErrorHandlingAsync(async (item: JobListItem) => {
|
|||||||
|
|
||||||
if (item.state === 'running' || item.state === 'initialization') {
|
if (item.state === 'running' || item.state === 'initialization') {
|
||||||
// Running/initializing jobs: interrupt execution
|
// 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()
|
await queueStore.update()
|
||||||
} else if (item.state === 'pending') {
|
} else if (item.state === 'pending') {
|
||||||
// Pending jobs: remove from queue
|
// Pending jobs: remove from queue
|
||||||
@@ -268,7 +274,15 @@ const inspectJobAsset = wrapWithErrorHandlingAsync(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const cancelQueuedWorkflows = wrapWithErrorHandlingAsync(async () => {
|
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')
|
await commandStore.execute('Comfy.ClearPendingTasks')
|
||||||
|
|
||||||
|
// Clear initialization state for removed prompts
|
||||||
|
executionStore.clearInitializationByPromptIds(pendingPromptIds)
|
||||||
})
|
})
|
||||||
|
|
||||||
const interruptAll = wrapWithErrorHandlingAsync(async () => {
|
const interruptAll = wrapWithErrorHandlingAsync(async () => {
|
||||||
@@ -284,10 +298,14 @@ const interruptAll = wrapWithErrorHandlingAsync(async () => {
|
|||||||
// on cloud to ensure we cancel the workflow the user clicked.
|
// on cloud to ensure we cancel the workflow the user clicked.
|
||||||
if (isCloud) {
|
if (isCloud) {
|
||||||
await Promise.all(promptIds.map((id) => api.deleteItem('queue', id)))
|
await Promise.all(promptIds.map((id) => api.deleteItem('queue', id)))
|
||||||
|
executionStore.clearInitializationByPromptIds(promptIds)
|
||||||
|
await queueStore.update()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all(promptIds.map((id) => api.interrupt(id)))
|
await Promise.all(promptIds.map((id) => api.interrupt(id)))
|
||||||
|
executionStore.clearInitializationByPromptIds(promptIds)
|
||||||
|
await queueStore.update()
|
||||||
})
|
})
|
||||||
|
|
||||||
const showClearHistoryDialog = () => {
|
const showClearHistoryDialog = () => {
|
||||||
|
|||||||
@@ -244,6 +244,7 @@ import { useSettingStore } from '@/platform/settings/settingStore'
|
|||||||
import { getJobDetail } from '@/services/jobOutputCache'
|
import { getJobDetail } from '@/services/jobOutputCache'
|
||||||
import { useCommandStore } from '@/stores/commandStore'
|
import { useCommandStore } from '@/stores/commandStore'
|
||||||
import { useDialogStore } from '@/stores/dialogStore'
|
import { useDialogStore } from '@/stores/dialogStore'
|
||||||
|
import { useExecutionStore } from '@/stores/executionStore'
|
||||||
import { ResultItemImpl, useQueueStore } from '@/stores/queueStore'
|
import { ResultItemImpl, useQueueStore } from '@/stores/queueStore'
|
||||||
import { formatDuration, getMediaTypeFromFilename } from '@/utils/formatUtil'
|
import { formatDuration, getMediaTypeFromFilename } from '@/utils/formatUtil'
|
||||||
import { cn } from '@/utils/tailwindUtil'
|
import { cn } from '@/utils/tailwindUtil'
|
||||||
@@ -257,6 +258,7 @@ interface JobOutputItem {
|
|||||||
const { t, n } = useI18n()
|
const { t, n } = useI18n()
|
||||||
const commandStore = useCommandStore()
|
const commandStore = useCommandStore()
|
||||||
const queueStore = useQueueStore()
|
const queueStore = useQueueStore()
|
||||||
|
const executionStore = useExecutionStore()
|
||||||
const settingStore = useSettingStore()
|
const settingStore = useSettingStore()
|
||||||
|
|
||||||
const activeTab = ref<'input' | 'output'>('output')
|
const activeTab = ref<'input' | 'output'>('output')
|
||||||
@@ -511,7 +513,13 @@ const handleBulkDelete = async (assets: AssetItem[]) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleClearQueue = async () => {
|
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')
|
await commandStore.execute('Comfy.ClearPendingTasks')
|
||||||
|
|
||||||
|
executionStore.clearInitializationByPromptIds(pendingPromptIds)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBulkAddToWorkflow = async (assets: AssetItem[]) => {
|
const handleBulkAddToWorkflow = async (assets: AssetItem[]) => {
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ import type { Ref } from 'vue'
|
|||||||
import type { JobListItem } from '@/composables/queue/useJobList'
|
import type { JobListItem } from '@/composables/queue/useJobList'
|
||||||
import type { MenuEntry } from '@/composables/queue/useJobMenu'
|
import type { MenuEntry } from '@/composables/queue/useJobMenu'
|
||||||
|
|
||||||
|
vi.mock('@/platform/distribution/types', () => ({
|
||||||
|
isCloud: false
|
||||||
|
}))
|
||||||
|
|
||||||
const downloadFileMock = vi.fn()
|
const downloadFileMock = vi.fn()
|
||||||
vi.mock('@/base/common/downloadUtil', () => ({
|
vi.mock('@/base/common/downloadUtil', () => ({
|
||||||
downloadFile: (...args: any[]) => downloadFileMock(...args)
|
downloadFile: (...args: any[]) => downloadFileMock(...args)
|
||||||
@@ -55,7 +59,8 @@ const workflowStoreMock = {
|
|||||||
createTemporary: vi.fn()
|
createTemporary: vi.fn()
|
||||||
}
|
}
|
||||||
vi.mock('@/platform/workflow/management/stores/workflowStore', () => ({
|
vi.mock('@/platform/workflow/management/stores/workflowStore', () => ({
|
||||||
useWorkflowStore: () => workflowStoreMock
|
useWorkflowStore: () => workflowStoreMock,
|
||||||
|
ComfyWorkflow: class {}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const interruptMock = vi.fn()
|
const interruptMock = vi.fn()
|
||||||
@@ -104,6 +109,13 @@ vi.mock('@/stores/queueStore', () => ({
|
|||||||
useQueueStore: () => queueStoreMock
|
useQueueStore: () => queueStoreMock
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
const executionStoreMock = {
|
||||||
|
clearInitializationByPromptId: vi.fn()
|
||||||
|
}
|
||||||
|
vi.mock('@/stores/executionStore', () => ({
|
||||||
|
useExecutionStore: () => executionStoreMock
|
||||||
|
}))
|
||||||
|
|
||||||
const getJobWorkflowMock = vi.fn()
|
const getJobWorkflowMock = vi.fn()
|
||||||
vi.mock('@/services/jobOutputCache', () => ({
|
vi.mock('@/services/jobOutputCache', () => ({
|
||||||
getJobWorkflow: (...args: any[]) => getJobWorkflowMock(...args)
|
getJobWorkflow: (...args: any[]) => getJobWorkflowMock(...args)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
|
|||||||
import { st, t } from '@/i18n'
|
import { st, t } from '@/i18n'
|
||||||
import { mapTaskOutputToAssetItem } from '@/platform/assets/composables/media/assetMappers'
|
import { mapTaskOutputToAssetItem } from '@/platform/assets/composables/media/assetMappers'
|
||||||
import { useMediaAssetActions } from '@/platform/assets/composables/useMediaAssetActions'
|
import { useMediaAssetActions } from '@/platform/assets/composables/useMediaAssetActions'
|
||||||
|
import { isCloud } from '@/platform/distribution/types'
|
||||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||||
import { useWorkflowService } from '@/platform/workflow/core/services/workflowService'
|
import { useWorkflowService } from '@/platform/workflow/core/services/workflowService'
|
||||||
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
|
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
|
||||||
@@ -15,6 +16,7 @@ import { downloadBlob } from '@/scripts/utils'
|
|||||||
import { useDialogService } from '@/services/dialogService'
|
import { useDialogService } from '@/services/dialogService'
|
||||||
import { getJobWorkflow } from '@/services/jobOutputCache'
|
import { getJobWorkflow } from '@/services/jobOutputCache'
|
||||||
import { useLitegraphService } from '@/services/litegraphService'
|
import { useLitegraphService } from '@/services/litegraphService'
|
||||||
|
import { useExecutionStore } from '@/stores/executionStore'
|
||||||
import { useNodeDefStore } from '@/stores/nodeDefStore'
|
import { useNodeDefStore } from '@/stores/nodeDefStore'
|
||||||
import { useQueueStore } from '@/stores/queueStore'
|
import { useQueueStore } from '@/stores/queueStore'
|
||||||
import type { ResultItemImpl, TaskItemImpl } from '@/stores/queueStore'
|
import type { ResultItemImpl, TaskItemImpl } from '@/stores/queueStore'
|
||||||
@@ -44,6 +46,7 @@ export function useJobMenu(
|
|||||||
const workflowStore = useWorkflowStore()
|
const workflowStore = useWorkflowStore()
|
||||||
const workflowService = useWorkflowService()
|
const workflowService = useWorkflowService()
|
||||||
const queueStore = useQueueStore()
|
const queueStore = useQueueStore()
|
||||||
|
const executionStore = useExecutionStore()
|
||||||
const { copyToClipboard } = useCopyToClipboard()
|
const { copyToClipboard } = useCopyToClipboard()
|
||||||
const litegraphService = useLitegraphService()
|
const litegraphService = useLitegraphService()
|
||||||
const nodeDefStore = useNodeDefStore()
|
const nodeDefStore = useNodeDefStore()
|
||||||
@@ -72,10 +75,15 @@ export function useJobMenu(
|
|||||||
const target = resolveItem(item)
|
const target = resolveItem(item)
|
||||||
if (!target) return
|
if (!target) return
|
||||||
if (target.state === 'running' || target.state === 'initialization') {
|
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') {
|
} else if (target.state === 'pending') {
|
||||||
await api.deleteItem('queue', target.id)
|
await api.deleteItem('queue', target.id)
|
||||||
}
|
}
|
||||||
|
executionStore.clearInitializationByPromptId(target.id)
|
||||||
await queueStore.update()
|
await queueStore.update()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -425,6 +425,18 @@ export const useExecutionStore = defineStore('execution', () => {
|
|||||||
initializingPromptIds.value = next
|
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(
|
function isPromptInitializing(
|
||||||
promptId: string | number | undefined
|
promptId: string | number | undefined
|
||||||
): boolean {
|
): boolean {
|
||||||
@@ -650,6 +662,8 @@ export const useExecutionStore = defineStore('execution', () => {
|
|||||||
runningWorkflowCount,
|
runningWorkflowCount,
|
||||||
initializingPromptIds,
|
initializingPromptIds,
|
||||||
isPromptInitializing,
|
isPromptInitializing,
|
||||||
|
clearInitializationByPromptId,
|
||||||
|
clearInitializationByPromptIds,
|
||||||
bindExecutionEvents,
|
bindExecutionEvents,
|
||||||
unbindExecutionEvents,
|
unbindExecutionEvents,
|
||||||
storePrompt,
|
storePrompt,
|
||||||
|
|||||||
Reference in New Issue
Block a user