Initial MVP for QA asset backend
This commit is contained in:
91
hy_qa_asset_backend/frontend/components/SessionTable.tsx
Normal file
91
hy_qa_asset_backend/frontend/components/SessionTable.tsx
Normal file
@@ -0,0 +1,91 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { FileText, Play, RotateCw } from "lucide-react";
|
||||
import { api, formatDateTime } from "@/lib/api";
|
||||
import type { FeishuSession, TaskRun } from "@/lib/types";
|
||||
import StatusBadge from "./StatusBadge";
|
||||
|
||||
export default function SessionTable({ sessions, onChanged }: { sessions: FeishuSession[]; onChanged: () => void }) {
|
||||
async function run(id: number, reprocess = false) {
|
||||
await api.post<TaskRun>(`/sessions/${id}/${reprocess ? "reprocess" : "process"}`, {});
|
||||
onChanged();
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="table-wrap rounded-md border border-line bg-white">
|
||||
<table className="min-w-[1100px] w-full border-collapse text-left text-sm">
|
||||
<thead className="bg-panel text-xs uppercase text-slate-500">
|
||||
<tr>
|
||||
<th className="px-4 py-3">日期</th>
|
||||
<th className="px-4 py-3">标题</th>
|
||||
<th className="px-4 py-3">老师</th>
|
||||
<th className="px-4 py-3">飞书资料</th>
|
||||
<th className="px-4 py-3">状态</th>
|
||||
<th className="px-4 py-3">问答</th>
|
||||
<th className="px-4 py-3">待审</th>
|
||||
<th className="px-4 py-3">入库</th>
|
||||
<th className="px-4 py-3">失败原因</th>
|
||||
<th className="px-4 py-3">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{sessions.map((session) => (
|
||||
<tr key={session.id} className="border-t border-line align-top">
|
||||
<td className="px-4 py-3">{session.date ?? "-"}</td>
|
||||
<td className="px-4 py-3 font-medium text-ink">{session.title}</td>
|
||||
<td className="px-4 py-3">{session.teachers ?? "-"}</td>
|
||||
<td className="px-4 py-3">
|
||||
{session.feishu_doc_url ? (
|
||||
<span className="text-jade">{session.feishu_doc_url}</span>
|
||||
) : (
|
||||
<span className="text-slate-400">-</span>
|
||||
)}
|
||||
</td>
|
||||
<td className="px-4 py-3">
|
||||
<StatusBadge status={session.process_status} />
|
||||
</td>
|
||||
<td className="px-4 py-3">{session.qa_count}</td>
|
||||
<td className="px-4 py-3">{session.pending_review_count}</td>
|
||||
<td className="px-4 py-3">{session.standard_qa_count}</td>
|
||||
<td className="max-w-xs px-4 py-3 text-rose-700">{session.failed_reason ?? "-"}</td>
|
||||
<td className="px-4 py-3">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<Link
|
||||
href={`/sessions/${session.id}`}
|
||||
className="inline-flex h-8 items-center gap-1 rounded-md border border-line px-2 text-xs hover:bg-slate-50"
|
||||
>
|
||||
<FileText className="h-3.5 w-3.5" aria-hidden />
|
||||
详情
|
||||
</Link>
|
||||
<button
|
||||
onClick={() => run(session.id)}
|
||||
className="inline-flex h-8 items-center gap-1 rounded-md border border-line px-2 text-xs hover:bg-slate-50"
|
||||
>
|
||||
<Play className="h-3.5 w-3.5" aria-hidden />
|
||||
处理
|
||||
</button>
|
||||
<button
|
||||
onClick={() => run(session.id, true)}
|
||||
className="inline-flex h-8 items-center gap-1 rounded-md border border-line px-2 text-xs hover:bg-slate-50"
|
||||
>
|
||||
<RotateCw className="h-3.5 w-3.5" aria-hidden />
|
||||
重跑
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
{sessions.length === 0 ? (
|
||||
<tr>
|
||||
<td className="px-4 py-8 text-center text-slate-500" colSpan={10}>
|
||||
暂无场次
|
||||
</td>
|
||||
</tr>
|
||||
) : null}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user