Implement workflow progress panel (#6092)

Adds a workflow progress panel component underneath the
`actionbar-container`.

I suggest starting a review at the extraneous changes that were needed.
Including but not limited to:

- `get createTime()` in queueStore
- `promptIdToWorkflowId`, `initializingPromptIds`, and
`nodeProgressStatesByPrompt` in executionStore
- `create_time` handling in v2ToV1Adapter
- `pointer-events-auto` on ComfyActionbar.vue

The rest of the changes should be contained under
`QueueProgressOverlay.vue`, and has less of a blast radius in case
something goes wrong.

---------

Co-authored-by: pythongosssss <125205205+pythongosssss@users.noreply.github.com>
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: Jin Yi <jin12cc@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: Johnpaul Chiwetelu <49923152+Myestery@users.noreply.github.com>
Co-authored-by: Christian Byrne <cbyrne@comfy.org>
Co-authored-by: Comfy Org PR Bot <snomiao+comfy-pr@gmail.com>
Co-authored-by: christian-byrne <72887196+christian-byrne@users.noreply.github.com>
This commit is contained in:
Benjamin Lu
2025-11-18 22:43:49 -08:00
committed by GitHub
parent 92968f3f9b
commit e42715086e
76 changed files with 7117 additions and 39 deletions

View File

@@ -0,0 +1,119 @@
<template>
<div class="flex flex-col gap-3 p-2">
<div class="flex flex-col gap-1">
<div
class="relative h-2 w-full overflow-hidden rounded-full border border-interface-stroke bg-interface-panel-surface"
>
<div
class="absolute inset-0 h-full rounded-full transition-[width]"
:style="totalProgressStyle"
/>
<div
class="absolute inset-0 h-full rounded-full transition-[width]"
:style="currentNodeProgressStyle"
/>
</div>
<div class="flex items-start justify-end gap-4 text-[12px] leading-none">
<div class="flex items-center gap-1 text-text-primary opacity-90">
<i18n-t keypath="sideToolbar.queueProgressOverlay.total">
<template #percent>
<span class="font-bold">{{ totalPercentFormatted }}</span>
</template>
</i18n-t>
</div>
<div class="flex items-center gap-1 text-text-secondary">
<span>{{ t('sideToolbar.queueProgressOverlay.currentNode') }}</span>
<span class="inline-block max-w-[10rem] truncate">{{
currentNodeName
}}</span>
<span class="flex items-center gap-1">
<span>{{ currentNodePercentFormatted }}</span>
</span>
</div>
</div>
</div>
<div :class="bottomRowClass">
<div class="flex items-center gap-4 text-[12px] text-text-primary">
<div class="flex items-center gap-2">
<span class="opacity-90">
<span class="font-bold">{{ runningCount }}</span>
<span class="ml-1">{{
t('sideToolbar.queueProgressOverlay.running')
}}</span>
</span>
<button
v-if="runningCount > 0"
v-tooltip.top="cancelJobTooltip"
class="inline-flex size-6 cursor-pointer items-center justify-center rounded border-0 bg-secondary-background p-0 transition-colors hover:bg-destructive-background"
:aria-label="t('sideToolbar.queueProgressOverlay.interruptAll')"
@click="$emit('interruptAll')"
>
<i
class="icon-[lucide--x] block size-4 leading-none text-text-primary"
/>
</button>
</div>
<div class="flex items-center gap-2">
<span class="opacity-90">
<span class="font-bold">{{ queuedCount }}</span>
<span class="ml-1">{{
t('sideToolbar.queueProgressOverlay.queuedSuffix')
}}</span>
</span>
<button
v-if="queuedCount > 0"
v-tooltip.top="clearQueueTooltip"
class="inline-flex size-6 cursor-pointer items-center justify-center rounded border-0 bg-secondary-background p-0 transition-colors hover:bg-destructive-background"
:aria-label="t('sideToolbar.queueProgressOverlay.clearQueued')"
@click="$emit('clearQueued')"
>
<i
class="icon-[lucide--list-x] block size-4 leading-none text-text-primary"
/>
</button>
</div>
</div>
<button
class="inline-flex h-6 min-w-[120px] flex-1 cursor-pointer items-center justify-center rounded border-0 bg-secondary-background px-2 py-0 text-[12px] text-text-primary hover:bg-secondary-background-hover hover:opacity-90"
@click="$emit('viewAllJobs')"
>
{{ t('sideToolbar.queueProgressOverlay.viewAllJobs') }}
</button>
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { buildTooltipConfig } from '@/composables/useTooltipConfig'
defineProps<{
totalProgressStyle: Record<string, string>
currentNodeProgressStyle: Record<string, string>
totalPercentFormatted: string
currentNodePercentFormatted: string
currentNodeName: string
runningCount: number
queuedCount: number
bottomRowClass: string
}>()
defineEmits<{
(e: 'interruptAll'): void
(e: 'clearQueued'): void
(e: 'viewAllJobs'): void
}>()
const { t } = useI18n()
const cancelJobTooltip = computed(() =>
buildTooltipConfig(t('sideToolbar.queueProgressOverlay.cancelJobTooltip'))
)
const clearQueueTooltip = computed(() =>
buildTooltipConfig(t('sideToolbar.queueProgressOverlay.clearQueueTooltip'))
)
</script>