feat(console-web): replace TanStack UI with Solid host pages
- move the management frontend under the wasmeld-console crate - use a persistent Host shell with disposable iframe page documents - version Host/Page postMessage state and command contracts - migrate runtime, service, WIT, invocation, and settings workflows - add Tailwind CSS v4, responsive layouts, and Host-owned dialogs - emit a dependency-free PWA worker with API cache exclusions - remove the superseded root TanStack Start application
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
import { CloudUpload, Download, FileCode2, Search } from "lucide-solid";
|
||||
import { createMemo, For, Show } from "solid-js";
|
||||
import { EmptyState } from "../../components/ui/empty-state";
|
||||
import { PageHeading } from "../../components/ui/page-heading";
|
||||
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 (
|
||||
<main class="page">
|
||||
<PageHeading
|
||||
eyebrow="INTERFACES"
|
||||
title="WIT 包"
|
||||
description="管理不可变、版本化的 Component 接口依赖。"
|
||||
actions={
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
onClick={() => props.command({ type: "open-wit-publish" })}
|
||||
>
|
||||
<CloudUpload size={16} />
|
||||
发布 WIT 包
|
||||
</button>
|
||||
}
|
||||
/>
|
||||
<section class="panel">
|
||||
<div class="panel-header">
|
||||
<div>
|
||||
<h2>Registry</h2>
|
||||
<p>{packages().length} 个匹配包版本</p>
|
||||
</div>
|
||||
</div>
|
||||
<Show
|
||||
when={packages().length > 0}
|
||||
fallback={
|
||||
<EmptyState icon={Search} title="没有匹配的 WIT 包" detail="发布或调整搜索关键词。" />
|
||||
}
|
||||
>
|
||||
<div class="table-wrap">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>包</th>
|
||||
<th>版本</th>
|
||||
<th>直接依赖</th>
|
||||
<th>SHA-256</th>
|
||||
<th>
|
||||
<span class="sr-only">下载</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<For each={packages()}>
|
||||
{(item) => (
|
||||
<tr>
|
||||
<td>
|
||||
<span class="flex items-center gap-2">
|
||||
<FileCode2 size={15} class="text-cyan-strong" />
|
||||
<strong>{item.name}</strong>
|
||||
</span>
|
||||
</td>
|
||||
<td class="code">{item.version}</td>
|
||||
<td class="text-xs text-muted">
|
||||
{item.dependencies.length
|
||||
? item.dependencies
|
||||
.map((dependency) => `${dependency.name}@${dependency.version}`)
|
||||
.join(", ")
|
||||
: "无"}
|
||||
</td>
|
||||
<td class="code max-w-64 truncate text-muted" title={item.sha256}>
|
||||
{item.sha256}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<a
|
||||
class="icon-btn"
|
||||
title="下载"
|
||||
href={witPackageDownloadUrl(props.state()?.apiBase ?? "", item)}
|
||||
>
|
||||
<Download size={15} />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</For>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</Show>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user