import { useEffect, useState } from "react"; import { Banner, Pagination, Spin } from "@douyinfe/semi-ui-19"; import { api, displayValue, formatTime } from "../api"; import { WorkspaceTable } from "../components/WorkspaceTable"; import type { Components } from "./types"; /** Component evidence is always read from its own immutable observation. */ export function ComponentsPanel({ url, timezone, }: { url: string; timezone?: string; }) { const [page, setPage] = useState(1); const [data, setData] = useState(); const [error, setError] = useState(""); useEffect(() => { setPage(1); setData(undefined); }, [url]); useEffect(() => { const c = new AbortController(); setError(""); void api( `${url}${url.includes("?") ? "&" : "?"}limit=25&offset=${(page - 1) * 25}`, { signal: c.signal }, ) .then((value) => { if (!c.signal.aborted) setData(value); }) .catch((e: Error) => { if (!c.signal.aborted) setError(e.message); }); return () => c.abort(); }, [url, page]); if (error) return ; if (!data) return ; return (

{data.source === "preview" ? "Selection 预览组件" : "回测实际组件"} ·{" "} {data.complete ? `已核实 ${data.reported_total ?? data.total} 个` : "完整性未核实"}{" "} · 观察时间 {formatTime(data.observed_at, timezone)}

{data.complete && data.total === 0 && ( )} {(data.warnings ?? []).map((w, i) => ( ))}

组件指纹:{data.component_hash ?? "未核实"}

displayValue(r?.value ?? r?.selectionValue ?? r?.selection), }, { title: "可用指标与平台返回字段", width: 730, render: (_, r) => JSON.stringify(r), }, ]} empty="未提供组件" />
); }