From b455766d12a953eef28ad0b9dd3cf6b540df42f8 Mon Sep 17 00:00:00 2001 From: Benjamin Lu Date: Tue, 16 Dec 2025 13:15:50 -0800 Subject: [PATCH] Revert "Remove queue overlay header more menu (#7552)" (#7569) This reverts commit eb05a4f3eec75269de88711ee1612f1a909d9dd8. In favor of making a change to main, and backporting, with v-if=!iscloud on the ... menu --- src/components/queue/QueueOverlayExpanded.vue | 2 + .../queue/QueueOverlayHeader.test.ts | 53 ++++++++++- src/components/queue/QueueOverlayHeader.vue | 68 ++++++++++++++ src/components/queue/QueueProgressOverlay.vue | 29 ++++++ .../queue/dialogs/QueueClearHistoryDialog.vue | 90 +++++++++++++++++++ 5 files changed, 239 insertions(+), 3 deletions(-) create mode 100644 src/components/queue/dialogs/QueueClearHistoryDialog.vue diff --git a/src/components/queue/QueueOverlayExpanded.vue b/src/components/queue/QueueOverlayExpanded.vue index 01c0f85802..64e8458e0b 100644 --- a/src/components/queue/QueueOverlayExpanded.vue +++ b/src/components/queue/QueueOverlayExpanded.vue @@ -4,6 +4,7 @@ :header-title="headerTitle" :show-concurrent-indicator="showConcurrentIndicator" :concurrent-workflow-count="concurrentWorkflowCount" + @clear-history="$emit('clearHistory')" />
@@ -109,6 +110,7 @@ defineProps<{ 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 diff --git a/src/components/queue/QueueOverlayHeader.test.ts b/src/components/queue/QueueOverlayHeader.test.ts index c7f7f90c0d..2a64cdc6f3 100644 --- a/src/components/queue/QueueOverlayHeader.test.ts +++ b/src/components/queue/QueueOverlayHeader.test.ts @@ -1,17 +1,47 @@ import { mount } from '@vue/test-utils' -import { describe, expect, it } from 'vitest' +import { describe, expect, it, vi } from 'vitest' import { createI18n } from 'vue-i18n' +import { defineComponent } from 'vue' + +const popoverToggleSpy = vi.fn() +const popoverHideSpy = vi.fn() + +vi.mock('primevue/popover', () => { + const PopoverStub = defineComponent({ + name: 'Popover', + setup(_, { slots, expose }) { + const toggle = (event: Event) => { + popoverToggleSpy(event) + } + const hide = () => { + popoverHideSpy() + } + expose({ toggle, hide }) + return () => slots.default?.() + } + }) + return { default: PopoverStub } +}) import QueueOverlayHeader from './QueueOverlayHeader.vue' +import * as tooltipConfig from '@/composables/useTooltipConfig' + +const tooltipDirectiveStub = { + mounted: vi.fn(), + updated: vi.fn() +} const i18n = createI18n({ legacy: false, locale: 'en', messages: { en: { + g: { more: 'More' }, sideToolbar: { queueProgressOverlay: { - running: 'running' + running: 'running', + moreOptions: 'More options', + clearHistory: 'Clear history' } } } @@ -27,7 +57,8 @@ const mountHeader = (props = {}) => ...props }, global: { - plugins: [i18n] + plugins: [i18n], + directives: { tooltip: tooltipDirectiveStub } } }) @@ -48,4 +79,20 @@ describe('QueueOverlayHeader', () => { expect(wrapper.text()).toContain('Job queue') expect(wrapper.find('.inline-flex.items-center.gap-1').exists()).toBe(false) }) + + it('toggles popover and emits clear history', async () => { + const spy = vi.spyOn(tooltipConfig, 'buildTooltipConfig') + + const wrapper = mountHeader() + + const moreButton = wrapper.get('button[aria-label="More options"]') + await moreButton.trigger('click') + expect(popoverToggleSpy).toHaveBeenCalledTimes(1) + expect(spy).toHaveBeenCalledWith('More') + + const clearHistoryButton = wrapper.get('button[aria-label="Clear history"]') + await clearHistoryButton.trigger('click') + expect(popoverHideSpy).toHaveBeenCalledTimes(1) + expect(wrapper.emitted('clearHistory')).toHaveLength(1) + }) }) diff --git a/src/components/queue/QueueOverlayHeader.vue b/src/components/queue/QueueOverlayHeader.vue index 88975ac0b7..9b45cc57b8 100644 --- a/src/components/queue/QueueOverlayHeader.vue +++ b/src/components/queue/QueueOverlayHeader.vue @@ -17,17 +17,85 @@
+
+ + + + +
+ + + +
+
+
diff --git a/src/components/queue/QueueProgressOverlay.vue b/src/components/queue/QueueProgressOverlay.vue index 4766ad732f..a941af55aa 100644 --- a/src/components/queue/QueueProgressOverlay.vue +++ b/src/components/queue/QueueProgressOverlay.vue @@ -23,6 +23,7 @@ :displayed-job-groups="displayedJobGroups" :has-failed-jobs="hasFailedJobs" @show-assets="openAssetsSidebar" + @clear-history="onClearHistoryFromMenu" @clear-queued="cancelQueuedWorkflows" @cancel-item="onCancelItem" @delete-item="onDeleteItem" @@ -65,6 +66,7 @@ import { useI18n } from 'vue-i18n' import QueueOverlayActive from '@/components/queue/QueueOverlayActive.vue' import QueueOverlayEmpty from '@/components/queue/QueueOverlayEmpty.vue' import QueueOverlayExpanded from '@/components/queue/QueueOverlayExpanded.vue' +import QueueClearHistoryDialog from '@/components/queue/dialogs/QueueClearHistoryDialog.vue' import ResultGallery from '@/components/sidebar/tabs/queue/ResultGallery.vue' import { useCompletionSummary } from '@/composables/queue/useCompletionSummary' import { useJobList } from '@/composables/queue/useJobList' @@ -77,6 +79,7 @@ import { isCloud } from '@/platform/distribution/types' import { api } from '@/scripts/api' import { useAssetsStore } from '@/stores/assetsStore' import { useCommandStore } from '@/stores/commandStore' +import { useDialogStore } from '@/stores/dialogStore' import { useExecutionStore } from '@/stores/executionStore' import { useQueueStore } from '@/stores/queueStore' import { useSidebarTabStore } from '@/stores/workspace/sidebarTabStore' @@ -102,6 +105,7 @@ const queueStore = useQueueStore() const commandStore = useCommandStore() const executionStore = useExecutionStore() const sidebarTabStore = useSidebarTabStore() +const dialogStore = useDialogStore() const assetsStore = useAssetsStore() const assetSelectionStore = useAssetSelectionStore() const { wrapWithErrorHandlingAsync } = useErrorHandling() @@ -276,4 +280,29 @@ const interruptAll = wrapWithErrorHandlingAsync(async () => { await Promise.all(promptIds.map((id) => api.interrupt(id))) }) + +const showClearHistoryDialog = () => { + dialogStore.showDialog({ + key: 'queue-clear-history', + component: QueueClearHistoryDialog, + dialogComponentProps: { + headless: true, + closable: false, + closeOnEscape: true, + dismissableMask: true, + pt: { + root: { + class: 'max-w-[360px] w-auto bg-transparent border-none shadow-none' + }, + content: { + class: '!p-0 bg-transparent' + } + } + } + }) +} + +const onClearHistoryFromMenu = () => { + showClearHistoryDialog() +} diff --git a/src/components/queue/dialogs/QueueClearHistoryDialog.vue b/src/components/queue/dialogs/QueueClearHistoryDialog.vue new file mode 100644 index 0000000000..49283b7177 --- /dev/null +++ b/src/components/queue/dialogs/QueueClearHistoryDialog.vue @@ -0,0 +1,90 @@ + + +