| 1 | using AgentForge.Plugin.Ci.Contracts; |
| 2 | using AgentForge.Plugin.View; |
| 3 | |
| 4 | namespace AgentForge.Plugin.Ci.Pages; |
| 5 | |
| 6 | internal static class ForgeCiRunTimelinePage |
| 7 | { |
| 8 | internal static string Render(string repoName, CiRunDetailResponse run) |
| 9 | { |
| 10 | var parts = new List<string> |
| 11 | { |
| 12 | ForgeHtml.H2($"Run {run.Id[..Math.Min(8, run.Id.Length)]} · {run.DefinitionName}"), |
| 13 | ForgeHtml.P("meta", ForgeHtml.Text($"ref {run.Ref} · status {run.Status} · queued by {run.QueuedBy}")), |
| 14 | }; |
| 15 | |
| 16 | var stepItems = new List<string>(run.Steps.Count); |
| 17 | foreach (var step in run.Steps) |
| 18 | { |
| 19 | var log = string.IsNullOrWhiteSpace(step.LogText) |
| 20 | ? "" |
| 21 | : ForgeHtml.Pre("ci-log", step.LogText); |
| 22 | stepItems.Add(ForgeHtml.Li(null, |
| 23 | ForgeHtml.Strong($"{step.DisplayName} ({step.TaskId})"), |
| 24 | ForgeHtml.Text(" — "), |
| 25 | ForgeHtml.Span($"ci-step-{step.Status}", ForgeHtml.Text(step.Status)), |
| 26 | log)); |
| 27 | } |
| 28 | |
| 29 | parts.Add(ForgeHtml.Ul("ci-timeline", [.. stepItems])); |
| 30 | parts.Add(ForgeHtml.P(null, ForgeHtml.ARaw( |
| 31 | $"/view/repos/{ForgeRepoNames.ToUrlPath(repoName)}/ci", |
| 32 | ForgeHtml.Text("← Pipelines")))); |
| 33 | |
| 34 | return ForgeHtml.Fragment([.. parts]); |
| 35 | } |
| 36 | } |
| 37 | |