feat: add Super Alpha research, management and MCP workflows
Deploy production / deploy (push) Successful in 56s
Deploy production / deploy (push) Successful in 56s
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
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<Components>();
|
||||
const [error, setError] = useState("");
|
||||
useEffect(() => {
|
||||
setPage(1);
|
||||
setData(undefined);
|
||||
}, [url]);
|
||||
useEffect(() => {
|
||||
const c = new AbortController();
|
||||
setError("");
|
||||
void api<Components>(
|
||||
`${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 <Banner type="danger" description={error} />;
|
||||
if (!data) return <Spin />;
|
||||
return (
|
||||
<section className="super-components">
|
||||
<p>
|
||||
{data.source === "preview" ? "Selection 预览组件" : "回测实际组件"} ·{" "}
|
||||
{data.complete
|
||||
? `已核实 ${data.reported_total ?? data.total} 个`
|
||||
: "完整性未核实"}{" "}
|
||||
· 观察时间 {formatTime(data.observed_at, timezone)}
|
||||
</p>
|
||||
{data.complete && data.total === 0 && (
|
||||
<Banner
|
||||
type="warning"
|
||||
description="组件池为空,回测可能无法产生结果。请调整 Selection。"
|
||||
/>
|
||||
)}
|
||||
{(data.warnings ?? []).map((w, i) => (
|
||||
<Banner key={i} type="warning" description={displayValue(w)} />
|
||||
))}
|
||||
<p className="muted">组件指纹:{data.component_hash ?? "未核实"}</p>
|
||||
<WorkspaceTable
|
||||
rowKey="id"
|
||||
dataSource={data.items}
|
||||
scroll={{ x: 1100, y: 320 }}
|
||||
columns={[
|
||||
{ title: "组件 ID", dataIndex: "id", width: 190 },
|
||||
{
|
||||
title: "平台选择值",
|
||||
width: 180,
|
||||
render: (_, r) =>
|
||||
displayValue(r?.value ?? r?.selectionValue ?? r?.selection),
|
||||
},
|
||||
{
|
||||
title: "可用指标与平台返回字段",
|
||||
width: 730,
|
||||
render: (_, r) => JSON.stringify(r),
|
||||
},
|
||||
]}
|
||||
empty="未提供组件"
|
||||
/>
|
||||
<footer className="workspace-table-footer super-toolbar">
|
||||
<span>已保存 {data.total} 条</span>
|
||||
<Pagination
|
||||
total={data.total}
|
||||
currentPage={page}
|
||||
pageSize={25}
|
||||
onPageChange={setPage}
|
||||
/>
|
||||
</footer>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user