chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
import { useQuery } from '@tanstack/react-query';
import { GitPullRequestIcon } from 'lucide-react';
import { EmptyState } from '#/components/molecules/empty-state.jsx';
import { ListBox } from '#/components/molecules/list-box.jsx';
import { ListSkeleton } from '#/components/molecules/list-skeleton.jsx';
import { PageBar } from '#/components/molecules/page-bar.jsx';
import { PageNotice } from '#/components/molecules/page-notice.jsx';
import { PullCard } from '#/components/molecules/pull-card.jsx';
import { Screen } from '#/components/molecules/screen.jsx';
import { TabBar } from '#/components/molecules/tab-bar.jsx';
import { loadPulls } from '#/lib/collab.js';
import { repoRecord } from '#/lib/git.js';
const empty = [];
/** What each tab holds, and what an empty one says. */
const TABS = [
{ key: 'open', label: 'Open', of: (pulls) => pulls.open },
{ key: 'merged', label: 'Merged', of: (pulls) => pulls.merged },
];
/**
* Every pull request on a repository, gathered from every collaborator's own
* copy of it.
*
* A pull request is a branch in one account's copy, and its state is the
* object graph rather than a field somebody maintains: a branch canonical main
* does not reach is open, one it reaches is merged. So this screen cannot show
* a pull request that was merged last week or miss one somebody pushed a
* minute ago.
*
* One read fills both tabs, so moving between them costs nothing.
*/
export function PullsPage({ repo, tab, space }) {
const record = repoRecord(repo, space);
const { data, error } = useQuery({
queryKey: ['pulls', repo, space ?? ''],
queryFn: () => loadPulls(repo, space),
});
if (!record) {
return <PageNotice>No such repository.</PageNotice>;
}
const active = TABS.some((entry) => entry.key === tab) ? tab : 'open';
const at = `/${encodeURIComponent(repo)}/pulls`;
const shown = data ? TABS.find((entry) => entry.key === active).of(data) : [];
return (
<Screen
bar={
<PageBar tabs>
<TabBar
className="border-b-0"
active={active}
tabs={TABS.map((entry) => ({
key: entry.key,
label: entry.label,
href: entry.key === 'open' ? at : `${at}/${entry.key}`,
count: data ? entry.of(data).length : undefined,
}))}
/>
</PageBar>
}
>
{error && <PageNotice tone="error">{error.message}</PageNotice>}
{!data && !error && (
<ListBox>
<ListSkeleton />
</ListBox>
)}
{data &&
(shown.length === 0 ? (
<ListBox>
<EmptyState
icon={<GitPullRequestIcon />}
title={active === 'open' ? 'Nothing open' : 'Nothing merged'}
description={
active === 'open'
? data.configured
? 'Every branch these collaborators hold is already reachable from main.'
: 'No contributor has opened a pull request against this repository yet.'
: 'No pull request has been merged into main yet.'
}
/>
</ListBox>
) : (
<ListBox>
<div>
{shown.map((pull) => (
<PullCard
key={pull.id}
repo={repo}
pull={pull}
checks={data.checks.get(pull.id) ?? empty}
reviews={data.reviews.get(pull.id) ?? empty}
/>
))}
</div>
</ListBox>
))}
</Screen>
);
}