chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
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 (
<ListRow
Icon={mark.Icon}
iconClassName={mark.className}
title={pull.title}
href={diffHref(repo, pull)}
marks={
<>
{look && (
<span
className={`flex items-center gap-1 ${look.className}`}
title={`${latest.workflow ?? 'ci'} ${look.label}${
staleCheck ? ', on a commit this branch has replaced' : ''
}`}
>
<look.Icon className="size-3.5" />
{staleCheck && <span className="text-faint">stale</span>}
</span>
)}
<ListCount
Icon={CheckIcon}
count={approvals}
className="text-success"
title="Approved"
/>
<ListCount
Icon={XIcon}
count={changesRequested}
className="text-destructive"
title="Changes requested"
/>
<ListCount
Icon={MessageSquareIcon}
count={talk}
className="text-faint"
title="Reviews"
/>
</>
}
>
{/* 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. */}
<span>opened {timeAgo(pull.when)} by</span>
<Handle who={pull.author} className="text-[12.5px]" />
<Dot />
<code className="font-mono text-[12px]">{pull.branch}</code>
{pull.status && (
<>
<Dot />
<span
className="capitalize"
title="The author's own word, from their own record."
>
{pull.status}
</span>
</>
)}
{pull.fork && (
<>
<Dot />
<span title="From an account this repository has not named.">
fork
</span>
</>
)}
</ListRow>
);
}