feat: 支持研究素材删除并统一 Semi 表格

This commit is contained in:
yuxuanhui
2026-09-11 23:21:08 +08:00
parent f29063c9a2
commit 8eec12f0e0
26 changed files with 1008 additions and 562 deletions
+75 -58
View File
@@ -1,5 +1,5 @@
import { useEffect, useState } from "react";
import { Banner, Button, Input, Toast } from "@douyinfe/semi-ui-19";
import { Banner, Button, Input, Table, Toast } from "@douyinfe/semi-ui-19";
import { api, formatTime, post } from "../api";
import "./mcp-keys.css";
@@ -247,71 +247,88 @@ export function MCPKeysPage() {
已创建的 Key <span className="mcp-key-count">{data?.total ?? 0}</span>
</h2>
<div className="mcp-key-table">
<table>
<thead>
<tr>
<th>名称</th>
<th>权限</th>
<th>状态</th>
<th>创建时间</th>
<th>到期时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{data?.items.map((item) => (
<tr key={item.id}>
<td>
<Table<Token>
dataSource={data?.items ?? []}
rowKey="id"
pagination={false}
size="small"
style={{ minWidth: 1040 }}
loading={loading}
empty="暂无 MCP Key。"
columns={[
{
title: "名称",
key: "name",
width: 240,
render: (_, item) => (
<>
<strong>{item.name}</strong>
<small>{item.id}</small>
</td>
<td>
{item.scopes.map((scope) => (
<small key={scope}>
{scopes.find(([value]) => value === scope)?.[1] ??
scope}
</small>
))}
</td>
<td>{labels[item.status]}</td>
<td>{formatTime(item.created_at)}</td>
<td>{formatTime(item.expires_at)}</td>
<td>
{item.revoked_at ? (
"—"
) : revoking === item.id ? (
<div>
<p>撤销后新请求立即失效,已受理回测继续执行。</p>
<Button
type="danger"
disabled={busy}
onClick={() => void revoke(item.id)}
>
确认撤销
</Button>
<Button
disabled={busy}
onClick={() => setRevoking(null)}
>
取消
</Button>
</div>
) : (
</>
),
},
{
title: "权限",
key: "scopes",
width: 200,
render: (_, item) =>
item.scopes.map((scope) => (
<small key={scope}>
{scopes.find(([value]) => value === scope)?.[1] ?? scope}
</small>
)),
},
{
title: "状态",
key: "status",
width: 100,
render: (_, item) => labels[item.status],
},
{
title: "创建时间",
key: "created_at",
width: 180,
render: (_, item) => formatTime(item.created_at),
},
{
title: "到期时间",
key: "expires_at",
width: 180,
render: (_, item) => formatTime(item.expires_at),
},
{
title: "操作",
key: "actions",
render: (_, item) =>
item.revoked_at ? (
"—"
) : revoking === item.id ? (
<div>
<p>撤销后新请求立即失效,已受理回测继续执行。</p>
<Button
type="danger"
disabled={busy}
onClick={() => setRevoking(item.id)}
onClick={() => void revoke(item.id)}
>
撤销
确认撤销
</Button>
)}
</td>
</tr>
))}
</tbody>
</table>
<Button disabled={busy} onClick={() => setRevoking(null)}>
取消
</Button>
</div>
) : (
<Button
type="danger"
disabled={busy}
onClick={() => setRevoking(item.id)}
>
撤销
</Button>
),
},
]}
/>
</div>
{!loading && !data?.items.length && <p>暂无 MCP Key。</p>}
<div className="mcp-key-actions">
<Button
disabled={offset === 0 || loading || busy}