// ======================================== // Analysis Viewer Page // ======================================== // View analysis sessions from /workflow:analyze-with-file command import { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { FileSearch, Search, Calendar, CheckCircle, Clock, ChevronRight, Loader2, AlertCircle, X, FileText, Code, MessageSquare, } from 'lucide-react'; import { useWorkflowStore } from '@/stores/workflowStore'; import { Card } from '@/components/ui/Card'; import { Input } from '@/components/ui/Input'; import { Badge } from '@/components/ui/Badge'; import { Button } from '@/components/ui/Button'; import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/Tabs'; import { fetchAnalysisSessions, fetchAnalysisDetail } from '@/lib/api'; import { MessageRenderer } from '@/components/shared/CliStreamMonitor/MessageRenderer'; import { JsonCardView } from '@/components/shared/JsonCardView'; import type { AnalysisSessionSummary } from '@/types/analysis'; // ========== Session Card Component ========== interface SessionCardProps { session: AnalysisSessionSummary; onClick: () => void; isSelected: boolean; } function SessionCard({ session, onClick, isSelected }: SessionCardProps) { return (
{session.topic}

{session.id}

{session.status === 'completed' ? ( <>完成 ) : ( <>进行中 )} {session.createdAt}
); } // ========== Detail Panel Component ========== interface DetailPanelProps { sessionId: string; projectPath: string; onClose: () => void; } function DetailPanel({ sessionId, projectPath, onClose }: DetailPanelProps) { const { data: detail, isLoading, error } = useQuery({ queryKey: ['analysis-detail', sessionId, projectPath], queryFn: () => fetchAnalysisDetail(sessionId, projectPath), }); if (isLoading) { return (
); } if (error) { return (
加载失败: {(error as Error).message}
); } if (!detail) return null; // Build available tabs based on content const tabs = [ { id: 'discussion', label: '讨论记录', icon: MessageSquare, content: detail.discussion }, { id: 'conclusions', label: '结论', icon: CheckCircle, content: detail.conclusions }, { id: 'explorations', label: '代码探索', icon: Code, content: detail.explorations }, { id: 'perspectives', label: '视角分析', icon: FileText, content: detail.perspectives }, ].filter(tab => tab.content); const defaultTab = tabs[0]?.id || 'discussion'; return (
{/* Header */}

{detail.topic}

{detail.status === 'completed' ? '完成' : '进行中'} {detail.createdAt}
{/* Tabs Content */} {tabs.length > 0 ? ( {tabs.map(tab => ( {tab.label} ))}
{/* Discussion Tab */} {detail.discussion && ( )} {/* Conclusions Tab */} {detail.conclusions && ( )} {/* Explorations Tab */} {detail.explorations && ( )} {/* Perspectives Tab */} {detail.perspectives && ( )}
) : (
暂无分析内容
)}
); } // ========== Main Component ========== export function AnalysisPage() { const projectPath = useWorkflowStore((state) => state.projectPath); const [searchQuery, setSearchQuery] = useState(''); const [selectedSession, setSelectedSession] = useState(null); const { data: sessions = [], isLoading, error } = useQuery({ queryKey: ['analysis-sessions', projectPath], queryFn: () => fetchAnalysisSessions(projectPath), }); // Filter sessions by search query const filteredSessions = sessions.filter((session) => session.topic.toLowerCase().includes(searchQuery.toLowerCase()) || session.id.toLowerCase().includes(searchQuery.toLowerCase()) ); return (
{/* Left Panel - List */}
{/* Header */}

Analysis Viewer

查看 /workflow:analyze-with-file 命令的分析结果

{/* Search */}
setSearchQuery(e.target.value)} className="pl-9" />
{/* Content */} {isLoading ? (
) : error ? (
加载失败: {(error as Error).message}
) : filteredSessions.length === 0 ? (

{searchQuery ? '没有匹配的分析会话' : '暂无分析会话'}

使用 /workflow:analyze-with-file 命令创建分析

) : (
{filteredSessions.map((session) => ( setSelectedSession(session.id)} /> ))}
)}
{/* Right Panel - Detail */} {selectedSession && (
setSelectedSession(null)} />
)}
); } export default AnalysisPage;