mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-02 20:22:08 +00:00
## Summary - replace raw button elements in queue progress overlay UI with shared IconButton/TextButton/IconTextButton components - remove forced justify-start from IconTextButton base and add explicit alignment where needed - keep queue overlay actions consistent with button styling patterns ## Testing - pnpm typecheck - pnpm lint:fix ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6793-Use-shared-button-components-in-queue-overlay-2b26d73d3650814d9ebfebba74226036) by [Unito](https://www.unito.io)
152 lines
4.7 KiB
Vue
152 lines
4.7 KiB
Vue
<template>
|
|
<div class="flex w-full flex-col gap-4">
|
|
<QueueOverlayHeader
|
|
:header-title="headerTitle"
|
|
:show-concurrent-indicator="showConcurrentIndicator"
|
|
:concurrent-workflow-count="concurrentWorkflowCount"
|
|
@clear-history="$emit('clearHistory')"
|
|
/>
|
|
|
|
<div class="flex items-center justify-between px-3">
|
|
<IconTextButton
|
|
class="grow gap-1 p-2 text-center font-inter text-[12px] leading-none hover:opacity-90 justify-center"
|
|
type="secondary"
|
|
:label="t('sideToolbar.queueProgressOverlay.showAssets')"
|
|
:aria-label="t('sideToolbar.queueProgressOverlay.showAssets')"
|
|
@click="$emit('showAssets')"
|
|
>
|
|
<template #icon>
|
|
<div
|
|
class="pointer-events-none block size-4 shrink-0 leading-none icon-[comfy--image-ai-edit]"
|
|
aria-hidden="true"
|
|
/>
|
|
</template>
|
|
</IconTextButton>
|
|
<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>
|
|
<IconButton
|
|
v-if="queuedCount > 0"
|
|
class="group ml-2 size-6 bg-secondary-background hover:bg-destructive-background"
|
|
type="secondary"
|
|
size="sm"
|
|
:aria-label="t('sideToolbar.queueProgressOverlay.clearQueued')"
|
|
@click="$emit('clearQueued')"
|
|
>
|
|
<i
|
|
class="pointer-events-none icon-[lucide--list-x] block size-4 leading-none text-text-primary transition-colors group-hover:text-base-background"
|
|
/>
|
|
</IconButton>
|
|
</div>
|
|
</div>
|
|
|
|
<JobFiltersBar
|
|
:selected-job-tab="selectedJobTab"
|
|
:selected-workflow-filter="selectedWorkflowFilter"
|
|
:selected-sort-mode="selectedSortMode"
|
|
:has-failed-jobs="hasFailedJobs"
|
|
@update:selected-job-tab="$emit('update:selectedJobTab', $event)"
|
|
@update:selected-workflow-filter="
|
|
$emit('update:selectedWorkflowFilter', $event)
|
|
"
|
|
@update:selected-sort-mode="$emit('update:selectedSortMode', $event)"
|
|
/>
|
|
|
|
<div class="flex-1 min-h-0 overflow-y-auto">
|
|
<JobGroupsList
|
|
:displayed-job-groups="displayedJobGroups"
|
|
@cancel-item="onCancelItemEvent"
|
|
@delete-item="onDeleteItemEvent"
|
|
@view-item="$emit('viewItem', $event)"
|
|
@menu="onMenuItem"
|
|
/>
|
|
</div>
|
|
|
|
<JobContextMenu
|
|
ref="jobContextMenuRef"
|
|
:entries="jobMenuEntries"
|
|
@action="onJobMenuAction"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
|
|
import IconButton from '@/components/button/IconButton.vue'
|
|
import IconTextButton from '@/components/button/IconTextButton.vue'
|
|
import type {
|
|
JobGroup,
|
|
JobListItem,
|
|
JobSortMode,
|
|
JobTab
|
|
} from '@/composables/queue/useJobList'
|
|
import type { MenuEntry } from '@/composables/queue/useJobMenu'
|
|
import { useJobMenu } from '@/composables/queue/useJobMenu'
|
|
|
|
import QueueOverlayHeader from './QueueOverlayHeader.vue'
|
|
import JobContextMenu from './job/JobContextMenu.vue'
|
|
import JobFiltersBar from './job/JobFiltersBar.vue'
|
|
import JobGroupsList from './job/JobGroupsList.vue'
|
|
|
|
defineProps<{
|
|
headerTitle: string
|
|
showConcurrentIndicator: boolean
|
|
concurrentWorkflowCount: number
|
|
queuedCount: number
|
|
selectedJobTab: JobTab
|
|
selectedWorkflowFilter: 'all' | 'current'
|
|
selectedSortMode: JobSortMode
|
|
displayedJobGroups: JobGroup[]
|
|
hasFailedJobs: boolean
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
(e: 'showAssets'): void
|
|
(e: 'clearHistory'): void
|
|
(e: 'clearQueued'): void
|
|
(e: 'update:selectedJobTab', value: JobTab): void
|
|
(e: 'update:selectedWorkflowFilter', value: 'all' | 'current'): void
|
|
(e: 'update:selectedSortMode', value: JobSortMode): void
|
|
(e: 'cancelItem', item: JobListItem): void
|
|
(e: 'deleteItem', item: JobListItem): void
|
|
(e: 'viewItem', item: JobListItem): void
|
|
}>()
|
|
|
|
const { t } = useI18n()
|
|
|
|
const currentMenuItem = ref<JobListItem | null>(null)
|
|
const jobContextMenuRef = ref<InstanceType<typeof JobContextMenu> | null>(null)
|
|
|
|
const { jobMenuEntries } = useJobMenu(
|
|
() => currentMenuItem.value,
|
|
(item) => emit('viewItem', item)
|
|
)
|
|
|
|
const onCancelItemEvent = (item: JobListItem) => {
|
|
emit('cancelItem', item)
|
|
}
|
|
|
|
const onDeleteItemEvent = (item: JobListItem) => {
|
|
emit('deleteItem', item)
|
|
}
|
|
|
|
const onMenuItem = (item: JobListItem, event: Event) => {
|
|
currentMenuItem.value = item
|
|
jobContextMenuRef.value?.open(event)
|
|
}
|
|
|
|
const onJobMenuAction = async (entry: MenuEntry) => {
|
|
if (entry.kind === 'divider') return
|
|
if (entry.onClick) await entry.onClick()
|
|
jobContextMenuRef.value?.hide()
|
|
}
|
|
</script>
|