98 lines · 3.7 KB
import { useCallback, useState } from "react";
import { useRouter } from "@tanstack/react-router";
import { useJobLog } from "~/hooks/use-job-log";
import { formatDuration } from "~/lib/format";
import { StatusDot, runState } from "~/ui/StatusDot";
import { cn } from "~/utils/cn";

const ANSI = /\u001b\[[0-9;?]*[A-Za-z]/g;
const SETUP_STEP = -1;

type Step = {
  index: number;
  name: string;
  status: string;
  conclusion: string | null;
  startedAt: number | null;
  completedAt: number | null;
};

export function JobLog({ jobId, steps }: { jobId: string; steps: Step[] }) {
  const router = useRouter();
  const refresh = useCallback(() => {
    router.invalidate();
  }, [router]);
  const log = useJobLog(jobId, refresh);
  const [open, setOpen] = useState<Set<number>>(new Set());

  const sections = [
    {
      index: SETUP_STEP,
      name: "Set up job",
      status: "completed",
      conclusion: null,
      startedAt: null,
      completedAt: null,
    },
    ...steps,
  ];
  const failing = steps.find((step) => step.conclusion === "failure")?.index;
  const isOpen = (index: number) =>