diff --git a/packages/git-ui/src/pages/packages.jsx b/packages/git-ui/src/pages/packages.jsx index 6a7c805..97f47f5 100644 --- a/packages/git-ui/src/pages/packages.jsx +++ b/packages/git-ui/src/pages/packages.jsx @@ -3,15 +3,33 @@ import { PackageIcon } from 'lucide-react'; import { Skeleton } from '#/components/atoms/skeleton.jsx'; import { EmptyState } from '#/components/molecules/empty-state.jsx'; import { PackageCard } from '#/components/molecules/package-card.jsx'; +import { TabBar } from '#/components/molecules/tab-bar.jsx'; import { repoRecord } from '#/lib/git.js'; import { loadPackages } from '#/lib/packages.js'; +/** What each tab holds, and what an empty one says. */ +const TABS = [ + { key: '', label: 'All', noun: 'package', plural: 'packages' }, + { key: 'npm', label: 'npm', noun: 'npm package', plural: 'npm packages' }, + { + key: 'oci', + label: 'images', + noun: 'container image', + plural: 'container images', + }, +]; + /** * Everything this repository publishes to the account's own registries, with * the command that installs each one. The account holds the registries, so a * reader installs from the same host that serves this page. + * + * A repository can name many packages, so the page filters by registry. The + * registries there are (npm and oci) stay fixed tabs rather than being read + * from the data, so a tab is a stable address and the "nothing here" line + * tells the two registries apart. */ -export function PackagesPage({ repo }) { +export function PackagesPage({ repo, registry }) { const record = repoRecord(repo); const { data } = useQuery({ queryKey: ['packages', repo], @@ -22,8 +40,29 @@ export function PackagesPage({ repo }) { return
No such repository.
; } + const active = TABS.find((entry) => entry.key === registry) ?? TABS[0]; + const at = `/${encodeURIComponent(repo)}/packages`; + const of = (entry) => + (data ?? []).filter( + (pkg) => entry.key === '' || pkg.registry === entry.key, + ); + const shown = data ? of(active) : []; + return ( - <> +