From 7c61dadaf216de975b9775f44066330567342d1d Mon Sep 17 00:00:00 2001 From: Benjamin Lu Date: Fri, 23 Jan 2026 17:52:06 -0800 Subject: [PATCH] Replace QPO with opening assets tab (#8260) Route the queue progress button to toggle the Assets sidebar when QPO V2 is enabled. This effectively "removes" the QPO for users with QPOV2 enabled. https://github.com/user-attachments/assets/fa76482d-2dc7-4c28-8810-c15c338c51e4 --------- Co-authored-by: Benjamin Lu --- src/components/TopMenuSection.test.ts | 72 ++++++++++++++++++++++++++- src/components/TopMenuSection.vue | 28 ++++++++++- 2 files changed, 96 insertions(+), 4 deletions(-) diff --git a/src/components/TopMenuSection.test.ts b/src/components/TopMenuSection.test.ts index 944ce714c..8d4f3673d 100644 --- a/src/components/TopMenuSection.test.ts +++ b/src/components/TopMenuSection.test.ts @@ -12,7 +12,10 @@ import type { JobListItem, JobStatus } from '@/platform/remote/comfyui/jobs/jobTypes' +import { useSettingStore } from '@/platform/settings/settingStore' +import { useCommandStore } from '@/stores/commandStore' import { TaskItemImpl, useQueueStore } from '@/stores/queueStore' +import { useSidebarTabStore } from '@/stores/workspace/sidebarTabStore' import { isElectron } from '@/utils/envUtil' const mockData = vi.hoisted(() => ({ isLoggedIn: false })) @@ -33,7 +36,7 @@ vi.mock('@/stores/firebaseAuthStore', () => ({ })) })) -function createWrapper() { +function createWrapper(pinia = createTestingPinia({ createSpy: vi.fn })) { const i18n = createI18n({ legacy: false, locale: 'en', @@ -53,7 +56,7 @@ function createWrapper() { return mount(TopMenuSection, { global: { - plugins: [createTestingPinia({ createSpy: vi.fn }), i18n], + plugins: [pinia, i18n], stubs: { SubgraphBreadcrumb: true, QueueProgressOverlay: true, @@ -142,6 +145,71 @@ describe('TopMenuSection', () => { expect(queueButton.text()).toContain('3 active') }) + it('hides queue progress overlay when QPO V2 is enabled', async () => { + const pinia = createTestingPinia({ createSpy: vi.fn }) + const settingStore = useSettingStore(pinia) + vi.mocked(settingStore.get).mockImplementation((key) => + key === 'Comfy.Queue.QPOV2' ? true : undefined + ) + const wrapper = createWrapper(pinia) + + await nextTick() + + expect(wrapper.find('[data-testid="queue-overlay-toggle"]').exists()).toBe( + true + ) + expect( + wrapper.findComponent({ name: 'QueueProgressOverlay' }).exists() + ).toBe(false) + }) + + it('toggles the queue progress overlay when QPO V2 is disabled', async () => { + const pinia = createTestingPinia({ createSpy: vi.fn, stubActions: false }) + const settingStore = useSettingStore(pinia) + vi.mocked(settingStore.get).mockImplementation((key) => + key === 'Comfy.Queue.QPOV2' ? false : undefined + ) + const wrapper = createWrapper(pinia) + const commandStore = useCommandStore(pinia) + + await wrapper.find('[data-testid="queue-overlay-toggle"]').trigger('click') + + expect(commandStore.execute).toHaveBeenCalledWith( + 'Comfy.Queue.ToggleOverlay' + ) + }) + + it('opens the assets sidebar tab when QPO V2 is enabled', async () => { + const pinia = createTestingPinia({ createSpy: vi.fn, stubActions: false }) + const settingStore = useSettingStore(pinia) + vi.mocked(settingStore.get).mockImplementation((key) => + key === 'Comfy.Queue.QPOV2' ? true : undefined + ) + const wrapper = createWrapper(pinia) + const sidebarTabStore = useSidebarTabStore(pinia) + + await wrapper.find('[data-testid="queue-overlay-toggle"]').trigger('click') + + expect(sidebarTabStore.activeSidebarTabId).toBe('assets') + }) + + it('toggles the assets sidebar tab when QPO V2 is enabled', async () => { + const pinia = createTestingPinia({ createSpy: vi.fn, stubActions: false }) + const settingStore = useSettingStore(pinia) + vi.mocked(settingStore.get).mockImplementation((key) => + key === 'Comfy.Queue.QPOV2' ? true : undefined + ) + const wrapper = createWrapper(pinia) + const sidebarTabStore = useSidebarTabStore(pinia) + const toggleButton = wrapper.find('[data-testid="queue-overlay-toggle"]') + + await toggleButton.trigger('click') + expect(sidebarTabStore.activeSidebarTabId).toBe('assets') + + await toggleButton.trigger('click') + expect(sidebarTabStore.activeSidebarTabId).toBe(null) + }) + it('disables the clear queue context menu item when no queued jobs exist', () => { const wrapper = createWrapper() const menu = wrapper.findComponent({ name: 'ContextMenu' }) diff --git a/src/components/TopMenuSection.vue b/src/components/TopMenuSection.vue index b6b7bc4f3..05149589c 100644 --- a/src/components/TopMenuSection.vue +++ b/src/components/TopMenuSection.vue @@ -45,7 +45,13 @@ v-tooltip.bottom="queueHistoryTooltipConfig" type="destructive" size="md" - :aria-pressed="isQueueOverlayExpanded" + :aria-pressed=" + isQueuePanelV2Enabled + ? activeSidebarTabId === 'assets' + : isQueueProgressOverlayEnabled + ? isQueueOverlayExpanded + : undefined + " class="px-3" data-testid="queue-overlay-toggle" @click="toggleQueueOverlay" @@ -55,7 +61,11 @@ {{ activeJobsLabel }} - {{ t('sideToolbar.queueProgressOverlay.expandCollapsedQueue') }} + {{ + isQueuePanelV2Enabled + ? t('sideToolbar.queueProgressOverlay.viewJobHistory') + : t('sideToolbar.queueProgressOverlay.expandCollapsedQueue') + }} @@ -77,6 +87,7 @@ @@ -108,6 +119,7 @@ import { useCommandStore } from '@/stores/commandStore' import { useExecutionStore } from '@/stores/executionStore' import { useQueueStore, useQueueUIStore } from '@/stores/queueStore' import { useRightSidePanelStore } from '@/stores/workspace/rightSidePanelStore' +import { useSidebarTabStore } from '@/stores/workspace/sidebarTabStore' import { useWorkspaceStore } from '@/stores/workspaceStore' import { isElectron } from '@/utils/envUtil' import { useConflictAcknowledgment } from '@/workbench/extensions/manager/composables/useConflictAcknowledgment' @@ -126,8 +138,10 @@ const commandStore = useCommandStore() const queueStore = useQueueStore() const executionStore = useExecutionStore() const queueUIStore = useQueueUIStore() +const sidebarTabStore = useSidebarTabStore() const { activeJobsCount } = storeToRefs(queueStore) const { isOverlayExpanded: isQueueOverlayExpanded } = storeToRefs(queueUIStore) +const { activeSidebarTabId } = storeToRefs(sidebarTabStore) const releaseStore = useReleaseStore() const { shouldShowRedDot: showReleaseRedDot } = storeToRefs(releaseStore) const { shouldShowRedDot: shouldShowConflictRedDot } = @@ -144,6 +158,12 @@ const activeJobsLabel = computed(() => { const isIntegratedTabBar = computed( () => settingStore.get('Comfy.UI.TabBarLayout') === 'Integrated' ) +const isQueuePanelV2Enabled = computed(() => + settingStore.get('Comfy.Queue.QPOV2') +) +const isQueueProgressOverlayEnabled = computed( + () => !isQueuePanelV2Enabled.value +) const queueHistoryTooltipConfig = computed(() => buildTooltipConfig(t('sideToolbar.queueProgressOverlay.viewJobHistory')) ) @@ -185,6 +205,10 @@ onMounted(() => { }) const toggleQueueOverlay = () => { + if (isQueuePanelV2Enabled.value) { + sidebarTabStore.toggleSidebarTab('assets') + return + } commandStore.execute('Comfy.Queue.ToggleOverlay') }