3.5 KiB
3.5 KiB
Task 8: Add Hierarchy Visualization
Task ID: TASK-008 | Story: STORY-002 | Sprint: Sprint 1 Estimated Hours: 4h | Assignee: Frontend Developer 2 | Priority: P0 | Status: Not Started
Task Description
Build tree view component to visualize Epic → Story → Task hierarchy with expand/collapse and breadcrumb navigation.
Implementation
Component: HierarchyTree.tsx
import React, { useState } from 'react';
import { Epic, Story, Task } from '../api/types';
interface HierarchyTreeProps {
epics: Epic[];
stories: Story[];
tasks: Task[];
}
export const HierarchyTree: React.FC<HierarchyTreeProps> = ({ epics, stories, tasks }) => {
const [expandedEpics, setExpandedEpics] = useState<Set<string>>(new Set());
const [expandedStories, setExpandedStories] = useState<Set<string>>(new Set());
const toggleEpic = (epicId: string) => {
setExpandedEpics(prev => {
const next = new Set(prev);
if (next.has(epicId)) next.delete(epicId);
else next.add(epicId);
return next;
});
};
const getStoriesForEpic = (epicId: string) => {
return stories.filter(s => s.parentEpicId === epicId);
};
const getTasksForStory = (storyId: string) => {
return tasks.filter(t => t.parentStoryId === storyId);
};
return (
<div className="hierarchy-tree">
{epics.map(epic => (
<div key={epic.id} className="epic-node">
<div className="flex items-center gap-2 p-2 hover:bg-gray-50 cursor-pointer" onClick={() => toggleEpic(epic.id)}>
<span className="text-purple-600">📊</span>
<span className="font-semibold">{epic.title}</span>
<span className="text-sm text-gray-500">
({getStoriesForEpic(epic.id).length} stories)
</span>
</div>
{expandedEpics.has(epic.id) && (
<div className="ml-6 border-l-2 border-gray-200">
{getStoriesForEpic(epic.id).map(story => (
<div key={story.id} className="story-node">
<div className="flex items-center gap-2 p-2">
<span className="text-blue-600">📝</span>
<span>{story.title}</span>
<span className="text-sm text-gray-500">
({getTasksForStory(story.id).length} tasks)
</span>
</div>
<div className="ml-6">
{getTasksForStory(story.id).map(task => (
<div key={task.id} className="task-node flex items-center gap-2 p-2">
<span className="text-green-600">✓</span>
<span className="text-sm">{task.title}</span>
<span className={`px-2 py-1 text-xs rounded ${task.status === 'Done' ? 'bg-green-100' : 'bg-gray-100'}`}>
{task.status}
</span>
</div>
))}
</div>
</div>
))}
</div>
)}
</div>
))}
</div>
);
};
Acceptance Criteria
- Tree view displays Epic → Story → Task structure
- Expand/collapse Epic nodes
- Show child count for each node
- Icons differentiate Epic/Story/Task
- Click to navigate to detail page
- Breadcrumb navigation component
Deliverables
- HierarchyTree.tsx component
- Breadcrumb.tsx component
- CSS styles for tree layout
- Unit tests (8+ tests)
Status: Not Started | Created: 2025-11-04