Files
ColaFlow-Web/components/features/kanban/KanbanColumn.tsx
Yaojia Wang de697d436b feat(frontend): Implement Issue management and Kanban board
Add comprehensive Issue management functionality with drag-and-drop Kanban board.

Changes:
- Created Issue API client (issues.ts) with CRUD operations
- Implemented React Query hooks for Issue data management
- Added IssueCard component with drag-and-drop support using @dnd-kit
- Created KanbanColumn component with droppable zones
- Built CreateIssueDialog with form validation using zod
- Implemented Kanban page at /projects/[id]/kanban with DnD status changes
- Added missing UI components (textarea, select, skeleton)
- Enhanced API client with helper methods (get, post, put, patch, delete)
- Installed dependencies: @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities, @radix-ui/react-select, sonner
- Fixed SignalR ConnectionManager TypeScript error
- Preserved legacy KanbanBoard component for backward compatibility

Features:
- Drag and drop issues between Backlog, Todo, InProgress, and Done columns
- Real-time status updates via API
- Issue creation with type (Story, Task, Bug, Epic) and priority
- Visual feedback with priority colors and type icons
- Toast notifications for user actions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 11:50:01 +01:00

44 lines
1.4 KiB
TypeScript

'use client';
import { useDroppable } from '@dnd-kit/core';
import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Issue } from '@/lib/api/issues';
import { IssueCard } from './IssueCard';
interface KanbanColumnProps {
id: string;
title: string;
issues: Issue[];
}
export function KanbanColumn({ id, title, issues }: KanbanColumnProps) {
const { setNodeRef } = useDroppable({ id });
return (
<Card>
<CardHeader className="pb-3">
<CardTitle className="text-sm font-medium flex items-center justify-between">
<span>{title}</span>
<span className="text-muted-foreground">{issues.length}</span>
</CardTitle>
</CardHeader>
<CardContent ref={setNodeRef} className="space-y-2 min-h-[400px]">
<SortableContext
items={issues.map((i) => i.id)}
strategy={verticalListSortingStrategy}
>
{issues.map((issue) => (
<IssueCard key={issue.id} issue={issue} />
))}
</SortableContext>
{issues.length === 0 && (
<div className="flex h-32 items-center justify-center rounded-lg border-2 border-dashed border-muted-foreground/25">
<p className="text-sm text-muted-foreground">No issues</p>
</div>
)}
</CardContent>
</Card>
);
}