'use client'; import Link from 'next/link'; import React from 'react'; import { Activity, ArrowRight, Clock3, FolderKanban, Loader2, Sparkles, Users, } from 'lucide-react'; import { OfficeStatusBadge, formatOfficeTime, progressPercent } from '@/components/office/OfficeShared'; import { TaskManagementTabs } from '@/components/task-management/TaskManagementTabs'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { buildOfficeTaskList, isOfficeTaskTerminal } from '@/lib/office'; import { appConnectionStatusLabel } from '@/lib/i18n/common'; import { pickAppText } from '@/lib/i18n/core'; import { useAppI18n } from '@/lib/i18n/provider'; import { useChatStore } from '@/lib/store'; function TaskCard({ taskId, title, sessionLabel, rootActorName, status, updatedAt, memberCount, activeRuns, artifactCount, errorCount, currentStageLabel, progressLabel, progressValue, locale, }: { taskId: string; title: string; sessionLabel: string; rootActorName: string; status: Parameters[0]['status']; updatedAt: string; memberCount: number; activeRuns: number; artifactCount: number; errorCount: number; currentStageLabel: string | null; progressLabel: string; progressValue: number; locale: 'zh-CN' | 'en-US'; }) { return (
{title} {pickAppText(locale, '会话', 'Session')}: {sessionLabel} {pickAppText(locale, '主 Agent', 'Lead agent')}: {rootActorName} {pickAppText(locale, '更新于', 'Updated')} {formatOfficeTime(updatedAt, locale)}
{progressLabel} {currentStageLabel ? {currentStageLabel} : null}
); } function Metric({ icon: Icon, label, value, }: { icon: React.ComponentType<{ className?: string }>; label: string; value: string; }) { return (
{label}
{value}
); } export default function OfficeListPage() { const { locale } = useAppI18n(); const sessionId = useChatStore((state) => state.sessionId); const sessions = useChatStore((state) => state.sessions); const processRuns = useChatStore((state) => state.processRuns); const processEvents = useChatStore((state) => state.processEvents); const processArtifacts = useChatStore((state) => state.processArtifacts); const wsStatus = useChatStore((state) => state.wsStatus); const tasks = React.useMemo( () => buildOfficeTaskList({ sessionId, sessions, processRuns, processEvents, processArtifacts, }, locale), [locale, processArtifacts, processEvents, processRuns, sessionId, sessions] ); const activeTasks = tasks.filter((task) => !isOfficeTaskTerminal(task.status)); const recentTasks = tasks.filter((task) => isOfficeTaskTerminal(task.status)); return (

Office

{pickAppText( locale, '基于当前会话的真实运行数据,展示主 Agent 与子 Agent 的任务现场。任务结束后会从活跃现场移除,但保留回看入口。', 'Show the live task floor for the lead agent and its sub-agents using real runtime data from the current session. Finished tasks leave the active floor but remain available for review.' )}

{pickAppText(locale, '当前会话', 'Current session')}
{sessionId}
{pickAppText(locale, '连接状态', 'Connection')}
{appConnectionStatusLabel(wsStatus, wsStatus === 'connected' ? true : null, locale)}
{wsStatus === 'connecting' && tasks.length === 0 ? (
{pickAppText(locale, '正在等待运行时数据...', 'Waiting for runtime data...')}
) : null} {tasks.length === 0 ? (

{pickAppText(locale, '当前没有可展示的任务现场', 'No task floor is available yet')}

{pickAppText( locale, '先回到对话页发起一次主 Agent 任务。开始执行后,这里会出现活跃的 office 卡片。', 'Start a lead-agent task from the chat page first. Once it begins running, active office cards will appear here.' )}

) : ( <>

{pickAppText(locale, '活跃 Office', 'Active office')}

{pickAppText(locale, '正在运行中的任务现场会优先显示。', 'Running task floors are shown first.')}

{pickAppText(locale, `${activeTasks.length} 个任务`, `${activeTasks.length} tasks`)}
{activeTasks.length === 0 ? ( {pickAppText(locale, '当前没有活跃任务,下面可以查看最近结束的任务。', 'There are no active tasks right now. Recent finished tasks are listed below.')} ) : (
{activeTasks.map((task) => ( ))}
)}

{pickAppText(locale, '最近结束', 'Recently finished')}

{pickAppText(locale, '已完成、失败或取消的任务仍保留回看入口。', 'Completed, failed, or cancelled tasks remain available for review.')}

{pickAppText(locale, `${recentTasks.length} 个任务`, `${recentTasks.length} tasks`)}
{recentTasks.length === 0 ? ( {pickAppText(locale, '还没有历史任务。', 'There is no task history yet.')} ) : (
{recentTasks.map((task) => ( ))}
)}
)}
); }