import { FileCheck2, RotateCw } from "lucide-react"; import { useCallback, useEffect, useState } from "react"; import { platformApiClient } from "../api/client"; import type { AIConfigDiffPreviewResponse } from "../api/types"; import { ConfirmDialog } from "./OperationControls"; import { ErrorState, LoadingState, ResultBadge } from "./StateViews"; export function AIConfigDiffReviewPanel() { const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const [selected, setSelected] = useState(null); const [busyId, setBusyId] = useState(""); const [result, setResult] = useState<{ status: "succeeded" | "failed"; label: string } | null>(null); const refresh = useCallback(async () => { setLoading(true); setError(""); try { const response = await platformApiClient.listAIConfigDiffs(); setItems(response.items); } catch (caught) { setError(caught instanceof Error ? caught.message : "AI 配置审查队列加载失败"); } finally { setLoading(false); } }, []); useEffect(() => { void refresh(); }, [refresh]); async function approve() { if (!selected || busyId) return; setBusyId(selected.id); setResult(null); try { const response = await platformApiClient.approveAIConfigDiff(selected.id, `web:ai.config.approve:${selected.id}`); setResult({ status: "succeeded", label: `已审批 ${response.preview.id} · 写入任务 ${response.dispatch.job.id}` }); setSelected(null); await refresh(); } catch (caught) { setResult({ status: "failed", label: caught instanceof Error ? caught.message : "AI 配置审批失败" }); setSelected(null); } finally { setBusyId(""); } } return (

AI 配置审查

{result && } {loading && } {!loading && error && void refresh()} compact />} {!loading && !error && (
{items.length === 0 &&

当前没有 AI 配置差异。

} {items.slice(0, 12).map((item) => (
{item.serverInstanceId} · {item.key}{item.state}
请求 {item.requestId}版本 {item.configVersion}{item.model || "Platform model"}到期 {new Date(item.expiresAt).toLocaleString()}{item.jobId && 任务 {item.jobId}}

{item.diffSummary}

{item.proposedConfig &&
{item.proposedConfig}
} {item.state === "pending" &&
}
))}
)} { if (!busyId) setSelected(null); }} onConfirm={() => void approve()} />
); }