mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-19 22:34:15 +00:00
fix: move clear queued controls into queue header (#8920)
## Summary - Move queued-count summary and clear-queued action into the Queue Overlay header so controls remain visible while expanded content scrolls. ## What changed - `QueueOverlayExpanded.vue` - Passes `queuedCount` and `clearQueued` through to the header. - Removes duplicated summary/action content from the lower section. - `QueueOverlayHeader.vue` - Accepts new header data/actions for queued count and clear behavior. - Renders queued summary and clear button beside the title. - Adjusts layout to support persistent header actions. - Updated header unit tests to cover queued summary rendering and clear action behavior. ## Testing - Header unit tests were updated for the new behavior. - No additional test execution was requested. ## Notes - UI composition change only; queue execution semantics are unchanged. Design: https://www.figma.com/design/LVilZgHGk5RwWOkVN6yCEK/Queue-Progress-Modal?node-id=3924-38560&m=dev <img width="356" height="59" alt="Screenshot 2026-02-16 at 3 30 44 PM" src="https://github.com/user-attachments/assets/987e42bd-9e24-4e65-9158-3f96b5338199" />
This commit is contained in:
@@ -4,12 +4,14 @@
|
||||
:header-title="headerTitle"
|
||||
:show-concurrent-indicator="showConcurrentIndicator"
|
||||
:concurrent-workflow-count="concurrentWorkflowCount"
|
||||
:queued-count="queuedCount"
|
||||
@clear-history="$emit('clearHistory')"
|
||||
@clear-queued="$emit('clearQueued')"
|
||||
/>
|
||||
|
||||
<div class="flex items-center justify-between px-3">
|
||||
<div class="px-3">
|
||||
<Button
|
||||
class="grow gap-1 justify-center"
|
||||
class="w-full gap-1 justify-center"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
@click="$emit('showAssets')"
|
||||
@@ -17,26 +19,6 @@
|
||||
<i class="icon-[comfy--image-ai-edit] size-4" />
|
||||
<span>{{ t('sideToolbar.queueProgressOverlay.showAssets') }}</span>
|
||||
</Button>
|
||||
<div class="ml-4 inline-flex items-center">
|
||||
<div
|
||||
class="inline-flex h-6 items-center text-[12px] leading-none text-text-primary opacity-90"
|
||||
>
|
||||
<span class="font-bold">{{ queuedCount }}</span>
|
||||
<span class="ml-1">{{
|
||||
t('sideToolbar.queueProgressOverlay.queuedSuffix')
|
||||
}}</span>
|
||||
</div>
|
||||
<Button
|
||||
v-if="queuedCount > 0"
|
||||
class="ml-2"
|
||||
variant="destructive"
|
||||
size="icon"
|
||||
:aria-label="t('sideToolbar.queueProgressOverlay.clearQueued')"
|
||||
@click="$emit('clearQueued')"
|
||||
>
|
||||
<i class="icon-[lucide--list-x] size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<JobFiltersBar
|
||||
|
||||
@@ -40,6 +40,8 @@ const i18n = createI18n({
|
||||
sideToolbar: {
|
||||
queueProgressOverlay: {
|
||||
running: 'running',
|
||||
queuedSuffix: 'queued',
|
||||
clearQueued: 'Clear queued',
|
||||
moreOptions: 'More options',
|
||||
clearHistory: 'Clear history'
|
||||
}
|
||||
@@ -54,6 +56,7 @@ const mountHeader = (props = {}) =>
|
||||
headerTitle: 'Job queue',
|
||||
showConcurrentIndicator: true,
|
||||
concurrentWorkflowCount: 2,
|
||||
queuedCount: 3,
|
||||
...props
|
||||
},
|
||||
global: {
|
||||
@@ -80,6 +83,25 @@ describe('QueueOverlayHeader', () => {
|
||||
expect(wrapper.find('.inline-flex.items-center.gap-1').exists()).toBe(false)
|
||||
})
|
||||
|
||||
it('shows queued summary and emits clear queued', async () => {
|
||||
const wrapper = mountHeader({ queuedCount: 4 })
|
||||
|
||||
expect(wrapper.text()).toContain('4')
|
||||
expect(wrapper.text()).toContain('queued')
|
||||
|
||||
const clearQueuedButton = wrapper.get('button[aria-label="Clear queued"]')
|
||||
await clearQueuedButton.trigger('click')
|
||||
expect(wrapper.emitted('clearQueued')).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('hides clear queued button when queued count is zero', () => {
|
||||
const wrapper = mountHeader({ queuedCount: 0 })
|
||||
|
||||
expect(wrapper.find('button[aria-label="Clear queued"]').exists()).toBe(
|
||||
false
|
||||
)
|
||||
})
|
||||
|
||||
it('toggles popover and emits clear history', async () => {
|
||||
const spy = vi.spyOn(tooltipConfig, 'buildTooltipConfig')
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div
|
||||
class="flex h-12 items-center justify-between gap-2 border-b border-interface-stroke px-2"
|
||||
class="flex h-12 items-center gap-2 border-b border-interface-stroke px-2"
|
||||
>
|
||||
<div class="px-2 text-[14px] font-normal text-text-primary">
|
||||
<div class="min-w-0 flex-1 px-2 text-[14px] font-normal text-text-primary">
|
||||
<span>{{ headerTitle }}</span>
|
||||
<span
|
||||
v-if="showConcurrentIndicator"
|
||||
@@ -17,6 +17,25 @@
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="inline-flex h-6 items-center gap-2 text-[12px] leading-none text-text-primary"
|
||||
>
|
||||
<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"
|
||||
variant="destructive"
|
||||
size="icon"
|
||||
:aria-label="t('sideToolbar.queueProgressOverlay.clearQueued')"
|
||||
@click="$emit('clearQueued')"
|
||||
>
|
||||
<i class="icon-[lucide--list-x] size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
<div v-if="!isCloud" class="flex items-center gap-1">
|
||||
<Button
|
||||
v-tooltip.top="moreTooltipConfig"
|
||||
@@ -78,10 +97,12 @@ defineProps<{
|
||||
headerTitle: string
|
||||
showConcurrentIndicator: boolean
|
||||
concurrentWorkflowCount: number
|
||||
queuedCount: number
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'clearHistory'): void
|
||||
(e: 'clearQueued'): void
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
Reference in New Issue
Block a user