Files
ColaFlow/docs/plans/sprint_1_story_2_task_4.md
Yaojia Wang 08b317e789
Some checks failed
Code Coverage / Generate Coverage Report (push) Has been cancelled
Tests / Run Tests (9.0.x) (push) Has been cancelled
Tests / Docker Build Test (push) Has been cancelled
Tests / Test Summary (push) Has been cancelled
Add trace files.
2025-11-04 23:28:56 +01:00

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

  1. HierarchyTree.tsx component
  2. Breadcrumb.tsx component
  3. CSS styles for tree layout
  4. Unit tests (8+ tests)

Status: Not Started | Created: 2025-11-04