40 lines
2.7 KiB
TypeScript
40 lines
2.7 KiB
TypeScript
import { Mail } from "lucide-react";
|
|
import { Disclosure } from "@/shared/ui/disclosure";
|
|
import { Button } from "@/shared/ui/button";
|
|
import type { AgentMailboxMessage } from "../api/agent-messages";
|
|
|
|
const messageStatusLabels = { pending: "待接收", enqueued: "已排队", delivered: "已投递", failed: "投递失败" };
|
|
|
|
export function AgentMessageInbox({ messages, loading, error, hasMore, loadingMore, onLoadMore, onRefresh }: {
|
|
messages: AgentMailboxMessage[];
|
|
loading?: boolean;
|
|
error?: string | null;
|
|
hasMore?: boolean;
|
|
loadingMore?: boolean;
|
|
onLoadMore?: () => Promise<void>;
|
|
onRefresh?: () => void;
|
|
}) {
|
|
if (!messages.length && !loading && !error) return null;
|
|
const received = messages.filter((message) => message.direction === "to_chat").length;
|
|
return <Disclosure label={<span className="flex items-center gap-2 px-3"><Mail size={14} />任务消息{received ? ` · 收到 ${received} 条` : ""}</span>} initiallyOpen className="surface-reading rounded-xl">
|
|
<div className="space-y-3 p-3 text-xs" aria-live="polite">
|
|
<p className="text-[var(--ink-muted)]">新消息会在此显示。由你决定是否继续发送指令。</p>
|
|
{loading ? <p className="text-[var(--ink-muted)]">正在加载任务消息…</p> : null}
|
|
{error ? <div className="flex items-center justify-between gap-2"><p className="text-[var(--status-warning-foreground)]">{error}</p><Button variant="ghost" size="sm" onClick={onRefresh}>重试</Button></div> : null}
|
|
{messages.map((message) => <article key={message.message_id} className="space-y-1.5 border-t border-[var(--surface-divider)] pt-3">
|
|
<div className="flex flex-wrap items-center justify-between gap-2 text-[var(--ink-muted)]">
|
|
<span>{message.direction === "to_chat" ? "调查任务来信" : "发给调查任务"}</span>
|
|
<span>{messageStatusLabels[message.status]}</span>
|
|
</div>
|
|
<p className="whitespace-pre-wrap break-words text-sm leading-6 text-[var(--ink)]">{message.text}</p>
|
|
<details className="text-[var(--ink-muted)]"><summary className="cursor-pointer">消息详情</summary>
|
|
<p className="break-all">任务编号:<span className="select-text font-mono">{message.task_id}</span></p>
|
|
<p className="break-all">运行编号:<span className="select-text font-mono">{message.run_id}</span></p>
|
|
</details>
|
|
{message.failure_detail ? <p className="break-words text-[var(--status-danger-foreground)]">{message.failure_detail}</p> : null}
|
|
</article>)}
|
|
{hasMore ? <Button variant="ghost" size="sm" disabled={loadingMore} onClick={() => void onLoadMore?.().catch(() => undefined)}>{loadingMore ? "正在加载…" : "加载更多消息"}</Button> : null}
|
|
</div>
|
|
</Disclosure>;
|
|
}
|