@@ -11,6 +11,7 @@ import { DateTime, DateTimeAccurate } from "../primitives/DateTime";
11
11
import { LiveTimer } from "../runs/v3/LiveTimer" ;
12
12
import tileBgPath from "~/assets/images/[email protected] " ;
13
13
import { Tooltip , TooltipContent , TooltipProvider , TooltipTrigger } from "../primitives/Tooltip" ;
14
+ import { getHelpTextForEvent , TimelineSpanEvent } from "~/utils/timelineSpanEvents" ;
14
15
15
16
// Types for the RunTimeline component
16
17
export type TimelineEventState = "complete" | "error" | "inprogress" | "delayed" ;
@@ -674,196 +675,3 @@ export function SpanTimeline({
674
675
</ >
675
676
) ;
676
677
}
677
-
678
- export type TimelineSpanEvent = {
679
- name : string ;
680
- offset : number ;
681
- timestamp : Date ;
682
- duration ?: number ;
683
- helpText ?: string ;
684
- markerVariant : TimelineEventVariant ;
685
- lineVariant : TimelineLineVariant ;
686
- } ;
687
-
688
- export function createTimelineSpanEventsFromSpanEvents (
689
- spanEvents : SpanEvent [ ] ,
690
- isAdmin : boolean ,
691
- relativeStartTime ?: number
692
- ) : Array < TimelineSpanEvent > {
693
- // Rest of function remains the same
694
- if ( ! spanEvents ) {
695
- return [ ] ;
696
- }
697
-
698
- const matchingSpanEvents = spanEvents . filter ( ( spanEvent ) =>
699
- spanEvent . name . startsWith ( "trigger.dev/" )
700
- ) ;
701
-
702
- if ( matchingSpanEvents . length === 0 ) {
703
- return [ ] ;
704
- }
705
-
706
- const sortedSpanEvents = [ ...matchingSpanEvents ] . sort ( ( a , b ) => {
707
- if ( a . time === b . time ) {
708
- return a . name . localeCompare ( b . name ) ;
709
- }
710
-
711
- const aTime = typeof a . time === "string" ? new Date ( a . time ) : a . time ;
712
- const bTime = typeof b . time === "string" ? new Date ( b . time ) : b . time ;
713
-
714
- return aTime . getTime ( ) - bTime . getTime ( ) ;
715
- } ) ;
716
-
717
- const visibleSpanEvents = sortedSpanEvents . filter (
718
- ( spanEvent ) =>
719
- isAdmin ||
720
- ! getAdminOnlyForEvent (
721
- "event" in spanEvent . properties && typeof spanEvent . properties . event === "string"
722
- ? spanEvent . properties . event
723
- : spanEvent . name
724
- )
725
- ) ;
726
-
727
- if ( visibleSpanEvents . length === 0 ) {
728
- return [ ] ;
729
- }
730
-
731
- const firstEventTime =
732
- typeof visibleSpanEvents [ 0 ] . time === "string"
733
- ? new Date ( visibleSpanEvents [ 0 ] . time )
734
- : visibleSpanEvents [ 0 ] . time ;
735
-
736
- const $relativeStartTime = relativeStartTime ?? firstEventTime . getTime ( ) ;
737
-
738
- const events = visibleSpanEvents . map ( ( spanEvent , index ) => {
739
- const timestamp =
740
- typeof spanEvent . time === "string" ? new Date ( spanEvent . time ) : spanEvent . time ;
741
-
742
- const offset = millisecondsToNanoseconds ( timestamp . getTime ( ) - $relativeStartTime ) ;
743
-
744
- const duration =
745
- "duration" in spanEvent . properties && typeof spanEvent . properties . duration === "number"
746
- ? spanEvent . properties . duration
747
- : undefined ;
748
-
749
- const name =
750
- "event" in spanEvent . properties && typeof spanEvent . properties . event === "string"
751
- ? spanEvent . properties . event
752
- : spanEvent . name ;
753
-
754
- let markerVariant : TimelineEventVariant = "dot-hollow" ;
755
-
756
- if ( index === 0 ) {
757
- markerVariant = "start-cap" ;
758
- }
759
-
760
- return {
761
- name : getFriendlyNameForEvent ( name ) ,
762
- offset,
763
- timestamp,
764
- duration,
765
- properties : spanEvent . properties ,
766
- helpText : getHelpTextForEvent ( name ) ,
767
- markerVariant,
768
- lineVariant : "light" as const ,
769
- } ;
770
- } ) ;
771
-
772
- // Now sort by offset, ascending
773
- events . sort ( ( a , b ) => a . offset - b . offset ) ;
774
-
775
- return events ;
776
- }
777
-
778
- function getFriendlyNameForEvent ( event : string ) : string {
779
- switch ( event ) {
780
- case "dequeue" : {
781
- return "Dequeued" ;
782
- }
783
- case "fork" : {
784
- return "Launched" ;
785
- }
786
- case "create_attempt" : {
787
- return "Attempt created" ;
788
- }
789
- case "import" : {
790
- return "Imported task file" ;
791
- }
792
- case "lazy_payload" : {
793
- return "Lazy attempt initialized" ;
794
- }
795
- case "pod_scheduled" : {
796
- return "Pod scheduled" ;
797
- }
798
- default : {
799
- return event ;
800
- }
801
- }
802
- }
803
-
804
- function getAdminOnlyForEvent ( event : string ) : boolean {
805
- switch ( event ) {
806
- case "dequeue" : {
807
- return false ;
808
- }
809
- case "fork" : {
810
- return false ;
811
- }
812
- case "create_attempt" : {
813
- return true ;
814
- }
815
- case "import" : {
816
- return true ;
817
- }
818
- case "lazy_payload" : {
819
- return true ;
820
- }
821
- case "pod_scheduled" : {
822
- return true ;
823
- }
824
- default : {
825
- return true ;
826
- }
827
- }
828
- }
829
-
830
- function getHelpTextForEvent ( event : string ) : string | undefined {
831
- switch ( event ) {
832
- case "dequeue" : {
833
- return "The run was dequeued from the queue" ;
834
- }
835
- case "fork" : {
836
- return "The process was created to run the task" ;
837
- }
838
- case "create_attempt" : {
839
- return "An attempt was created for the run" ;
840
- }
841
- case "import" : {
842
- return "A task file was imported" ;
843
- }
844
- case "lazy_payload" : {
845
- return "The payload was initialized lazily" ;
846
- }
847
- case "pod_scheduled" : {
848
- return "The Kubernetes pod was scheduled to run" ;
849
- }
850
- case "Triggered" : {
851
- return "The run was triggered" ;
852
- }
853
- case "Dequeued" : {
854
- return "The run was dequeued from the queue" ;
855
- }
856
- case "Started" : {
857
- return "The run began executing" ;
858
- }
859
- case "Finished" : {
860
- return "The run completed execution" ;
861
- }
862
- case "Expired" : {
863
- return "The run expired before it could be started" ;
864
- }
865
- default : {
866
- return undefined ;
867
- }
868
- }
869
- }
0 commit comments