Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions web-ui/src/components/TaskTreeView.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,7 @@ describe('TaskTreeView', () => {
expect(humanBadges.length).toBeGreaterThan(0); // Task
});

// TODO: Task dependencies not rendering - see beads issue cf-jf1
it.skip('should display task dependencies', async () => {
it('should display task dependencies', async () => {
const user = userEvent.setup();

render(<TaskTreeView issues={mockIssues} />);
Expand Down Expand Up @@ -380,8 +379,7 @@ describe('TaskTreeView', () => {
expect(titleElement).toBeInTheDocument();
});

// TODO: Task dependencies not rendering - see beads issue cf-jf1
it.skip('should handle multiple dependencies correctly', async () => {
it('should handle multiple dependencies correctly', async () => {
const user = userEvent.setup();

const multiDepTask: Task = {
Expand Down Expand Up @@ -614,9 +612,9 @@ describe('TaskTreeView', () => {
const expandButton = screen.getAllByRole('button', { name: /expand/i })[0];
await user.click(expandButton);

// Should show dependency count
const depCount = screen.getByText(/1 dependency/i);
expect(depCount).toBeInTheDocument();
// Should show dependency text
const depText = screen.getByText(/depends on.*task-1/i);
expect(depText).toBeInTheDocument();
});

it('should mark task as blocked when dependencies are not completed', async () => {
Expand Down
50 changes: 14 additions & 36 deletions web-ui/src/components/TaskTreeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -225,44 +225,22 @@ const TaskTreeView = memo(function TaskTreeView({ issues }: TaskTreeViewProps) {
</span>
)}

{/* Dependency details with hover tooltip */}
{hasDependencies && (
{/* Dependency details */}
{hasDependencies && task.depends_on && (
<span
className="group relative inline-flex items-center text-xs text-gray-500 cursor-help"
title={`Dependencies: ${task.depends_on.join(', ')}`}
className="ml-2 text-xs text-gray-500 cursor-help"
title={`Dependencies:\n${task.depends_on
.map((depId) => {
const depTask = allTasks.find(
(t) => t.id === depId || t.task_number === depId
);
return depTask
? `${depTask.task_number}: ${depTask.title} (${depTask.status})`
: depId;
})
.join('\n')}`}
>
↳ {task.depends_on.length} {task.depends_on.length === 1 ? 'dependency' : 'dependencies'}
{/* Hover tooltip */}
<span className="invisible group-hover:visible absolute left-0 top-full mt-1 w-48 p-2 bg-gray-900 text-white text-xs rounded shadow-lg z-10">
<strong>Depends on:</strong>
<ul className="mt-1 list-disc list-inside">
{task.depends_on.map((depId) => {
const depTask = allTasks.find(
(t) => t.id === depId || t.task_number === depId
);
return (
<li key={depId} className="truncate">
{depTask ? (
<span>
{depTask.task_number}: {depTask.title}
<span
className={`ml-1 ${
depTask.status === 'completed'
? 'text-green-400'
: 'text-yellow-400'
}`}
>
({depTask.status})
</span>
</span>
) : (
depId
)}
</li>
);
})}
</ul>
</span>
Depends on: {task.depends_on.join(', ')}
</span>
)}
</div>
Expand Down
Loading