"use client"; import { useState } from "react"; import { ChevronRightIcon } from "@/components/icons"; import type { StepStatus } from "@/lib/runs"; import { RunStatusIcon } from "./run-status"; export type StepView = { index: number; name: string; status: StepStatus; exitCode: number | null; duration: string | null; /** The output's last lines, already cleaned of terminal escapes. */ lines: string[]; /** How many lines before `lines` were left out. */ omitted: number; }; /** * A job's steps, each a row that opens onto its log. Running and failed steps open by themselves (and * follow along as the page refreshes) until the reader opens or closes them by hand. */ export function JobSteps({ steps, rawHref }: { steps: StepView[]; rawHref: string }) { const [toggled, setToggled] = useState>(new Map()); return (
    {steps.map((step) => { const auto = step.status === "in_progress" || step.status === "failure"; const open = toggled.get(step.index) ?? auto; const hasLog = step.lines.length > 0 || step.omitted > 0; return (
  1. {open && (
    {hasLog ? (
                        {step.omitted > 0 && (
                          
    {step.omitted.toLocaleString("en")} earlier lines not shown ยท{" "} view the full log
    )} {step.lines.map((line, i) => (
    {step.omitted + i + 1} {line || " "}
    ))}
    ) : (

    {step.status === "pending" ? "Not started yet." : step.status === "skipped" ? "This step was skipped." : "No output."}

    )}
    )}
  2. ); })}
); }