Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
74 lines
3.4 KiB
TypeScript
74 lines
3.4 KiB
TypeScript
import type { EpisodeMappingPreviewItem } from "@umt/contracts";
|
|
import { ArrowRight } from "lucide-react";
|
|
import { StatusBadge } from "~/components/console/status-badge.tsx";
|
|
import { cn, formatDateTime } from "~/lib/utils.ts";
|
|
import { canonicalText, methodText, sourceText, VALIDATION } from "./model.ts";
|
|
|
|
// 模拟预览表格:原始季集 → 当前结果 → 套用草稿后的结果、方式、校验;与当前不同的行高亮并标「有变化」。
|
|
|
|
export function PreviewTable({
|
|
items,
|
|
hasDraft,
|
|
empty = "这部作品还没有绑定的资源。",
|
|
}: {
|
|
items: EpisodeMappingPreviewItem[];
|
|
/** 有草稿时列名写「套用后」,否则写「重算」 */
|
|
hasDraft: boolean;
|
|
empty?: string;
|
|
}) {
|
|
if (!items.length) return <p className="px-4 py-6 text-caption text-muted-foreground sm:px-5">{empty}</p>;
|
|
return (
|
|
<div className="overflow-x-auto">
|
|
<table className="w-full min-w-[44rem] text-caption">
|
|
<thead>
|
|
<tr className="border-b border-border/60 text-left text-meta text-muted-foreground">
|
|
<th className="px-4 py-2 font-medium">资源</th>
|
|
<th className="px-3 py-2 font-medium">原始</th>
|
|
<th className="px-3 py-2 font-medium">当前</th>
|
|
<th className="px-3 py-2 font-medium">{hasDraft ? "套用后" : "重算"}</th>
|
|
<th className="px-3 py-2 font-medium">方式</th>
|
|
<th className="px-4 py-2 font-medium">校验</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{items.map((it) => {
|
|
const v = VALIDATION[it.validation];
|
|
return (
|
|
<tr
|
|
key={it.sourceReleaseId}
|
|
data-changed={it.changed || undefined}
|
|
className={cn("border-b border-border/60 last:border-b-0", it.changed && "bg-foreground/[0.04]")}
|
|
>
|
|
<td className="max-w-[22rem] px-4 py-2 align-top">
|
|
<div className="font-mono text-meta break-all text-foreground">{it.title}</div>
|
|
<div className="mt-0.5 text-meta text-muted-foreground">
|
|
{[it.releaseGroup, formatDateTime(it.publishedAt)].filter(Boolean).join(" · ")}
|
|
</div>
|
|
</td>
|
|
<td className="px-3 py-2 align-top font-mono tabular-nums">{sourceText(it.preview)}</td>
|
|
<td className="px-3 py-2 align-top">
|
|
<div className="font-mono tabular-nums">{canonicalText(it.current)}</div>
|
|
<div className="text-meta text-muted-foreground">{methodText(it.current)}</div>
|
|
</td>
|
|
<td className="px-3 py-2 align-top">
|
|
<div className="inline-flex items-center gap-1 font-mono tabular-nums">
|
|
{it.changed ? <ArrowRight aria-hidden className="h-3 w-3 text-muted-foreground" /> : null}
|
|
<span className={cn(it.changed && "font-semibold text-foreground")}>
|
|
{canonicalText(it.preview)}
|
|
</span>
|
|
</div>
|
|
{it.changed ? <div className="text-meta text-muted-foreground">有变化</div> : null}
|
|
</td>
|
|
<td className="px-3 py-2 align-top">{methodText(it.preview)}</td>
|
|
<td className="px-4 py-2 align-top">
|
|
<StatusBadge tone={v.tone}>{v.label}</StatusBadge>
|
|
</td>
|
|
</tr>
|
|
);
|
|
})}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
);
|
|
}
|