Files
wasmeld/crates/wasmeld-console/web/src/pages/wit-packages/index.tsx
T

115 lines
3.9 KiB
TypeScript
Raw Normal View History

import { CloudUpload, Download, FileCode2, Search } from "lucide-solid";
import { createMemo, For, Show } from "solid-js";
import { EmptyState } from "../../components/feedback/empty-state";
import { Page } from "../../components/layout/page";
import { PageHeading } from "../../components/layout/page-heading";
import { Button, IconLink } from "../../components/ui/button";
import { Card, CardHeader } from "../../components/ui/card";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "../../components/ui/table";
import { witPackageDownloadUrl } from "../../lib/api";
import type { PageProps } from "../types";
export default function WitPackagesPage(props: PageProps) {
const packages = createMemo(() => {
const state = props.state();
const query = state?.query.trim().toLowerCase() ?? "";
return (
state?.snapshot?.witPackages.filter(
(item) =>
!query ||
item.name.toLowerCase().includes(query) ||
item.version.toLowerCase().includes(query) ||
item.sha256.toLowerCase().includes(query),
) ?? []
);
});
return (
<Page>
<PageHeading
eyebrow="INTERFACES"
title="WIT 包"
description="管理不可变、版本化的 Component 接口依赖。"
actions={
<Button variant="primary" onClick={() => props.command({ type: "open-wit-publish" })}>
<CloudUpload size={16} />
发布 WIT
</Button>
}
/>
<Card as="section">
<CardHeader>
<div>
<h2>Registry</h2>
<p>{packages().length} 个匹配包版本</p>
</div>
</CardHeader>
<Show
when={packages().length > 0}
fallback={
<EmptyState icon={Search} title="没有匹配的 WIT 包" detail="发布或调整搜索关键词。" />
}
>
<Table>
<TableHeader>
<TableRow>
<TableHead></TableHead>
<TableHead>版本</TableHead>
<TableHead>直接依赖</TableHead>
<TableHead>SHA-256</TableHead>
<TableHead>
<span class="sr-only">下载</span>
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<For each={packages()}>
{(item) => (
<TableRow>
<TableCell>
<span class="flex items-center gap-2">
<FileCode2 size={15} class="text-cyan-strong" />
<strong>{item.name}</strong>
</span>
</TableCell>
<TableCell class="font-mono text-xs">{item.version}</TableCell>
<TableCell class="text-xs text-muted">
{item.dependencies.length
? item.dependencies
.map((dependency) => `${dependency.name}@${dependency.version}`)
.join(", ")
: "无"}
</TableCell>
<TableCell
class="max-w-64 truncate font-mono text-xs text-muted"
title={item.sha256}
>
{item.sha256}
</TableCell>
<TableCell class="text-right">
<IconLink
aria-label={`下载 ${item.name}@${item.version}`}
title="下载"
href={witPackageDownloadUrl(props.state()?.apiBase ?? "", item)}
>
<Download size={15} />
</IconLink>
</TableCell>
</TableRow>
)}
</For>
</TableBody>
</Table>
</Show>
</Card>
</Page>
);
}