feat(frontend): restore session progress sidebar

This commit is contained in:
2026-05-22 14:34:45 +08:00
parent e061961a79
commit c671b66043
8 changed files with 1046 additions and 7 deletions

View File

@ -5,6 +5,7 @@ import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useSta
import { Brain, Plus, Send, Trash2, X } from 'lucide-react';
import { ChatWorkbench } from '@/components/chat-workbench/ChatWorkbench';
import { CurrentSessionProgressSidebar } from '@/components/chat-workbench/CurrentSessionProgressSidebar';
import { ScrollArea } from '@/components/ui/scroll-area';
import {
archiveSession,
@ -18,9 +19,10 @@ import {
uploadFile,
wsManager,
} from '@/lib/api';
import { mergeServerWithPendingUsers } from '@/lib/chat-messages';
import { mergeServerWithPendingUsers, shouldMergePendingUsers } from '@/lib/chat-messages';
import { pickAppText } from '@/lib/i18n/core';
import { useAppI18n } from '@/lib/i18n/provider';
import { buildSessionProgressView } from '@/lib/session-progress';
import { useChatStore } from '@/lib/store';
import type { ActiveTask, ChatMessage, FileAttachment, SessionUpdatedEvent, WsEvent } from '@/types';
@ -60,6 +62,9 @@ export default function ChatPage() {
setSessionId,
setMessages,
addMessage,
setInputDraft,
getInputDraft,
clearInputDraft,
setIsLoading,
clearMessages,
setIsThinking,
@ -68,7 +73,7 @@ export default function ChatPage() {
updateMessageFeedback,
} = useChatStore();
const [input, setInput] = useState('');
const [input, setInput] = useState(() => useChatStore.getState().getInputDraft(useChatStore.getState().sessionId));
const [thinkingModeEnabled, setThinkingModeEnabled] = useState(loadThinkingModePreference);
const [pendingFiles, setPendingFiles] = useState<Array<{ file: File; id?: string; progress: number; error?: string }>>([]);
const [activeTask, setActiveTask] = useState<ActiveTask | null>(null);
@ -105,6 +110,17 @@ export default function ChatPage() {
);
const selectedSessionRunId = selectedRunId && sessionRunIds.has(selectedRunId) ? selectedRunId : null;
const sessionProgressView = useMemo(
() =>
buildSessionProgressView({
sessionId,
processRuns,
processEvents,
processArtifacts,
locale,
}),
[locale, processArtifacts, processEvents, processRuns, sessionId]
);
const loadSessions = useCallback(async () => {
try {
@ -141,7 +157,8 @@ export default function ChatPage() {
setSessionProcess(key, process);
}
void loadActiveTask(key);
const nextMessages = waitingForReply
const shouldMergePending = shouldMergePendingUsers(detail.messages, localSnapshot, waitingForReply);
const nextMessages = shouldMergePending
? mergeServerWithPendingUsers(detail.messages, localSnapshot)
: detail.messages;
setMessages(nextMessages);
@ -167,6 +184,7 @@ export default function ChatPage() {
}
setActiveTask(null);
setRevisionTargetRunId(null);
setInput(useChatStore.getState().getInputDraft(sessionId));
void loadSessionMessages(sessionId);
void loadActiveTask(sessionId);
}, [clearMessages, loadActiveTask, loadSessionMessages, sessionId, setIsLoading, setIsThinking]);
@ -308,6 +326,7 @@ export default function ChatPage() {
}
setInput('');
clearInputDraft(sessionId);
setPendingFiles([]);
addMessage({
role: 'user',
@ -372,7 +391,7 @@ export default function ChatPage() {
});
}
}
}, [addMessage, input, isLoading, loadActiveTask, loadSessionMessages, loadSessions, locale, pendingFiles, revisionTargetRunId, sessionId, setIsLoading, setIsThinking, setSessionProcess, thinkingModeEnabled, updateMessageFeedback]);
}, [addMessage, clearInputDraft, input, isLoading, loadActiveTask, loadSessionMessages, loadSessions, locale, pendingFiles, revisionTargetRunId, sessionId, setIsLoading, setIsThinking, setSessionProcess, thinkingModeEnabled, updateMessageFeedback]);
const handleFeedback = useCallback(async (runId: string, feedbackType: 'satisfied' | 'revise' | 'abandon', comment?: string) => {
updateMessageFeedback(runId, feedbackType);
@ -433,6 +452,8 @@ export default function ChatPage() {
setSelectedRunId(null);
setActiveTask(null);
setRevisionTargetRunId(null);
clearInputDraft(id);
setInput('');
clearMessages();
useChatStore.getState().resetProcessState();
try {
@ -452,6 +473,8 @@ export default function ChatPage() {
setSessionId('web:default');
setActiveTask(null);
setRevisionTargetRunId(null);
clearInputDraft(key);
setInput(useChatStore.getState().getInputDraft('web:default'));
clearMessages();
useChatStore.getState().resetProcessState();
}
@ -469,6 +492,7 @@ export default function ChatPage() {
setSelectedRunId(null);
setActiveTask(null);
setRevisionTargetRunId(null);
setInput(useChatStore.getState().getInputDraft(key));
setSessionId(key);
};
@ -619,7 +643,10 @@ export default function ChatPage() {
<textarea
ref={textareaRef}
value={input}
onChange={(e) => setInput(e.target.value)}
onChange={(e) => {
setInput(e.target.value);
setInputDraft(sessionId, e.target.value);
}}
onKeyDown={handleKeyDown}
placeholder={
revisionTargetRunId
@ -678,6 +705,8 @@ export default function ChatPage() {
</div>
</div>
</div>
{sessionProgressView && <CurrentSessionProgressSidebar view={sessionProgressView} />}
</div>
);
}