import { SearchIcon } from "lucide-react";
import { memo, type RefCallback } from "react";
import { cn } from "~/lib/utils";
import { getSourceControlPresentationForKind } from "~/sourceControlPresentation";
import { formatRelativeTimeLabel } from "~/timestampFormat";
import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
import { PullRequestChecksPopover } from "./PullRequestChecksPopover";
import { pullRequestLabelColor, type EnvironmentPullRequestEntry } from "./pullRequestList.logic";
import { openOnHostLabel, showPullRequestLinkContextMenu } from "./pullRequestLinkContextMenu";
import {
PullRequestActorLabel,
PullRequestDiffStat,
PullRequestMetaLine,
PullRequestStateGlyph,
} from "./pullRequestPresentation";
function PullRequestRowLabels({ labels }: { labels: EnvironmentPullRequestEntry["labels"] }) {
const label = labels[0];
if (!label) return null;
const dot = pullRequestLabelColor(label.color);
return (
{label.name}
{labels.length > 1 ? +{labels.length - 1} : null}
);
}
function PullRequestRowImpl({
entry,
selected,
showProjectTitle,
showProvider,
environmentLabel,
matchedElsewhere,
statsKey,
statsRef,
onSelect,
}: {
entry: EnvironmentPullRequestEntry;
selected: boolean;
showProjectTitle: boolean;
/** Only when the list spans more than one host, where the repository alone is ambiguous. */
showProvider: boolean;
/** Names the server this row was read from, where the list spans more than one. */
environmentLabel?: string;
/**
* A search found this, but in something the row does not show — a description, a comment, a
* commit message. Saying so is the difference between a result and an apparently random row.
*/
matchedElsewhere?: boolean;
/** Used by the list's shared visibility observer to defer optional line-count reads. */
statsKey?: string;
statsRef?: RefCallback;
onSelect: (entry: EnvironmentPullRequestEntry) => void;
}) {
const { Icon, providerName } = getSourceControlPresentationForKind(entry.provider);
return (
);
}
/**
* Memoized: the list re-renders on every keystroke of a search and every status poll, and a
* row whose entry, selection and match state are unchanged has nothing new to say. Effective
* because the route hands it a stable `onSelect`.
*/
export const PullRequestRow = memo(PullRequestRowImpl);