import { useEffect, useState } from 'react'; import { Card } from '@/components/ui/card'; import { TaskRelationshipCard } from './TaskRelationshipCard'; import { attemptsApi } from '@/lib/api'; import type { TaskAttempt, TaskRelationships, TaskWithAttemptStatus, } from 'shared/types'; import { ChevronDown, ChevronRight } from 'lucide-react'; import { cn } from '@/lib/utils'; interface TaskRelationshipViewerProps { selectedAttempt: TaskAttempt | null; onNavigateToTask?: (taskId: string) => void; task?: TaskWithAttemptStatus | null; tasksById?: Record; } export function TaskRelationshipViewer({ selectedAttempt, onNavigateToTask, task, tasksById, }: TaskRelationshipViewerProps) { const [relationships, setRelationships] = useState( null ); const [parentTask, setParentTask] = useState( null ); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [childrenExpanded, setChildrenExpanded] = useState(true); // Effect for attempt-based relationships (existing behavior) useEffect(() => { if (!selectedAttempt?.id) { setRelationships(null); return; } const fetchRelationships = async () => { setLoading(true); setError(null); try { const relationshipData = await attemptsApi.getChildren( selectedAttempt.id ); setRelationships(relationshipData); } catch (err) { console.error('Failed to fetch task relationships:', err); setError('Failed to load task relationships'); } finally { setLoading(false); } }; fetchRelationships(); }, [selectedAttempt?.id]); // Effect for parent task when child has no attempts (one request + tasksById lookup) useEffect(() => { if (selectedAttempt?.id) { // If we have an attempt, clear parent task since relationships will handle it setParentTask(null); return; } if (task?.parent_task_attempt && tasksById) { attemptsApi .get(task.parent_task_attempt) .then((parentAttempt) => { // Use existing tasksById instead of second API call const parentTaskData = tasksById[parentAttempt.task_id]; setParentTask(parentTaskData || null); }) .catch(() => setParentTask(null)); } else { setParentTask(null); } }, [selectedAttempt?.id, task?.parent_task_attempt, tasksById]); const displayParentTask = relationships?.parent_task || parentTask; const childTasks = relationships?.children || []; const hasParent = displayParentTask !== null; const hasChildren = childTasks.length > 0; // Don't render if no relationships and no current task if (!hasParent && !hasChildren && !loading && !error) { return null; } return (
Task Relationships
{loading ? (
Loading relationships...
) : error ? (
{error}
) : (
{/* Parent Task Section */} {hasParent && displayParentTask && (

Parent Task

onNavigateToTask?.(displayParentTask.id)} className="shadow-sm" />
)} {/* Child Tasks Section */} {hasChildren && (
{childrenExpanded && (
{childTasks.map((childTask) => ( onNavigateToTask?.(childTask.id)} className="shadow-sm hover:shadow-md transition-shadow" /> ))}
)}
)}
)}
); }