@@ -11,7 +11,7 @@ import TaskDetails from '../components/task/TaskDetails';
1111import { TaskGraph } from '../components/graph' ;
1212import { formatDuration , formatRelativeTime } from '../utils/time' ;
1313import * as api from '../api/client' ;
14- import type { SSEEvent , TaskDetails as TaskDetailsType , TaskLogEntry , TestRunDetails } from '../types/api' ;
14+ import type { SSEEvent , TaskDetails as TaskDetailsType , TaskLogEntry , TaskState , TestRunDetails } from '../types/api' ;
1515
1616type ViewMode = 'list' | 'graph' ;
1717
@@ -75,7 +75,7 @@ function TestRun() {
7575 pendingTaskRefreshRef . current . add ( taskIndex ) ;
7676
7777 if ( ! refreshTimerRef . current ) {
78- refreshTimerRef . current = setTimeout ( flushTaskRefresh , 5000 ) ;
78+ refreshTimerRef . current = setTimeout ( flushTaskRefresh , 1000 ) ;
7979 }
8080 } ,
8181 [ flushTaskRefresh ]
@@ -149,8 +149,59 @@ function TestRun() {
149149 }
150150 break ;
151151 case 'task.started' :
152- case 'task.completed' :
153- case 'task.failed' :
152+ if ( event . taskIndex !== undefined ) {
153+ // Immediate optimistic update
154+ queryClient . setQueryData ( queryKeys . testRunDetails ( runIdNum ) , ( oldData ?: TestRunDetails ) => {
155+ if ( ! oldData ?. tasks ) return oldData ;
156+ return {
157+ ...oldData ,
158+ tasks : oldData . tasks . map ( ( task ) =>
159+ task . index === event . taskIndex
160+ ? { ...task , started : true , status : 'running' as const , start_time : Date . now ( ) }
161+ : task
162+ ) ,
163+ } ;
164+ } ) ;
165+ scheduleTaskRefresh ( event . taskIndex ) ;
166+ }
167+ break ;
168+ case 'task.completed' : {
169+ if ( event . taskIndex !== undefined ) {
170+ const data = event . data as { result ?: string } ;
171+ const result = data . result === 'success' ? 'success' : data . result === 'failure' ? 'failure' : 'none' ;
172+ queryClient . setQueryData ( queryKeys . testRunDetails ( runIdNum ) , ( oldData ?: TestRunDetails ) => {
173+ if ( ! oldData ?. tasks ) return oldData ;
174+ return {
175+ ...oldData ,
176+ tasks : oldData . tasks . map ( ( task ) =>
177+ task . index === event . taskIndex
178+ ? { ...task , completed : true , status : 'complete' as const , result : result as TaskState [ 'result' ] , stop_time : Date . now ( ) }
179+ : task
180+ ) ,
181+ } ;
182+ } ) ;
183+ scheduleTaskRefresh ( event . taskIndex ) ;
184+ }
185+ break ;
186+ }
187+ case 'task.failed' : {
188+ if ( event . taskIndex !== undefined ) {
189+ const data = event . data as { error ?: string } ;
190+ queryClient . setQueryData ( queryKeys . testRunDetails ( runIdNum ) , ( oldData ?: TestRunDetails ) => {
191+ if ( ! oldData ?. tasks ) return oldData ;
192+ return {
193+ ...oldData ,
194+ tasks : oldData . tasks . map ( ( task ) =>
195+ task . index === event . taskIndex
196+ ? { ...task , completed : true , status : 'complete' as const , result : 'failure' as const , result_error : data . error ?? '' , stop_time : Date . now ( ) }
197+ : task
198+ ) ,
199+ } ;
200+ } ) ;
201+ scheduleTaskRefresh ( event . taskIndex ) ;
202+ }
203+ break ;
204+ }
154205 case 'task.progress' :
155206 if ( event . taskIndex !== undefined ) {
156207 scheduleTaskRefresh ( event . taskIndex ) ;
0 commit comments