From 5cdf5e4c1dffac011de35ed69d6af26a0e8dd0e8 Mon Sep 17 00:00:00 2001 From: xmanrui <841206367@qq.com> Date: Tue, 3 Mar 2026 01:04:09 +0800 Subject: [PATCH] feat: add copy action to error status popovers --- app/page.tsx | 79 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 4 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 8f72dba..528a51b 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -83,6 +83,74 @@ function formatMs(ms: number): string { return (ms / 1000).toFixed(1) + "s"; } +async function copyText(text: string): Promise { + try { + if (navigator.clipboard?.writeText) { + await navigator.clipboard.writeText(text); + return true; + } + } catch { + // Fallback below + } + + try { + const textarea = document.createElement("textarea"); + textarea.value = text; + textarea.setAttribute("readonly", ""); + textarea.style.position = "fixed"; + textarea.style.opacity = "0"; + document.body.appendChild(textarea); + textarea.select(); + const ok = document.execCommand("copy"); + document.body.removeChild(textarea); + return ok; + } catch { + return false; + } +} + +function ErrorStatusWithCopy({ error, className }: { error?: string; className?: string }) { + const [copyState, setCopyState] = useState<"idle" | "copied" | "failed">("idle"); + const errorText = (error || "Unknown error").trim() || "Unknown error"; + + const onCopy = async (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + const ok = await copyText(errorText); + setCopyState(ok ? "copied" : "failed"); + }; + + return ( + setCopyState("idle")} + > + + + ); +} + // 趋势折线图 function TrendChart({ data, lines, height = 180, t }: { data: DayStat[]; lines: { key: keyof DayStat; color: string; label: string }[]; height?: number; t: TFunc }) { if (data.length === 0) return
{t("common.noData")}
; @@ -264,7 +332,7 @@ function PlatformBadge({ platform, agentId, gatewayPort, gatewayToken, gatewayHo ) : testResult.ok ? ( ) : ( - + )} ); @@ -403,7 +471,7 @@ function AgentCard({ agent, gatewayPort, gatewayToken, gatewayHost, t, testResul ) : sessionTestResult.ok ? ( ) : ( - + )} @@ -418,7 +486,7 @@ function AgentCard({ agent, gatewayPort, gatewayToken, gatewayHost, t, testResul ) : testResult.ok ? ( ) : ( - + )} @@ -442,7 +510,10 @@ function AgentCard({ agent, gatewayPort, gatewayToken, gatewayHost, t, testResul ) : dmResult.ok ? ( DM Session: ✅ ) : ( - DM Session: ❌ + + DM Session: + + )}