From e70484d59635e4a53e5c88d0975eacbc6bf6a629 Mon Sep 17 00:00:00 2001 From: Benjamin Lu Date: Mon, 16 Feb 2026 18:19:16 -0800 Subject: [PATCH] fix: move queue assets action into filter controls (#8926) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Move the queue overlay "Show assets" action into the filter controls as an icon button, so the action is available inline with other list controls while keeping existing behavior. ## Changes - **What**: - Remove the full-width "Show assets" button from `QueueOverlayExpanded`. - Add a secondary icon button in `JobFiltersBar` with tooltip + aria-label and emit `showAssets` on click. - Wire `showAssets` from `JobFiltersBar` through `QueueOverlayExpanded` to the existing handler. - Add `JobFiltersBar` unit coverage to verify `showAssets` is emitted when the icon button is clicked. ## Review Focus - Verify the icon button placement in the filter row is sensible and discoverable. - Verify clicking the new button opens the assets panel as before. - Verify tooltip and accessibility label copy are correct. ## Screenshots (if applicable) Design: https://www.figma.com/design/LVilZgHGk5RwWOkVN6yCEK/Queue-Progress-Modal?node-id=3924-38560&m=dev Screenshot 2026-02-16 at 4 53 34 PM --- src/components/queue/QueueOverlayExpanded.vue | 17 +--- .../queue/job/JobFiltersBar.test.ts | 79 +++++++++++++++++++ src/components/queue/job/JobFiltersBar.vue | 13 +++ 3 files changed, 93 insertions(+), 16 deletions(-) create mode 100644 src/components/queue/job/JobFiltersBar.test.ts diff --git a/src/components/queue/QueueOverlayExpanded.vue b/src/components/queue/QueueOverlayExpanded.vue index fad53db111..8e1d5d3e0a 100644 --- a/src/components/queue/QueueOverlayExpanded.vue +++ b/src/components/queue/QueueOverlayExpanded.vue @@ -9,23 +9,12 @@ @clear-queued="$emit('clearQueued')" /> -
- -
- import { ref } from 'vue' -import { useI18n } from 'vue-i18n' -import Button from '@/components/ui/button/Button.vue' import type { JobGroup, JobListItem, @@ -94,8 +81,6 @@ const emit = defineEmits<{ (e: 'viewItem', item: JobListItem): void }>() -const { t } = useI18n() - const currentMenuItem = ref(null) const jobContextMenuRef = ref | null>(null) diff --git a/src/components/queue/job/JobFiltersBar.test.ts b/src/components/queue/job/JobFiltersBar.test.ts new file mode 100644 index 0000000000..69e3b7901d --- /dev/null +++ b/src/components/queue/job/JobFiltersBar.test.ts @@ -0,0 +1,79 @@ +import { mount } from '@vue/test-utils' +import { describe, expect, it, vi } from 'vitest' +import { createI18n } from 'vue-i18n' +import { defineComponent } from 'vue' + +vi.mock('primevue/popover', () => { + const PopoverStub = defineComponent({ + name: 'Popover', + setup(_, { slots, expose }) { + expose({ + hide: () => undefined, + toggle: (_event: Event) => undefined + }) + return () => slots.default?.() + } + }) + return { default: PopoverStub } +}) + +vi.mock('@/platform/distribution/types', () => ({ + isCloud: false +})) + +import JobFiltersBar from '@/components/queue/job/JobFiltersBar.vue' + +const i18n = createI18n({ + legacy: false, + locale: 'en', + messages: { + en: { + g: { + all: 'All', + completed: 'Completed' + }, + queue: { + jobList: { + sortMostRecent: 'Most recent', + sortTotalGenerationTime: 'Total generation time' + } + }, + sideToolbar: { + queueProgressOverlay: { + filterJobs: 'Filter jobs', + filterBy: 'Filter by', + sortJobs: 'Sort jobs', + sortBy: 'Sort by', + showAssets: 'Show assets', + showAssetsPanel: 'Show assets panel', + filterAllWorkflows: 'All workflows', + filterCurrentWorkflow: 'Current workflow' + } + } + } + } +}) + +describe('JobFiltersBar', () => { + it('emits showAssets when the assets icon button is clicked', async () => { + const wrapper = mount(JobFiltersBar, { + props: { + selectedJobTab: 'All', + selectedWorkflowFilter: 'all', + selectedSortMode: 'mostRecent', + hasFailedJobs: false + }, + global: { + plugins: [i18n], + directives: { tooltip: () => undefined } + } + }) + + const showAssetsButton = wrapper.get( + 'button[aria-label="Show assets panel"]' + ) + await showAssetsButton.trigger('click') + + expect(wrapper.emitted('showAssets')).toHaveLength(1) + }) +}) diff --git a/src/components/queue/job/JobFiltersBar.vue b/src/components/queue/job/JobFiltersBar.vue index a227c46d97..66b00195ee 100644 --- a/src/components/queue/job/JobFiltersBar.vue +++ b/src/components/queue/job/JobFiltersBar.vue @@ -127,6 +127,15 @@ + @@ -150,6 +159,7 @@ const props = defineProps<{ }>() const emit = defineEmits<{ + (e: 'showAssets'): void (e: 'update:selectedJobTab', value: JobTab): void (e: 'update:selectedWorkflowFilter', value: 'all' | 'current'): void (e: 'update:selectedSortMode', value: JobSortMode): void @@ -165,6 +175,9 @@ const filterTooltipConfig = computed(() => const sortTooltipConfig = computed(() => buildTooltipConfig(t('sideToolbar.queueProgressOverlay.sortBy')) ) +const showAssetsTooltipConfig = computed(() => + buildTooltipConfig(t('sideToolbar.queueProgressOverlay.showAssets')) +) // This can be removed when cloud implements /jobs and we switch to it. const showWorkflowFilter = !isCloud