11import type { Interpolation , Theme } from "@emotion/react" ;
22import type { TimingStage } from "api/typesGenerated" ;
3+ import { T } from "lodash/fp" ;
34import { CircleAlertIcon , InfoIcon } from "lucide-react" ;
45import type { FC } from "react" ;
56import { Bar , ClickableBar } from "./Chart/Bar" ;
@@ -52,7 +53,7 @@ export type Stage = {
5253tooltip :Omit < TooltipProps , "children" > ;
5354} ;
5455
55- type StageTiming = {
56+ export type StageTiming = {
5657stage :Stage ;
5758/**
5859 * Represents the number of resources included in this stage that can be
@@ -65,7 +66,7 @@ type StageTiming = {
6566 * duration of the stage and to position the stage within the chart. This can
6667 * be undefined if a stage has no timing data.
6768 */
68- range :TimeRange | undefined ;
69+ ranges :TimeRange [ ] | undefined ;
6970/**
7071 * Display an error icon within the bar to indicate when a stage has failed.
7172 * This is used in the agent scripts stage.
@@ -83,11 +84,15 @@ export const StagesChart: FC<StagesChartProps> = ({
8384onSelectStage,
8485} ) => {
8586const totalRange = mergeTimeRanges (
86- timings . map ( ( t ) => t . range ) . filter ( ( t ) => t !== undefined ) ,
87+ timings
88+ . map ( ( t ) => t . ranges )
89+ . filter ( ( t ) => t !== undefined )
90+ . flat ( ) ,
8791) ;
8892const totalTime = calcDuration ( totalRange ) ;
8993const [ ticks , scale ] = makeTicks ( totalTime ) ;
9094const sections = Array . from ( new Set ( timings . map ( ( t ) => t . stage . section ) ) ) ;
95+ console . log ( "timings" , timings ) ;
9196
9297return (
9398< Chart >
@@ -129,11 +134,12 @@ export const StagesChart: FC<StagesChartProps> = ({
129134const stageTimings = timings . filter (
130135( t ) => t . stage . section === section ,
131136) ;
137+
132138return (
133139< XAxisSection key = { section } >
134140{ stageTimings . map ( ( t ) => {
135141// If the stage has no timing data, we just want to render an empty row
136- if ( t . range === undefined ) {
142+ if ( t . ranges === undefined ) {
137143return (
138144< XAxisRow
139145key = { t . stage . name }
@@ -142,53 +148,55 @@ export const StagesChart: FC<StagesChartProps> = ({
142148) ;
143149}
144150
145- const value = calcDuration ( t . range ) ;
146- const offset = calcOffset ( t . range , totalRange ) ;
147- const validDuration = value > 0 && ! Number . isNaN ( value ) ;
151+ return t . ranges ?. map ( ( range , index ) => {
152+ const value = calcDuration ( range ) ;
153+ const offset = calcOffset ( range , totalRange ) ;
154+ const validDuration = value > 0 && ! Number . isNaN ( value ) ;
148155
149- return (
150- < XAxisRow
151- key = { t . stage . name }
152- yAxisLabelId = { encodeURIComponent ( t . stage . name ) }
153- >
154- { /** We only want to expand stages with more than one resource */ }
155- { t . visibleResources > 1 ?(
156- < ClickableBar
157- aria-label = { `View${ t . stage . label } details` }
158- scale = { scale }
159- value = { value }
160- offset = { offset }
161- onClick = { ( ) => {
162- onSelectStage ( t . stage ) ;
163- } }
164- >
165- { t . error && (
166- < CircleAlertIcon
167- className = "size-icon-sm"
168- css = { {
169- color :"#F87171" ,
170- marginRight :4 ,
171- } }
172- />
173- ) }
174- < Blocks count = { t . visibleResources } />
175- </ ClickableBar >
176- ) :(
177- < Bar scale = { scale } value = { value } offset = { offset } />
178- ) }
179- { validDuration ?(
180- < span > { formatTime ( value ) } </ span >
181- ) :(
182- < span
183- css = { ( theme ) => ( {
184- color :theme . palette . error . main ,
185- } ) }
186- >
187- Invalid
188- </ span >
189- ) }
190- </ XAxisRow >
191- ) ;
156+ return (
157+ < XAxisRow
158+ key = { t . stage . name + index }
159+ yAxisLabelId = { encodeURIComponent ( t . stage . name ) }
160+ >
161+ { /** We only want to expand stages with more than one resource */ }
162+ { t . visibleResources > 1 ?(
163+ < ClickableBar
164+ aria-label = { `View${ t . stage . label } details` }
165+ scale = { scale }
166+ value = { value }
167+ offset = { offset }
168+ onClick = { ( ) => {
169+ onSelectStage ( t . stage ) ;
170+ } }
171+ >
172+ { t . error && (
173+ < CircleAlertIcon
174+ className = "size-icon-sm"
175+ css = { {
176+ color :"#F87171" ,
177+ marginRight :4 ,
178+ } }
179+ />
180+ ) }
181+ < Blocks count = { t . visibleResources } />
182+ </ ClickableBar >
183+ ) :(
184+ < Bar scale = { scale } value = { value } offset = { offset } />
185+ ) }
186+ { validDuration ?(
187+ < span > { formatTime ( value ) } </ span >
188+ ) :(
189+ < span
190+ css = { ( theme ) => ( {
191+ color :theme . palette . error . main ,
192+ } ) }
193+ >
194+ Invalid
195+ </ span >
196+ ) }
197+ </ XAxisRow >
198+ ) ;
199+ } ) ;
192200} ) }
193201</ XAxisSection >
194202) ;