({ timings, totalTime }: TimingBarProps)
| 183 | } |
| 184 | |
| 185 | function TimingBar({ timings, totalTime }: TimingBarProps) { |
| 186 | const segments = [ |
| 187 | { name: 'Blocked', value: timings.blocked, color: 'bg-slate-400' }, |
| 188 | { name: 'DNS', value: timings.dns, color: 'bg-cyan-500' }, |
| 189 | { name: 'Connect', value: timings.connect, color: 'bg-orange-500' }, |
| 190 | { name: 'SSL', value: timings.ssl, color: 'bg-purple-500' }, |
| 191 | { name: 'Send', value: timings.send, color: 'bg-blue-500' }, |
| 192 | { name: 'Wait', value: timings.wait, color: 'bg-emerald-500' }, |
| 193 | { name: 'Receive', value: timings.receive, color: 'bg-sky-500' }, |
| 194 | ].filter((s) => s.value > 0); |
| 195 | |
| 196 | if (segments.length === 0 || totalTime <= 0) { |
| 197 | return <div className="text-xs text-muted-foreground">No timing data available</div>; |
| 198 | } |
| 199 | |
| 200 | return ( |
| 201 | <div className="space-y-3"> |
| 202 | <div className="h-6 rounded-md overflow-hidden flex bg-muted"> |
| 203 | {segments.map((segment) => ( |
| 204 | <div |
| 205 | key={segment.name} |
| 206 | className={cn(segment.color, 'h-full relative group')} |
| 207 | style={{ |
| 208 | width: `${(segment.value / totalTime) * 100}%`, |
| 209 | minWidth: segment.value > 0 ? '2px' : 0, |
| 210 | }} |
| 211 | title={`${segment.name}: ${formatDuration(segment.value)}`} |
| 212 | > |
| 213 | <div className="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 bg-black/20 text-white text-[10px] font-medium transition-opacity"> |
| 214 | {segment.name} |
| 215 | </div> |
| 216 | </div> |
| 217 | ))} |
| 218 | </div> |
| 219 | <div className="flex flex-wrap gap-3 text-xs"> |
| 220 | {segments.map((segment) => ( |
| 221 | <div key={segment.name} className="flex items-center gap-1.5"> |
| 222 | <div className={cn('w-2.5 h-2.5 rounded-sm', segment.color)} /> |
| 223 | <span className="text-muted-foreground">{segment.name}:</span> |
| 224 | <span className="font-mono">{formatDuration(segment.value)}</span> |
| 225 | </div> |
| 226 | ))} |
| 227 | </div> |
| 228 | </div> |
| 229 | ); |
| 230 | } |
| 231 | |
| 232 | interface RequestDetailProps { |
| 233 | request: NetworkRequest; |
nothing calls this directly
no test coverage detected