~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
123 lines · 4.0 KB Raw History
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>
  );
}