diff --git a/src/composables/queue/useJobList.ts b/src/composables/queue/useJobList.ts index 2250cf3e8..133c62423 100644 --- a/src/composables/queue/useJobList.ts +++ b/src/composables/queue/useJobList.ts @@ -4,7 +4,6 @@ import { useI18n } from 'vue-i18n' import { useCurrentNodeName } from '@/composables/queue/useCurrentNodeName' import { useQueueProgress } from '@/composables/queue/useQueueProgress' import { isCloud } from '@/platform/distribution/types' -import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore' import { useExecutionStore } from '@/stores/executionStore' import { useQueueStore } from '@/stores/queueStore' import type { TaskItemImpl } from '@/stores/queueStore' @@ -19,14 +18,6 @@ import { import { buildJobDisplay } from '@/utils/queueDisplay' import { jobStateFromTask } from '@/utils/queueUtil' -/** Tabs for job list filtering */ -/** Tabs for job list filtering */ -const jobTabs = ['All', 'Completed', 'Failed'] -type JobTab = (typeof jobTabs)[number] - -const jobSortModes = ['mostRecent', 'totalGenerationTime'] -type JobSortMode = (typeof jobSortModes)[number] - /** * UI item in the job list. Mirrors data previously prepared inline. */ @@ -89,13 +80,12 @@ type TaskWithState = { } /** - * Builds the reactive job list, filters, and grouped view for the queue overlay. + * Builds the reactive job list and grouped view for the queue overlay. */ export function useJobList() { const { t, locale } = useI18n() const queueStore = useQueueStore() const executionStore = useExecutionStore() - const workflowStore = useWorkflowStore() const seenPendingIds = ref>(new Set()) const recentlyAddedPendingIds = ref>(new Set()) @@ -184,11 +174,7 @@ export function useJobList() { const isJobInitializing = (promptId: string | number | undefined) => executionStore.isPromptInitializing(promptId) - const selectedJobTab = ref('All') - const selectedWorkflowFilter = ref<'all' | 'current'>('all') - const selectedSortMode = ref('mostRecent') - - const allTasksSorted = computed(() => { + const orderedTasks = computed(() => { const all = [ ...queueStore.pendingTasks, ...queueStore.runningTasks, @@ -198,50 +184,14 @@ export function useJobList() { }) const tasksWithJobState = computed(() => - allTasksSorted.value.map((task) => ({ + orderedTasks.value.map((task) => ({ task, state: jobStateFromTask(task, isJobInitializing(task?.promptId)) })) ) - const hasFailedJobs = computed(() => - tasksWithJobState.value.some(({ state }) => state === 'failed') - ) - - watch( - () => hasFailedJobs.value, - (hasFailed) => { - if (!hasFailed && selectedJobTab.value === 'Failed') { - selectedJobTab.value = 'All' - } - } - ) - - const filteredTaskEntries = computed(() => { - let entries = tasksWithJobState.value - if (selectedJobTab.value === 'Completed') { - entries = entries.filter(({ state }) => state === 'completed') - } else if (selectedJobTab.value === 'Failed') { - entries = entries.filter(({ state }) => state === 'failed') - } - - if (selectedWorkflowFilter.value === 'current') { - const activeId = workflowStore.activeWorkflow?.activeState?.id - if (!activeId) return [] - entries = entries.filter(({ task }) => { - const wid = task.workflow?.id - return !!wid && wid === activeId - }) - } - return entries - }) - - const filteredTasks = computed(() => - filteredTaskEntries.value.map(({ task }) => task) - ) - const jobItems = computed(() => { - return filteredTaskEntries.value.map(({ task, state }) => { + return tasksWithJobState.value.map(({ task, state }) => { const isActive = String(task.promptId ?? '') === String(executionStore.activePromptId ?? '') @@ -295,7 +245,7 @@ export function useJobList() { const groups: JobGroup[] = [] const index = new Map() const localeValue = locale.value - for (const { task, state } of filteredTaskEntries.value) { + for (const { task, state } of tasksWithJobState.value) { let ts: number | undefined if (state === 'completed' || state === 'failed') { ts = task.executionEndTimestamp @@ -321,29 +271,11 @@ export function useJobList() { if (ji) groups[groupIdx].items.push(ji) } - if (selectedSortMode.value === 'totalGenerationTime') { - const valueOrDefault = (value: JobListItem['executionTimeMs']) => - typeof value === 'number' && !Number.isNaN(value) ? value : -1 - const sortByExecutionTimeDesc = (a: JobListItem, b: JobListItem) => - valueOrDefault(b.executionTimeMs) - valueOrDefault(a.executionTimeMs) - - groups.forEach((group) => { - group.items.sort(sortByExecutionTimeDesc) - }) - } - return groups }) return { - // filters/state - selectedJobTab, - selectedWorkflowFilter, - selectedSortMode, - hasFailedJobs, - // data sources - allTasksSorted, - filteredTasks, + orderedTasks, jobItems, groupedJobItems, currentNodeName diff --git a/tests-ui/tests/composables/useJobList.test.ts b/tests-ui/tests/composables/useJobList.test.ts index 36a14162b..d433804d7 100644 --- a/tests-ui/tests/composables/useJobList.test.ts +++ b/tests-ui/tests/composables/useJobList.test.ts @@ -158,23 +158,6 @@ vi.mock('@/stores/executionStore', () => ({ } })) -let workflowStoreMock: { - activeWorkflow: null | { activeState?: { id?: string } } -} -const ensureWorkflowStore = () => { - if (!workflowStoreMock) { - workflowStoreMock = reactive({ - activeWorkflow: null as null | { activeState?: { id?: string } } - }) - } - return workflowStoreMock -} -vi.mock('@/platform/workflow/management/stores/workflowStore', () => ({ - useWorkflowStore: () => { - return ensureWorkflowStore() - } -})) - const createTask = ( overrides: Partial & { mockState?: JobState } = {} ): TestTask => ({ @@ -210,9 +193,6 @@ const resetStores = () => { executionStore.activePromptId = null executionStore.executingNode = null - const workflowStore = ensureWorkflowStore() - workflowStore.activeWorkflow = null - ensureProgressRefs() totalPercent.value = 0 currentNodePercent.value = 0 @@ -332,7 +312,7 @@ describe('useJobList', () => { expect(vi.getTimerCount()).toBe(0) }) - it('sorts all tasks by queue index descending', async () => { + it('sorts tasks by queue index descending', async () => { queueStoreMock.pendingTasks = [ createTask({ promptId: 'p', queueIndex: 1, mockState: 'pending' }) ] @@ -343,75 +323,16 @@ describe('useJobList', () => { createTask({ promptId: 'h', queueIndex: 3, mockState: 'completed' }) ] - const { allTasksSorted } = initComposable() + const { orderedTasks } = initComposable() await flush() - expect(allTasksSorted.value.map((task) => task.promptId)).toEqual([ + expect(orderedTasks.value.map((task) => task.promptId)).toEqual([ 'r', 'h', 'p' ]) }) - it('filters by job tab and resets failed tab when failures disappear', async () => { - queueStoreMock.historyTasks = [ - createTask({ promptId: 'c', queueIndex: 3, mockState: 'completed' }), - createTask({ promptId: 'f', queueIndex: 2, mockState: 'failed' }), - createTask({ promptId: 'p', queueIndex: 1, mockState: 'pending' }) - ] - - const instance = initComposable() - await flush() - - instance.selectedJobTab.value = 'Completed' - await flush() - expect(instance.filteredTasks.value.map((t) => t.promptId)).toEqual(['c']) - - instance.selectedJobTab.value = 'Failed' - await flush() - expect(instance.filteredTasks.value.map((t) => t.promptId)).toEqual(['f']) - expect(instance.hasFailedJobs.value).toBe(true) - - queueStoreMock.historyTasks = [ - createTask({ promptId: 'c', queueIndex: 3, mockState: 'completed' }) - ] - await flush() - - expect(instance.hasFailedJobs.value).toBe(false) - expect(instance.selectedJobTab.value).toBe('All') - }) - - it('filters by active workflow when requested', async () => { - queueStoreMock.pendingTasks = [ - createTask({ - promptId: 'wf-1', - queueIndex: 2, - mockState: 'pending', - workflow: { id: 'workflow-1' } - }), - createTask({ - promptId: 'wf-2', - queueIndex: 1, - mockState: 'pending', - workflow: { id: 'workflow-2' } - }) - ] - - const instance = initComposable() - await flush() - - instance.selectedWorkflowFilter.value = 'current' - await flush() - expect(instance.filteredTasks.value).toEqual([]) - - workflowStoreMock.activeWorkflow = { activeState: { id: 'workflow-1' } } - await flush() - - expect(instance.filteredTasks.value.map((t) => t.promptId)).toEqual([ - 'wf-1' - ]) - }) - it('hydrates job items with active progress and compute hours', async () => { queueStoreMock.runningTasks = [ createTask({ @@ -468,7 +389,7 @@ describe('useJobList', () => { ) }) - it('groups job items by date label and sorts by total generation time when requested', async () => { + it('groups job items by date label using queue order', async () => { vi.useFakeTimers() vi.setSystemTime(new Date('2024-01-10T12:00:00Z')) queueStoreMock.historyTasks = [ @@ -501,7 +422,6 @@ describe('useJobList', () => { ] const instance = initComposable() - instance.selectedSortMode.value = 'totalGenerationTime' await flush() const groups = instance.groupedJobItems.value @@ -513,8 +433,8 @@ describe('useJobList', () => { const todayGroup = groups[0] expect(todayGroup.items.map((item) => item.id)).toEqual([ - 'today-large', - 'today-small' + 'today-small', + 'today-large' ]) }) })