mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-30 19:21:54 +00:00
* Revert "Filter cached/canceled results (#1586)"
This reverts commit 6fbf1248f4.
* nit
This commit is contained in:
@@ -1,18 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<SidebarTabTemplate :title="$t('sideToolbar.queue')">
|
<SidebarTabTemplate :title="$t('sideToolbar.queue')">
|
||||||
<template #tool-buttons>
|
<template #tool-buttons>
|
||||||
<Popover ref="outputFilterPopup">
|
|
||||||
<OutputFilters />
|
|
||||||
</Popover>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
icon="pi pi-filter"
|
|
||||||
text
|
|
||||||
severity="secondary"
|
|
||||||
@click="outputFilterPopup.toggle($event)"
|
|
||||||
v-tooltip="$t(`sideToolbar.queueTab.filter`)"
|
|
||||||
:class="{ 'text-yellow-500': anyFilter }"
|
|
||||||
/>
|
|
||||||
<Button
|
<Button
|
||||||
:icon="
|
:icon="
|
||||||
imageFit === 'cover'
|
imageFit === 'cover'
|
||||||
@@ -111,7 +99,6 @@ import Button from 'primevue/button'
|
|||||||
import ConfirmPopup from 'primevue/confirmpopup'
|
import ConfirmPopup from 'primevue/confirmpopup'
|
||||||
import ContextMenu from 'primevue/contextmenu'
|
import ContextMenu from 'primevue/contextmenu'
|
||||||
import type { MenuItem } from 'primevue/menuitem'
|
import type { MenuItem } from 'primevue/menuitem'
|
||||||
import Popover from 'primevue/popover'
|
|
||||||
import ProgressSpinner from 'primevue/progressspinner'
|
import ProgressSpinner from 'primevue/progressspinner'
|
||||||
import TaskItem from './queue/TaskItem.vue'
|
import TaskItem from './queue/TaskItem.vue'
|
||||||
import ResultGallery from './queue/ResultGallery.vue'
|
import ResultGallery from './queue/ResultGallery.vue'
|
||||||
@@ -124,9 +111,7 @@ import { useSettingStore } from '@/stores/settingStore'
|
|||||||
import { useCommandStore } from '@/stores/commandStore'
|
import { useCommandStore } from '@/stores/commandStore'
|
||||||
import { app } from '@/scripts/app'
|
import { app } from '@/scripts/app'
|
||||||
|
|
||||||
const SETTING_FIT = 'Comfy.Queue.ImageFit'
|
const IMAGE_FIT = 'Comfy.Queue.ImageFit'
|
||||||
const SETTING_FLAT = 'Comfy.Queue.ShowFlatList'
|
|
||||||
const SETTING_FILTER = 'Comfy.Queue.Filter'
|
|
||||||
const confirm = useConfirm()
|
const confirm = useConfirm()
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
const queueStore = useQueueStore()
|
const queueStore = useQueueStore()
|
||||||
@@ -135,7 +120,7 @@ const commandStore = useCommandStore()
|
|||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
// Expanded view: show all outputs in a flat list.
|
// Expanded view: show all outputs in a flat list.
|
||||||
const isExpanded = computed<boolean>(() => settingStore.get(SETTING_FLAT))
|
const isExpanded = ref(false)
|
||||||
const visibleTasks = ref<TaskItemImpl[]>([])
|
const visibleTasks = ref<TaskItemImpl[]>([])
|
||||||
const scrollContainer = ref<HTMLElement | null>(null)
|
const scrollContainer = ref<HTMLElement | null>(null)
|
||||||
const loadMoreTrigger = ref<HTMLElement | null>(null)
|
const loadMoreTrigger = ref<HTMLElement | null>(null)
|
||||||
@@ -143,23 +128,7 @@ const galleryActiveIndex = ref(-1)
|
|||||||
// Folder view: only show outputs from a single selected task.
|
// Folder view: only show outputs from a single selected task.
|
||||||
const folderTask = ref<TaskItemImpl | null>(null)
|
const folderTask = ref<TaskItemImpl | null>(null)
|
||||||
const isInFolderView = computed(() => folderTask.value !== null)
|
const isInFolderView = computed(() => folderTask.value !== null)
|
||||||
const imageFit = computed<string>(() => settingStore.get(SETTING_FIT))
|
const imageFit = computed<string>(() => settingStore.get(IMAGE_FIT))
|
||||||
const hideCached = computed<boolean>(
|
|
||||||
() => settingStore.get(SETTING_FILTER)?.hideCached
|
|
||||||
)
|
|
||||||
const hideCanceled = computed<boolean>(
|
|
||||||
() => settingStore.get(SETTING_FILTER)?.hideCanceled
|
|
||||||
)
|
|
||||||
const anyFilter = computed(() => hideCanceled.value || hideCached.value)
|
|
||||||
|
|
||||||
watch(hideCached, () => {
|
|
||||||
updateVisibleTasks()
|
|
||||||
})
|
|
||||||
watch(hideCanceled, () => {
|
|
||||||
updateVisibleTasks()
|
|
||||||
})
|
|
||||||
|
|
||||||
const outputFilterPopup = ref(null)
|
|
||||||
|
|
||||||
const ITEMS_PER_PAGE = 8
|
const ITEMS_PER_PAGE = 8
|
||||||
const SCROLL_THRESHOLD = 100 // pixels from bottom to trigger load
|
const SCROLL_THRESHOLD = 100 // pixels from bottom to trigger load
|
||||||
@@ -180,31 +149,9 @@ const allGalleryItems = computed(() =>
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
const filterTasks = (tasks: TaskItemImpl[]) =>
|
|
||||||
tasks
|
|
||||||
.filter((t) => {
|
|
||||||
if (
|
|
||||||
hideCanceled.value &&
|
|
||||||
t.status?.messages?.at(-1)?.[0] === 'execution_interrupted'
|
|
||||||
) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
hideCached.value &&
|
|
||||||
t.flatOutputs?.length &&
|
|
||||||
t.flatOutputs.every((o) => o.cached)
|
|
||||||
) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
.slice(0, ITEMS_PER_PAGE)
|
|
||||||
|
|
||||||
const loadMoreItems = () => {
|
const loadMoreItems = () => {
|
||||||
const currentLength = visibleTasks.value.length
|
const currentLength = visibleTasks.value.length
|
||||||
const newTasks = filterTasks(allTasks.value).slice(
|
const newTasks = allTasks.value.slice(
|
||||||
currentLength,
|
currentLength,
|
||||||
currentLength + ITEMS_PER_PAGE
|
currentLength + ITEMS_PER_PAGE
|
||||||
)
|
)
|
||||||
@@ -239,11 +186,11 @@ useResizeObserver(scrollContainer, () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const updateVisibleTasks = () => {
|
const updateVisibleTasks = () => {
|
||||||
visibleTasks.value = filterTasks(allTasks.value)
|
visibleTasks.value = allTasks.value.slice(0, ITEMS_PER_PAGE)
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggleExpanded = () => {
|
const toggleExpanded = () => {
|
||||||
settingStore.set(SETTING_FLAT, !isExpanded.value)
|
isExpanded.value = !isExpanded.value
|
||||||
updateVisibleTasks()
|
updateVisibleTasks()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,10 +291,7 @@ const exitFolderView = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const toggleImageFit = () => {
|
const toggleImageFit = () => {
|
||||||
settingStore.set(
|
settingStore.set(IMAGE_FIT, imageFit.value === 'cover' ? 'contain' : 'cover')
|
||||||
SETTING_FIT,
|
|
||||||
imageFit.value === 'cover' ? 'contain' : 'cover'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="flex flex-col gap-2">
|
|
||||||
<label class="flex items-center gap-2">
|
|
||||||
{{ $t('sideToolbar.queueTab.filters.hideCached') }}
|
|
||||||
<ToggleSwitch v-model="hideCached" />
|
|
||||||
</label>
|
|
||||||
<label class="flex items-center gap-2">
|
|
||||||
{{ $t('sideToolbar.queueTab.filters.hideCanceled') }}
|
|
||||||
<ToggleSwitch v-model="hideCanceled" />
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { computed } from 'vue'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import ToggleSwitch from 'primevue/toggleswitch'
|
|
||||||
import { useSettingStore } from '@/stores/settingStore'
|
|
||||||
const SETTING_FILTER = 'Comfy.Queue.Filter'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
const settingStore = useSettingStore()
|
|
||||||
const filter = settingStore.get(SETTING_FILTER) ?? {}
|
|
||||||
|
|
||||||
const createCompute = (k: string) =>
|
|
||||||
computed({
|
|
||||||
get() {
|
|
||||||
return filter[k]
|
|
||||||
},
|
|
||||||
set(value) {
|
|
||||||
filter[k] = value
|
|
||||||
settingStore.set(SETTING_FILTER, filter)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const hideCached = createCompute('hideCached')
|
|
||||||
const hideCanceled = createCompute('hideCanceled')
|
|
||||||
</script>
|
|
||||||
@@ -31,20 +31,16 @@
|
|||||||
|
|
||||||
<div class="task-item-details">
|
<div class="task-item-details">
|
||||||
<div class="tag-wrapper status-tag-group">
|
<div class="tag-wrapper status-tag-group">
|
||||||
<Tag v-if="isFlatTask && task.isHistory && node" class="node-name-tag">
|
<Tag v-if="isFlatTask && task.isHistory" class="node-name-tag">
|
||||||
<Button
|
<Button
|
||||||
class="task-node-link"
|
class="task-node-link"
|
||||||
:label="`${node.type} (#${node.id})`"
|
:label="`${node?.type} (#${node?.id})`"
|
||||||
link
|
link
|
||||||
size="small"
|
size="small"
|
||||||
@click="app.goToNode(node?.id)"
|
@click="app.goToNode(node?.id)"
|
||||||
/>
|
/>
|
||||||
</Tag>
|
</Tag>
|
||||||
<Tag
|
<Tag :severity="taskTagSeverity(task.displayStatus)">
|
||||||
:severity="taskTagSeverity(task.displayStatus)"
|
|
||||||
class="task-duration relative"
|
|
||||||
>
|
|
||||||
<i v-if="isCachedResult" class="pi pi-server task-cached-icon"></i>
|
|
||||||
<span v-html="taskStatusText(task.displayStatus)"></span>
|
<span v-html="taskStatusText(task.displayStatus)"></span>
|
||||||
<span v-if="task.isHistory" class="task-time">
|
<span v-if="task.isHistory" class="task-time">
|
||||||
{{ formatTime(task.executionTimeInSeconds) }}
|
{{ formatTime(task.executionTimeInSeconds) }}
|
||||||
@@ -94,7 +90,6 @@ const node: ComfyNode | null =
|
|||||||
) ?? null
|
) ?? null
|
||||||
: null
|
: null
|
||||||
const progressPreviewBlobUrl = ref('')
|
const progressPreviewBlobUrl = ref('')
|
||||||
const isCachedResult = props.isFlatTask && coverResult?.cached
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(
|
(
|
||||||
@@ -147,7 +142,7 @@ const taskStatusText = (status: TaskItemDisplayStatus) => {
|
|||||||
case TaskItemDisplayStatus.Running:
|
case TaskItemDisplayStatus.Running:
|
||||||
return '<i class="pi pi-spin pi-spinner" style="font-weight: bold"></i> Running'
|
return '<i class="pi pi-spin pi-spinner" style="font-weight: bold"></i> Running'
|
||||||
case TaskItemDisplayStatus.Completed:
|
case TaskItemDisplayStatus.Completed:
|
||||||
return `<i class="pi pi-check${isCachedResult ? ' cached' : ''}" style="font-weight: bold"></i>`
|
return '<i class="pi pi-check" style="font-weight: bold"></i>'
|
||||||
case TaskItemDisplayStatus.Failed:
|
case TaskItemDisplayStatus.Failed:
|
||||||
return 'Failed'
|
return 'Failed'
|
||||||
case TaskItemDisplayStatus.Cancelled:
|
case TaskItemDisplayStatus.Cancelled:
|
||||||
@@ -231,15 +226,4 @@ are floating on top of images. */
|
|||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
object-position: center;
|
object-position: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.task-cached-icon {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.pi-check.cached) {
|
|
||||||
font-size: 12px;
|
|
||||||
position: absolute;
|
|
||||||
left: 16px;
|
|
||||||
top: 12px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -198,25 +198,6 @@ export const CORE_SETTINGS: SettingParams[] = [
|
|||||||
type: 'hidden',
|
type: 'hidden',
|
||||||
defaultValue: 'cover'
|
defaultValue: 'cover'
|
||||||
},
|
},
|
||||||
// Hidden setting used by the queue for if the results should be grouped by prompt
|
|
||||||
{
|
|
||||||
id: 'Comfy.Queue.ShowFlatList',
|
|
||||||
name: 'Queue show flat list',
|
|
||||||
type: 'hidden',
|
|
||||||
defaultValue: false
|
|
||||||
},
|
|
||||||
|
|
||||||
// Hidden setting used by the queue to filter certain results
|
|
||||||
{
|
|
||||||
id: 'Comfy.Queue.Filter',
|
|
||||||
name: 'Queue output filters',
|
|
||||||
type: 'hidden',
|
|
||||||
defaultValue: {
|
|
||||||
hideCanceled: false,
|
|
||||||
hideCached: false
|
|
||||||
},
|
|
||||||
versionAdded: '1.4.3'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'Comfy.GroupSelectedNodes.Padding',
|
id: 'Comfy.GroupSelectedNodes.Padding',
|
||||||
category: ['LiteGraph', 'Group', 'Padding'],
|
category: ['LiteGraph', 'Group', 'Padding'],
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ export class ResultItemImpl {
|
|||||||
filename: string
|
filename: string
|
||||||
subfolder: string
|
subfolder: string
|
||||||
type: string
|
type: string
|
||||||
cached: boolean
|
|
||||||
|
|
||||||
nodeId: NodeId
|
nodeId: NodeId
|
||||||
// 'audio' | 'images' | ...
|
// 'audio' | 'images' | ...
|
||||||
@@ -44,7 +43,6 @@ export class ResultItemImpl {
|
|||||||
this.filename = obj.filename ?? ''
|
this.filename = obj.filename ?? ''
|
||||||
this.subfolder = obj.subfolder ?? ''
|
this.subfolder = obj.subfolder ?? ''
|
||||||
this.type = obj.type ?? ''
|
this.type = obj.type ?? ''
|
||||||
this.cached = obj.cached
|
|
||||||
|
|
||||||
this.nodeId = obj.nodeId
|
this.nodeId = obj.nodeId
|
||||||
this.mediaType = obj.mediaType
|
this.mediaType = obj.mediaType
|
||||||
@@ -151,13 +149,6 @@ export class TaskItemImpl {
|
|||||||
if (!this.outputs) {
|
if (!this.outputs) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
const cachedEntries = new Set(
|
|
||||||
this.status?.messages?.find((message) => {
|
|
||||||
return message[0] === 'execution_cached'
|
|
||||||
})?.[1].nodes
|
|
||||||
)
|
|
||||||
|
|
||||||
return Object.entries(this.outputs).flatMap(([nodeId, nodeOutputs]) =>
|
return Object.entries(this.outputs).flatMap(([nodeId, nodeOutputs]) =>
|
||||||
Object.entries(nodeOutputs).flatMap(([mediaType, items]) =>
|
Object.entries(nodeOutputs).flatMap(([mediaType, items]) =>
|
||||||
(items as ResultItem[]).map(
|
(items as ResultItem[]).map(
|
||||||
@@ -165,8 +156,7 @@ export class TaskItemImpl {
|
|||||||
new ResultItemImpl({
|
new ResultItemImpl({
|
||||||
...item,
|
...item,
|
||||||
nodeId,
|
nodeId,
|
||||||
mediaType,
|
mediaType
|
||||||
cached: cachedEntries.has(nodeId)
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -454,11 +454,6 @@ const zNodeBadgeMode = z.enum(
|
|||||||
Object.values(NodeBadgeMode) as [string, ...string[]]
|
Object.values(NodeBadgeMode) as [string, ...string[]]
|
||||||
)
|
)
|
||||||
|
|
||||||
const zQueueFilter = z.object({
|
|
||||||
hideCached: z.boolean(),
|
|
||||||
hideCanceled: z.boolean()
|
|
||||||
})
|
|
||||||
|
|
||||||
const zSettings = z.record(z.any()).and(
|
const zSettings = z.record(z.any()).and(
|
||||||
z
|
z
|
||||||
.object({
|
.object({
|
||||||
@@ -511,8 +506,6 @@ const zSettings = z.record(z.any()).and(
|
|||||||
'Comfy.Validation.Workflows': z.boolean(),
|
'Comfy.Validation.Workflows': z.boolean(),
|
||||||
'Comfy.Workflow.SortNodeIdOnSave': z.boolean(),
|
'Comfy.Workflow.SortNodeIdOnSave': z.boolean(),
|
||||||
'Comfy.Queue.ImageFit': z.enum(['contain', 'cover']),
|
'Comfy.Queue.ImageFit': z.enum(['contain', 'cover']),
|
||||||
'Comfy.Queue.ShowFlatList': z.boolean(),
|
|
||||||
'Comfy.Queue.Filter': zQueueFilter.passthrough(),
|
|
||||||
'Comfy.Workflow.WorkflowTabsPosition': z.enum(['Sidebar', 'Topbar']),
|
'Comfy.Workflow.WorkflowTabsPosition': z.enum(['Sidebar', 'Topbar']),
|
||||||
'Comfy.Node.DoubleClickTitleToEdit': z.boolean(),
|
'Comfy.Node.DoubleClickTitleToEdit': z.boolean(),
|
||||||
'Comfy.Window.UnloadConfirmation': z.boolean(),
|
'Comfy.Window.UnloadConfirmation': z.boolean(),
|
||||||
|
|||||||
@@ -19,7 +19,10 @@ import { useI18n } from 'vue-i18n'
|
|||||||
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
||||||
import { api } from '@/scripts/api'
|
import { api } from '@/scripts/api'
|
||||||
import { StatusWsMessageStatus } from '@/types/apiTypes'
|
import { StatusWsMessageStatus } from '@/types/apiTypes'
|
||||||
import { useQueuePendingTaskCountStore } from '@/stores/queueStore'
|
import {
|
||||||
|
useQueuePendingTaskCountStore,
|
||||||
|
useQueueStore
|
||||||
|
} from '@/stores/queueStore'
|
||||||
import type { ToastMessageOptions } from 'primevue/toast'
|
import type { ToastMessageOptions } from 'primevue/toast'
|
||||||
import { useToast } from 'primevue/usetoast'
|
import { useToast } from 'primevue/usetoast'
|
||||||
import { i18n } from '@/i18n'
|
import { i18n } from '@/i18n'
|
||||||
|
|||||||
Reference in New Issue
Block a user