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 @@
+
+
+
+
+
+
+ {{
+ t('sideToolbar.queueProgressOverlay.clearHistoryDialogDescription')
+ }}
+
+
+ {{ t('sideToolbar.queueProgressOverlay.clearHistoryDialogAssetsNote') }}
+
+
+
+
+
+
+
+