ReleasesIndexPage

tcmts.studio.ReleasesIndexPage · #xbqoqwhr · term · runs on the server

is an async component

Every package the codebase has, each a link to its own page (releaseHref): its latest release and when, and whether a release waits (something under its namespace changed since its latest), not worked out further here (its page says what version, and why); those waiting first, then those up to date, then those never released, the codebase's own first among its kind. q narrows them to names and descriptions with it.

import { publishingList, unchangedSince } from "#codebase/tcmts/cli/release_pages";
import { ago, at, Html, markdownHtml, projectNow, shareNow } from "#codebase/tcmts/share";
import { releaseHref, StudioFrame, studioShare } from "#codebase/tcmts/studio";

export async function ReleasesIndexPage({ q }: { q: string }) {
  studioShare();
  const s = shareNow();
  if (!s.signedIn)
    return (
      <StudioFrame tab="releases" title="Sign in">
        {null}
      </StudioFrame>
    );
  const own = projectNow(s).name;
  const words = q.trim().toLowerCase();
  const all = publishingList(s.cb).map((p) => {
    const latest = s.cb.store.releases(p.name)[0];
    const state: "waits" | "current" | "new" = !latest
      ? "new"
      : unchangedSince(s.cb, latest.causal, p.namespace)
        ? "current"
        : "waits";
    return { ...p, state };
  });
  const order = { waits: 0, current: 1, new: 2 };
  const shown = all
    .filter((p) => !words || `${p.name} ${p.description ?? ""}`.toLowerCase().includes(words))
    .sort(
      (a, b) =>
        order[a.state] - order[b.state] ||
        Number(b.name === own) - Number(a.name === own) ||
        a.name.localeCompare(b.name),
    );
  const waiting = all.filter((p) => p.state === "waits").length;
  return (
    <StudioFrame tab="releases" title="Releases">
      <div className="pagehead">
        <h2 className="title">Releases</h2>
        <span className="muted">
          {all.length} package{all.length === 1 ? "" : "s"}
          {waiting ? `, ${waiting} with changes since their latest release` : ""}
        </span>
        {all.length > 6 && (
          <form className="right" action={at("/releases")} method="get">
            <input
              className="field"
              type="search"
              name="q"
              defaultValue={q}
              placeholder="Find a package"
              aria-label="Find a package"
              style={{ height: 30 }}
            />
          </form>
        )}
      </div>
      {!all.length ? (
        <div className="box">
          <div className="empty">
            No packages yet: a <code>manifest</code> says what one holds (
            <a href="https://tcm.codes/docs/publishing.html">publishing</a>).
          </div>
        </div>
      ) : (
        <div className="box">
          {shown.map((p) => (
            <a className="lib relrow" key={p.name} href={releaseHref(p.name)}>
              <div>
                <span className="name mono">{p.name}</span>{" "}
                <span className="muted mono" style={{ fontSize: 12.5 }}>
                  {p.namespace}
                </span>
                {p.description && (
                  <Html
                    className="desc md"
                    html={markdownHtml(s.cb, p.description.split("\n")[0]!)}
                  />
                )}
              </div>
              <div className="stat">
                {p.latest ? (
                  <>
                    <b className="mono">{p.latest.version}</b>
                    {ago(p.latest.ts)}
                  </>
                ) : (
                  <span className="muted">not released</span>
                )}
              </div>
              <div className="meta">
                {p.state === "waits" ? (
                  <span className="warn">changed since {p.latest?.version}: a release waits</span>
                ) : p.state === "current" ? (
                  <span className="ok">up to date</span>
                ) : (
                  <span>its first release would be 0.1.0</span>
                )}
                <span>
                  {p.releases} release{p.releases === 1 ? "" : "s"}
                </span>
              </div>
            </a>
          ))}
          {!shown.length && (
            <div className="empty">No package has “{q}” in its name or description.</div>
          )}
        </div>
      )}
    </StudioFrame>
  );
}

uses

used by