'use client'; /** * TodoPanel Component (WebUI) * Displays agent's todo list with progress tracking */ import React from 'react'; import { CheckCircle2, Circle } from 'lucide-react'; import { Card } from './ui/card'; import { cn } from '@/lib/utils'; import { useTodoStore, type Todo } from '@/lib/stores/todoStore'; interface TodoPanelProps { sessionId: string; } // Stable empty array to avoid infinite re-render loop const EMPTY_TODOS: Todo[] = []; /** * Compact todo panel showing task progress * Shows up to 10 tasks with minimal spacing */ export function TodoPanel({ sessionId }: TodoPanelProps) { // Select directly from state, use stable empty array fallback outside selector const todos = useTodoStore((state) => state.sessions.get(sessionId)?.todos) ?? EMPTY_TODOS; if (todos.length === 0) { return null; } const completedCount = todos.filter((t) => t.status === 'completed').length; const totalCount = todos.length; // Show up to 10 tasks total const visibleTodos = todos.slice(0, 10); const hasMore = todos.length > 10; return (
{/* Header with progress */}
Tasks in Progress
0 ? (completedCount / totalCount) * 100 : 0}%`, }} />
{completedCount}/{totalCount}
{/* All tasks */}
{visibleTodos.map((todo) => { const isInProgress = todo.status === 'in_progress'; const isCompleted = todo.status === 'completed'; return (
{isCompleted ? ( ) : isInProgress ? (
) : ( )}
{isInProgress ? todo.activeForm : todo.content}
); })}
{/* More tasks indicator */} {hasMore && (
+{todos.length - 10} more tasks...
)}
); }