'use client'; import React from 'react'; import type { ChatMessage, ProcessArtifact, ProcessEvent, ProcessRun } from '@/types'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { MessageList } from '@/components/chat-workbench/MessageList'; import { ArtifactSidebar } from '@/components/chat-workbench/ArtifactSidebar'; import { ProcessLane } from '@/components/chat-workbench/ProcessLane'; import { pickAppText } from '@/lib/i18n/core'; import { useAppI18n } from '@/lib/i18n/provider'; export function ChatWorkbench({ messages, isThinking, messagesEndRef, messageViewportRef, processRuns, processEvents, processArtifacts, selectedRunId, onSelectRun, onCancelRun, onFeedback, }: { messages: ChatMessage[]; isThinking: boolean; messagesEndRef: React.RefObject; messageViewportRef: React.RefObject; processRuns: ProcessRun[]; processEvents: ProcessEvent[]; processArtifacts: ProcessArtifact[]; selectedRunId: string | null; onSelectRun: (runId: string) => void; onCancelRun: (runId: string) => void; onFeedback: (runId: string, feedbackType: 'satisfied' | 'revise' | 'abandon') => void; }) { const { locale } = useAppI18n(); const [isDesktop, setIsDesktop] = React.useState(() => typeof window === 'undefined' ? true : window.matchMedia('(min-width: 1024px)').matches ); React.useEffect(() => { if (typeof window === 'undefined') { return; } const mediaQuery = window.matchMedia('(min-width: 1024px)'); const updateLayout = () => setIsDesktop(mediaQuery.matches); updateLayout(); if (typeof mediaQuery.addEventListener === 'function') { mediaQuery.addEventListener('change', updateLayout); return () => mediaQuery.removeEventListener('change', updateLayout); } mediaQuery.addListener(updateLayout); return () => mediaQuery.removeListener(updateLayout); }, []); const selectedRun = selectedRunId ? processRuns.find((item) => item.run_id === selectedRunId) || null : null; const selectedRunEvents = selectedRun ? processEvents.filter((item) => item.run_id === selectedRun.run_id) : []; const selectedRunArtifacts = selectedRun ? processArtifacts.filter((item) => item.run_id === selectedRun.run_id) : []; const hasResultsPanel = Boolean( selectedRun && ( selectedRun.summary || selectedRunEvents.length > 0 || selectedRunArtifacts.length > 0 ) ); const hasProcessPanel = processRuns.length > 0; const desktopColumns = hasProcessPanel && hasResultsPanel ? 'grid-cols-[minmax(0,1fr)_340px_360px]' : hasProcessPanel ? 'grid-cols-[minmax(0,1fr)_340px]' : hasResultsPanel ? 'grid-cols-[minmax(0,1fr)_360px]' : 'grid-cols-[minmax(0,1fr)]'; const messageList = ( ); if (isDesktop) { return (
{messageList}
{hasProcessPanel && (
)} {hasResultsPanel && (
)}
); } return (
{!hasResultsPanel && !hasProcessPanel ? ( messageList ) : (
{pickAppText(locale, '聊天', 'Chat')} {pickAppText(locale, '过程', 'Process')} {hasResultsPanel && ( {pickAppText(locale, '结果', 'Results')} )}
{messageList} {hasResultsPanel && ( )}
)}
); }