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

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
108 lines · 3.2 KB Raw History
import { useQuery } from '@tanstack/react-query';
import { CircleCheckIcon } from 'lucide-react';
import { useState } from 'react';
import { CheckFilter } from '#/components/molecules/check-filter.jsx';
import { CheckGroup } from '#/components/molecules/check-group.jsx';
import { EmptyState } from '#/components/molecules/empty-state.jsx';
import { ListSkeleton } from '#/components/molecules/list-skeleton.jsx';
import { PageNotice } from '#/components/molecules/page-notice.jsx';
import { Screen } from '#/components/molecules/screen.jsx';
import {
  groupBySha,
  loadChecks,
  workflowNames,
  workflowOf,
} from '#/lib/checks.js';
import { commitLabels, repoRecord } from '#/lib/git.js';

/**
 * Every run the repository's runner published, newest first, grouped by the
 * commit it ran against. One commit's group holds a line per workflow, and a
 * second line for a workflow someone asked for again.
 */
export function ChecksPage({ repo, space }) {
  const record = repoRecord(repo, space);
  const [workflow, setWorkflow] = useState('');
  const { data } = useQuery({
    queryKey: ['checks', repo, space ?? ''],
    queryFn: () => loadChecks(repo, space),
  });

  // What each commit is called. This opens the repository, which costs the
  // bundle download the run listing itself never needs, so it runs behind the
  // paint: the groups render under their shas and take their subjects here.
  const refs = [
    ...new Set((data?.runs ?? []).map((run) => run.ref).filter(Boolean)),
  ];
  const { data: labels } = useQuery({
    queryKey: ['commit-labels', repo, refs, space ?? ''],
    enabled: refs.length > 0,
    queryFn: () =>
      commitLabels(repo, /** @type {string[]} */ (refs), 100, space),
    staleTime: Number.POSITIVE_INFINITY,
  });

  if (!record) {
    return <PageNotice>No such repository.</PageNotice>;
  }

  const all = data?.runs ?? [];
  const runs = all.filter((run) => !workflow || workflowOf(run) === workflow);
  const counts = {};
  for (const run of all) {
    counts[workflowOf(run)] = (counts[workflowOf(run)] ?? 0) + 1;
  }

  if (!data) {
    return (
      <Screen>
        <ListSkeleton />
      </Screen>
    );
  }

  if (all.length === 0) {
    return (
      <Screen>
        <EmptyState
          icon={<CircleCheckIcon />}
          title="No checks"
          description={
            data.runner
              ? "The repository's runner has published no results yet."
              : 'This repository names no check runner.'
          }
        />
      </Screen>
    );
  }

  return (
    <Screen>
      <div className="flex flex-col md:flex-row">
        {workflowNames(all).length > 1 && (
          <CheckFilter
            workflows={workflowNames(all)}
            counts={counts}
            total={all.length}
            value={workflow}
            onSelect={setWorkflow}
          />
        )}

        <div className="min-w-0 flex-1">
          <ul className="flex flex-col gap-3 px-(--gutter) py-4">
            {groupBySha(runs).map((group) => (
              <CheckGroup
                key={group.sha}
                repo={repo}
                group={group}
                label={labels?.get(group.sha)}
              />
            ))}
          </ul>
        </div>
      </div>
    </Screen>
  );
}