50 lines
1.8 KiB
React
50 lines
1.8 KiB
React
export default function FailedBanner({ rerunTests, onDecision }) {
|
|
if (!rerunTests || rerunTests.length === 0) return null
|
|
|
|
const totalMinutes = rerunTests.reduce((sum, t) => sum + (t.estimated_minutes ?? 0), 0)
|
|
const hours = Math.floor(totalMinutes / 60)
|
|
const mins = totalMinutes % 60
|
|
const timeStr = hours > 0 ? `${hours}h ${mins}m` : `${mins}m`
|
|
|
|
// Group test IDs by device
|
|
const byDevice = rerunTests.reduce((acc, t) => {
|
|
const device = t.device ?? 'Unknown'
|
|
if (!acc[device]) acc[device] = []
|
|
acc[device].push(t.test_id)
|
|
return acc
|
|
}, {})
|
|
const deviceSummaries = Object.entries(byDevice)
|
|
.sort(([a], [b]) => a.localeCompare(b))
|
|
.map(([device, ids]) => `${device}: ${ids.join(', ')}`)
|
|
|
|
return (
|
|
<div className="flex items-start gap-4 px-6 py-3 bg-yellow-900/35 border-b border-yellow-700/55 text-yellow-100/85">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
className="w-5 h-5 mt-0.5 shrink-0 text-yellow-300/80"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
strokeWidth={2}
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
d="M12 9v4m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"
|
|
/>
|
|
</svg>
|
|
<div className="flex-1 min-w-0">
|
|
<p className="text-sm font-medium">
|
|
<span className="font-semibold">{rerunTests.length} test{rerunTests.length !== 1 ? 's' : ''}</span>
|
|
{' '}require a rerun — not completed in last overnight window:
|
|
</p>
|
|
{deviceSummaries.map((summary) => (
|
|
<p key={summary} className="text-sm font-mono text-yellow-200/80 mt-0.5 truncate">
|
|
{summary}
|
|
</p>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|