182 lines · 7.2 KB
import { useEffect, useRef, useState } from "react";
import { getPullMergeFix, startPullMergeFix } from "~/fns/mergefix";
import { useAction } from "~/hooks/use-action";
import { Badge, Panel } from "~/components/ui/Primitives";
import { Button } from "~/components/ui/Button";
import { ErrorBanner } from "~/components/ui/Field";
import { cn } from "~/utils/cn";

type MergeFix = Awaited<ReturnType<typeof getPullMergeFix>>;
type PullParams = { owner: string; repo: string; number: number };

const POLL_MS = 4000;
const ACTIVE = new Set(["queued", "running", "applying"]);

const STATUS_COPY = {
  queued: "Queued",
  running: "Analyzing conflicts",
  applying: "Committing fix",
  applied: "Fix committed",
  suggested: "Suggestions ready",
  failed: "Failed",
} as const;

const REQUEUE_COPY = {
  waiting: "Rejoins the merge queue once CI passes",
  enqueued: "Back in the merge queue",
  gave_up: "Not re-queued",
} as const;

function percent(value: number | undefined): string {
  return `${Math.round((value ?? 0) * 100)}%`;
}

/** Polls the latest run while it is active and reports when it settles. */
function useMergeFix(params: PullParams, initial: MergeFix, onSettled: (fix: MergeFix) => void) {
  const [fix, setFix] = useState(initial);
  const active = fix !== null && ACTIVE.has(fix.status);
  const latest = useRef({ params, onSettled });
  latest.current = { params, onSettled };
  useEffect(() => {