diff --git a/frontend/src/components/assistant/TaskLane.tsx b/frontend/src/components/assistant/TaskLane.tsx index e361b66e..152890fc 100644 --- a/frontend/src/components/assistant/TaskLane.tsx +++ b/frontend/src/components/assistant/TaskLane.tsx @@ -147,8 +147,16 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa return () => { if (saveTimerRef.current) clearTimeout(saveTimerRef.current) } }, [sessionId, tasks]) // eslint-disable-line react-hooks/exhaustive-deps - // Reset when new tasks come in from AI response + // Reset when new tasks come in from AI response — but preserve saved state useEffect(() => { + if (sessionId) { + const saved = loadTaskState(sessionId) + if (saved && saved.length > 0) { + // eslint-disable-next-line react-hooks/set-state-in-effect -- intentional: syncs derived state from prop changes + setTasks(saved) + return + } + } // eslint-disable-next-line react-hooks/set-state-in-effect -- intentional: syncs derived state from prop changes setTasks([ ...questions.map((q): QuestionResponse => ({ @@ -158,7 +166,7 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa type: 'action', label: a.label, command: a.command, description: a.description, state: 'pending', value: '', })), ]) - }, [questions, actions]) + }, [questions, actions]) // eslint-disable-line react-hooks/exhaustive-deps const updateTask = (idx: number, updates: Partial) => { setTasks(prev => prev.map((t, i) => i === idx ? { ...t, ...updates } as TaskResponse : t)) diff --git a/frontend/src/pages/AssistantChatPage.tsx b/frontend/src/pages/AssistantChatPage.tsx index dc6fcb7b..ad6d41c1 100644 --- a/frontend/src/pages/AssistantChatPage.tsx +++ b/frontend/src/pages/AssistantChatPage.tsx @@ -232,16 +232,17 @@ export default function AssistantChatPage() { const q = detail.pending_task_lane.questions || [] const a = detail.pending_task_lane.actions || [] if (q.length > 0 || a.length > 0) { - setActiveQuestions(q) - setActiveActions(a) - setShowTaskLane(true) - // Pre-load user's saved responses into sessionStorage so TaskLane restores them + // Pre-load user's saved responses into sessionStorage BEFORE setting props + // so TaskLane can restore them on mount/prop-change const responses = (detail.pending_task_lane as Record).responses as unknown[] | undefined if (responses && responses.length > 0) { try { sessionStorage.setItem(`rf-tasklane-state:${chatId}`, JSON.stringify(responses)) } catch { /* ignore */ } } + setActiveQuestions(q) + setActiveActions(a) + setShowTaskLane(true) } } } catch {