@@ -11,6 +11,7 @@ import { DateTime, DateTimeAccurate } from "../primitives/DateTime";
1111import { Spinner } from "../primitives/Spinner" ;
1212import { LiveTimer } from "../runs/v3/LiveTimer" ;
1313import tileBgPath from "~/assets/images/[email protected] " ; 14+ import { Tooltip , TooltipContent , TooltipProvider , TooltipTrigger } from "../primitives/Tooltip" ;
1415
1516// Types for the RunTimeline component
1617export type TimelineEventState = "complete" | "error" | "inprogress" | "delayed" ;
@@ -35,6 +36,7 @@ export type TimelineEventDefinition = {
3536 state ?: TimelineEventState ;
3637 shouldRender : boolean ;
3738 variant : TimelineEventVariant ;
39+ helpText ?: string ;
3840} ;
3941
4042export type TimelineLineDefinition = {
@@ -92,6 +94,7 @@ export function RunTimeline({ run }: { run: TimelineSpanRun }) {
9294 }
9395 state = { item . state as "complete" | "error" }
9496 variant = { item . variant }
97+ helpText = { item . helpText }
9598 />
9699 ) ;
97100 } else {
@@ -124,6 +127,7 @@ function buildTimelineItems(run: TimelineSpanRun): TimelineItem[] {
124127 state,
125128 shouldRender : true ,
126129 variant : "start-cap" ,
130+ helpText : getHelpTextForEvent ( "Triggered" ) ,
127131 } ) ;
128132
129133 // 2. Waiting to dequeue line
@@ -195,6 +199,7 @@ function buildTimelineItems(run: TimelineSpanRun): TimelineItem[] {
195199 state,
196200 shouldRender : true ,
197201 variant : "dot-hollow" ,
202+ helpText : getHelpTextForEvent ( "Dequeued" ) ,
198203 } ) ;
199204 }
200205
@@ -223,6 +228,7 @@ function buildTimelineItems(run: TimelineSpanRun): TimelineItem[] {
223228 state,
224229 shouldRender : true ,
225230 variant : "start-cap-thick" ,
231+ helpText : getHelpTextForEvent ( "Started" ) ,
226232 } ) ;
227233
228234 // 4c. Show executing line if applicable
@@ -283,6 +289,7 @@ function buildTimelineItems(run: TimelineSpanRun): TimelineItem[] {
283289 state,
284290 shouldRender : true ,
285291 variant : "end-cap-thick" ,
292+ helpText : getHelpTextForEvent ( "Finished" ) ,
286293 } ) ;
287294 }
288295
@@ -297,6 +304,7 @@ function buildTimelineItems(run: TimelineSpanRun): TimelineItem[] {
297304 state : "error" ,
298305 shouldRender : true ,
299306 variant : "dot-solid" ,
307+ helpText : getHelpTextForEvent ( "Expired" ) ,
300308 } ) ;
301309 }
302310
@@ -308,21 +316,34 @@ export type RunTimelineEventProps = {
308316 subtitle ?: ReactNode ;
309317 state ?: "complete" | "error" | "inprogress" ;
310318 variant ?: TimelineEventVariant ;
319+ helpText ?: string ;
311320} ;
312321
313322export function RunTimelineEvent ( {
314323 title,
315324 subtitle,
316325 state,
317326 variant = "dot-hollow" ,
327+ helpText,
318328} : RunTimelineEventProps ) {
319329 return (
320330 < div className = "grid h-5 grid-cols-[1.125rem_1fr] gap-1 text-sm" >
321331 < div className = "relative flex flex-col items-center justify-center" >
322332 < EventMarker variant = { variant } state = { state } />
323333 </ div >
324334 < div className = "flex items-baseline justify-between gap-3" >
325- < span className = "font-medium text-text-bright" > { title } </ span >
335+ < TooltipProvider disableHoverableContent >
336+ < Tooltip >
337+ < TooltipTrigger className = "cursor-default" >
338+ < span className = "font-medium text-text-bright" > { title } </ span >
339+ </ TooltipTrigger >
340+ { helpText && (
341+ < TooltipContent className = "flex items-center gap-1 text-xs" >
342+ { helpText }
343+ </ TooltipContent >
344+ ) }
345+ </ Tooltip >
346+ </ TooltipProvider >
326347 { subtitle ? (
327348 < span className = "text-xs tabular-nums text-text-dimmed" > { subtitle } </ span >
328349 ) : null }
@@ -605,6 +626,7 @@ export function SpanTimeline({
605626 subtitle = { < DateTimeAccurate date = { event . timestamp } previousDate = { prevDate } /> }
606627 variant = { event . markerVariant }
607628 state = { state }
629+ helpText = { event . helpText }
608630 />
609631 < RunTimelineLine
610632 title = {
@@ -632,6 +654,7 @@ export function SpanTimeline({
632654 }
633655 variant = { "start-cap-thick" }
634656 state = { state }
657+ helpText = { getHelpTextForEvent ( "Started" ) }
635658 />
636659 { state === "inprogress" ? (
637660 < RunTimelineLine
@@ -659,6 +682,7 @@ export function SpanTimeline({
659682 }
660683 state = { isError ? "error" : undefined }
661684 variant = "end-cap-thick"
685+ helpText = { getHelpTextForEvent ( "Finished" ) }
662686 />
663687 </ >
664688 ) }
@@ -822,6 +846,27 @@ function getHelpTextForEvent(event: string): string | undefined {
822846 case "import" : {
823847 return "A task file was imported" ;
824848 }
849+ case "lazy_payload" : {
850+ return "The payload was initialized lazily" ;
851+ }
852+ case "pod_scheduled" : {
853+ return "The Kubernetes pod was scheduled to run the task" ;
854+ }
855+ case "Triggered" : {
856+ return "When the run was initially triggered" ;
857+ }
858+ case "Dequeued" : {
859+ return "When the run was taken from the queue for processing" ;
860+ }
861+ case "Started" : {
862+ return "When the run began execution" ;
863+ }
864+ case "Finished" : {
865+ return "The run completed execution" ;
866+ }
867+ case "Expired" : {
868+ return "The run expired before it could be processed" ;
869+ }
825870 default : {
826871 return undefined ;
827872 }
0 commit comments