NamespaceView

tcmts.share.NamespaceView · #fm3cjg7z · term · runs on the server

is an async component

A namespace: where it is, the namespaces in it (a list, each with its size, description and where its code runs), its definitions by what they're for, its README.

import { ROLES } from "#codebase/tcmts/cli/pages";
import {
  ago, childrenOf, codeHref, Crumbs, DefRow, Frame, Html, inSlices, leafOf, markdownHtml, namesNow, namespaceSummary,
  pageOf, PlaceBar, placeMix, ProjectSide, roleNow, shareNow,
} from "#codebase/tcmts/share";

export async function NamespaceView({ ns }: { ns: string }) {
  const s = shareNow();
  const rows = namesNow(s);
  const { namespaces, defs } = childrenOf(rows, ns);
  const all = rows.filter((r) => r.path.startsWith(`${ns}.`));
  const readme = defs.find((r) => leafOf(r.path) === "README" && r.kind === "file");
  const readmePage = readme && pageOf(s, readme.hash);
  await inSlices(defs.map((r) => () => roleNow(s, r)));
  // (where each namespace's code runs: its row's bar)
  await inSlices(namespaces.map((n) => () => placeMix(s, n.rows, n.name)));
  const subs = [...namespaces].sort((a, b) => (a.name < b.name ? -1 : 1));
  const groups = ROLES.map(([role, label]) => ({
    label,
    defs: defs.filter((r) => r !== readme && roleNow(s, r) === role),
  })).filter((g) => g.defs.length);
  const latest = s.cache
    .atHead(s.cb, "history", () => s.cb.store.history(400))
    .filter((e) => e.path.startsWith(`${ns}.`))
    .sort((a, b) => b.ts - a.ts)[0];
  return (
    <Frame tab="code" title={ns}>
      <div className="page cols-2">
        <div>
          <div className="filters">
            <span style={{ fontSize: 17 }}>
              <Crumbs name={ns} />
            </span>
            <span className="right muted">
              {all.length} definitions{latest ? ` · changed ${ago(latest.ts)}` : ""}
            </span>
          </div>
          {subs.length > 0 && (
            <div className="box">
              <div className="boxhead">
                <b>Namespaces</b>
                <span className="muted">{subs.length}</span>
              </div>
              {subs.map((n) => {
                const about = namespaceSummary(s, rows, n.name);
                return (
                  <div className="nsrow" key={n.name}>
                    <a className="mono" href={codeHref(n.name)}>
                      {leafOf(n.name)}
                    </a>
                    <span className="sig">{`${n.rows.length.toLocaleString("en")} definition${n.rows.length === 1 ? "" : "s"}`}</span>
                    <PlaceBar mix={placeMix(s, n.rows, n.name)} />
                    {about && <span className="doc">{about}</span>}
                  </div>
                );
              })}
            </div>
          )}
          {groups.map((g) => (
            <div className="box" key={g.label}>
              <div className="boxhead">
                <b>{g.label}</b>
                <span className="muted">{g.defs.length}</span>
              </div>
              {g.defs.map((r) => (
                <DefRow key={r.path} row={r} />
              ))}
            </div>
          ))}
          {!groups.length && !namespaces.length && <div className="empty">Nothing here.</div>}
          {readmePage?.docMarkdown && (
            <div className="box">
              <div className="boxhead">
                <b>README</b>
              </div>
              <Html className="boxbody md" html={markdownHtml(s.cb, readmePage.docMarkdown)} />
            </div>
          )}
        </div>
        <ProjectSide />
      </div>
    </Frame>
  );
}

uses

used by