feat: task lane persistence + sidebar cleanup #121
@@ -147,8 +147,16 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa
|
|||||||
return () => { if (saveTimerRef.current) clearTimeout(saveTimerRef.current) }
|
return () => { if (saveTimerRef.current) clearTimeout(saveTimerRef.current) }
|
||||||
}, [sessionId, tasks]) // eslint-disable-line react-hooks/exhaustive-deps
|
}, [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(() => {
|
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
|
// eslint-disable-next-line react-hooks/set-state-in-effect -- intentional: syncs derived state from prop changes
|
||||||
setTasks([
|
setTasks([
|
||||||
...questions.map((q): QuestionResponse => ({
|
...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: '',
|
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<TaskResponse>) => {
|
const updateTask = (idx: number, updates: Partial<TaskResponse>) => {
|
||||||
setTasks(prev => prev.map((t, i) => i === idx ? { ...t, ...updates } as TaskResponse : t))
|
setTasks(prev => prev.map((t, i) => i === idx ? { ...t, ...updates } as TaskResponse : t))
|
||||||
|
|||||||
@@ -232,16 +232,17 @@ export default function AssistantChatPage() {
|
|||||||
const q = detail.pending_task_lane.questions || []
|
const q = detail.pending_task_lane.questions || []
|
||||||
const a = detail.pending_task_lane.actions || []
|
const a = detail.pending_task_lane.actions || []
|
||||||
if (q.length > 0 || a.length > 0) {
|
if (q.length > 0 || a.length > 0) {
|
||||||
setActiveQuestions(q)
|
// Pre-load user's saved responses into sessionStorage BEFORE setting props
|
||||||
setActiveActions(a)
|
// so TaskLane can restore them on mount/prop-change
|
||||||
setShowTaskLane(true)
|
|
||||||
// Pre-load user's saved responses into sessionStorage so TaskLane restores them
|
|
||||||
const responses = (detail.pending_task_lane as Record<string, unknown>).responses as unknown[] | undefined
|
const responses = (detail.pending_task_lane as Record<string, unknown>).responses as unknown[] | undefined
|
||||||
if (responses && responses.length > 0) {
|
if (responses && responses.length > 0) {
|
||||||
try {
|
try {
|
||||||
sessionStorage.setItem(`rf-tasklane-state:${chatId}`, JSON.stringify(responses))
|
sessionStorage.setItem(`rf-tasklane-state:${chatId}`, JSON.stringify(responses))
|
||||||
} catch { /* ignore */ }
|
} catch { /* ignore */ }
|
||||||
}
|
}
|
||||||
|
setActiveQuestions(q)
|
||||||
|
setActiveActions(a)
|
||||||
|
setShowTaskLane(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
Reference in New Issue
Block a user