import { CheckIcon, GitMergeIcon, GitPullRequestClosedIcon, GitPullRequestDraftIcon, GitPullRequestIcon, MessageSquareIcon, XIcon, } from 'lucide-react'; import { Handle } from '#/components/molecules/handle.jsx'; import { Dot, ListCount, ListRow } from '#/components/molecules/list-row.jsx'; import { checkLook } from '#/lib/checks.js'; import { diffHref } from '#/lib/collab.js'; import { threadSummaries } from '#/lib/comments.js'; import { timeAgo } from '#/lib/format.js'; /** The mark at the head of a row, which is the state before the words are. */ const MARKS = { open: { Icon: GitPullRequestIcon, className: 'text-success' }, merged: { Icon: GitMergeIcon, className: 'text-key' }, draft: { Icon: GitPullRequestDraftIcon, className: 'text-faint' }, withdrawn: { Icon: GitPullRequestClosedIcon, className: 'text-destructive' }, }; /** * One pull request, as a row: a branch in one account's own copy. Open and * merged read the same, because they are the same thing at two moments, and * the mark at the head says which. * * Every number is read from the object graph rather than from a stored state, * so there is nothing to fall out of date. Whether a check is stale is the * exception: a force-push leaves a sha nothing points at, and what remembers * it is the runner's push log and the statements written against it. */ export function PullCard({ repo, pull, checks, reviews }) { const latest = checks[0]; const look = latest ? checkLook(latest.status) : null; const staleCheck = latest && latest.sha !== pull.sha; const threads = threadSummaries(reviews); const approvals = threads.filter((t) => t.root.verdict === 'approve').length; const changesRequested = threads.filter( (t) => t.root.verdict === 'changesRequested', ).length; const talk = threads.length - approvals - changesRequested; const mark = MARKS[ pull.merged ? 'merged' : pull.status === 'draft' || pull.status === 'withdrawn' ? pull.status : 'open' ]; return ( {look && ( {staleCheck && stale} )} } > {/* Who, which branch, and when. The branch is the number a forge would show, because it is what addresses the pull request here. The counts, the drift and whether it merges read on the page the title opens, not on every row. */} opened {timeAgo(pull.when)} by {pull.branch} {pull.status && ( <> {pull.status} )} {pull.fork && ( <> fork )} ); }