From 2ca0c30cf7791e5906abcc002a1d26f0e670db55 Mon Sep 17 00:00:00 2001 From: Benjamin Lu Date: Mon, 16 Feb 2026 17:48:47 -0800 Subject: [PATCH] fix: localize queue overlay running and queued summary (#8919) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Localize QueueProgressOverlay header counts with dedicated i18n pluralization keys for running and queued jobs. - Replace the previous aggregate active-job wording with a translated running/queued summary. ## What changed - Updated `QueueProgressOverlay.vue` to derive `runningJobsLabel`, `queuedJobsLabel`, and `runningQueuedSummary` via `useI18n`. - Added `QueueProgressOverlay.test.ts` coverage for expanded-header text in both active and empty queue states. - Added new English locale keys in `src/locales/en/main.json`: - `runningJobsLabel` - `queuedJobsLabel` - `runningQueuedSummary` ## Testing - `Storybook Build Status` passed. - `Playwright Tests` were still running at the last check; merge should wait for completion. ## Notes - Behavioral scope is limited to queue overlay header text/rendering. Design: https://www.figma.com/design/LVilZgHGk5RwWOkVN6yCEK/Queue-Progress-Modal?node-id=3924-38560&m=dev Screenshot 2026-02-16 at 3 30 44 PM --- .../queue/QueueProgressOverlay.test.ts | 99 +++++++++++++++++++ src/components/queue/QueueProgressOverlay.vue | 34 +++++-- src/locales/en/main.json | 3 + 3 files changed, 130 insertions(+), 6 deletions(-) create mode 100644 src/components/queue/QueueProgressOverlay.test.ts diff --git a/src/components/queue/QueueProgressOverlay.test.ts b/src/components/queue/QueueProgressOverlay.test.ts new file mode 100644 index 0000000000..801aacfdc4 --- /dev/null +++ b/src/components/queue/QueueProgressOverlay.test.ts @@ -0,0 +1,99 @@ +import { createTestingPinia } from '@pinia/testing' +import { mount } from '@vue/test-utils' +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { defineComponent } from 'vue' + +import QueueProgressOverlay from '@/components/queue/QueueProgressOverlay.vue' +import { i18n } from '@/i18n' +import type { JobStatus } from '@/platform/remote/comfyui/jobs/jobTypes' +import { TaskItemImpl, useQueueStore } from '@/stores/queueStore' + +vi.mock('@/platform/distribution/types', () => ({ + isCloud: false +})) + +const QueueOverlayExpandedStub = defineComponent({ + name: 'QueueOverlayExpanded', + props: { + headerTitle: { + type: String, + required: true + } + }, + template: '
{{ headerTitle }}
' +}) + +function createTask(id: string, status: JobStatus): TaskItemImpl { + return new TaskItemImpl({ + id, + status, + create_time: 0, + priority: 0 + }) +} + +const mountComponent = ( + runningTasks: TaskItemImpl[], + pendingTasks: TaskItemImpl[] +) => { + const pinia = createTestingPinia({ + createSpy: vi.fn, + stubActions: false + }) + const queueStore = useQueueStore(pinia) + queueStore.runningTasks = runningTasks + queueStore.pendingTasks = pendingTasks + + return mount(QueueProgressOverlay, { + props: { + expanded: true + }, + global: { + plugins: [pinia, i18n], + stubs: { + QueueOverlayExpanded: QueueOverlayExpandedStub, + QueueOverlayActive: true, + ResultGallery: true + }, + directives: { + tooltip: () => {} + } + } + }) +} + +describe('QueueProgressOverlay', () => { + beforeEach(() => { + i18n.global.locale.value = 'en' + }) + + it('shows expanded header with running and queued labels', () => { + const wrapper = mountComponent( + [ + createTask('running-1', 'in_progress'), + createTask('running-2', 'in_progress') + ], + [createTask('pending-1', 'pending')] + ) + + expect(wrapper.get('[data-testid="expanded-title"]').text()).toBe( + '2 running, 1 queued' + ) + }) + + it('shows only running label when queued count is zero', () => { + const wrapper = mountComponent([createTask('running-1', 'in_progress')], []) + + expect(wrapper.get('[data-testid="expanded-title"]').text()).toBe( + '1 running' + ) + }) + + it('shows job queue title when there are no active jobs', () => { + const wrapper = mountComponent([], []) + + expect(wrapper.get('[data-testid="expanded-title"]').text()).toBe( + 'Job Queue' + ) + }) +}) diff --git a/src/components/queue/QueueProgressOverlay.vue b/src/components/queue/QueueProgressOverlay.vue index 92ff793eb3..8096c5e2bf 100644 --- a/src/components/queue/QueueProgressOverlay.vue +++ b/src/components/queue/QueueProgressOverlay.vue @@ -92,7 +92,7 @@ const emit = defineEmits<{ (e: 'update:expanded', value: boolean): void }>() -const { t } = useI18n() +const { t, n } = useI18n() const queueStore = useQueueStore() const commandStore = useCommandStore() const executionStore = useExecutionStore() @@ -126,7 +126,6 @@ const runningCount = computed(() => queueStore.runningTasks.length) const queuedCount = computed(() => queueStore.pendingTasks.length) const isExecuting = computed(() => !executionStore.isIdle) const hasActiveJob = computed(() => runningCount.value > 0 || isExecuting.value) -const activeJobsCount = computed(() => runningCount.value + queuedCount.value) const overlayState = computed(() => { if (isExpanded.value) return 'expanded' @@ -156,11 +155,34 @@ const bottomRowClass = computed( : 'opacity-0 pointer-events-none' }` ) -const headerTitle = computed(() => - hasActiveJob.value - ? `${activeJobsCount.value} ${t('sideToolbar.queueProgressOverlay.activeJobsSuffix')}` - : t('sideToolbar.queueProgressOverlay.jobQueue') +const runningJobsLabel = computed(() => + t('sideToolbar.queueProgressOverlay.runningJobsLabel', { + count: n(runningCount.value) + }) ) +const queuedJobsLabel = computed(() => + t('sideToolbar.queueProgressOverlay.queuedJobsLabel', { + count: n(queuedCount.value) + }) +) +const headerTitle = computed(() => { + if (!hasActiveJob.value) { + return t('sideToolbar.queueProgressOverlay.jobQueue') + } + + if (queuedCount.value === 0) { + return runningJobsLabel.value + } + + if (runningCount.value === 0) { + return queuedJobsLabel.value + } + + return t('sideToolbar.queueProgressOverlay.runningQueuedSummary', { + running: runningJobsLabel.value, + queued: queuedJobsLabel.value + }) +}) const concurrentWorkflowCount = computed( () => executionStore.runningWorkflowCount diff --git a/src/locales/en/main.json b/src/locales/en/main.json index 09dd8961a4..de5ddc3f15 100644 --- a/src/locales/en/main.json +++ b/src/locales/en/main.json @@ -814,6 +814,9 @@ "activeJobs": "{count} active job | {count} active jobs", "activeJobsShort": "{count} active | {count} active", "activeJobsSuffix": "active jobs", + "runningJobsLabel": "{count} running", + "queuedJobsLabel": "{count} queued", + "runningQueuedSummary": "{running}, {queued}", "jobQueue": "Job Queue", "expandCollapsedQueue": "Expand job queue", "viewJobHistory": "View active jobs (right-click to clear queue)",