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>
85 lines
2.0 KiB
TypeScript
85 lines
2.0 KiB
TypeScript
import { api } from './client';
|
|
|
|
export interface Issue {
|
|
id: string;
|
|
projectId: string;
|
|
title: string;
|
|
description: string;
|
|
type: 'Story' | 'Task' | 'Bug' | 'Epic';
|
|
status: 'Backlog' | 'Todo' | 'InProgress' | 'Done';
|
|
priority: 'Low' | 'Medium' | 'High' | 'Critical';
|
|
assigneeId?: string;
|
|
reporterId: string;
|
|
createdAt: string;
|
|
updatedAt?: string;
|
|
}
|
|
|
|
export interface CreateIssueDto {
|
|
title: string;
|
|
description: string;
|
|
type: string;
|
|
priority: string;
|
|
}
|
|
|
|
export interface UpdateIssueDto {
|
|
title: string;
|
|
description: string;
|
|
priority: string;
|
|
}
|
|
|
|
export interface ChangeStatusDto {
|
|
status: string;
|
|
}
|
|
|
|
export interface AssignIssueDto {
|
|
assigneeId: string | null;
|
|
}
|
|
|
|
export const issuesApi = {
|
|
list: async (projectId: string, status?: string): Promise<Issue[]> => {
|
|
const params = status ? `?status=${status}` : '';
|
|
return api.get<Issue[]>(`/api/v1/projects/${projectId}/issues${params}`);
|
|
},
|
|
|
|
getById: async (projectId: string, id: string): Promise<Issue> => {
|
|
return api.get<Issue>(`/api/v1/projects/${projectId}/issues/${id}`);
|
|
},
|
|
|
|
create: async (projectId: string, data: CreateIssueDto): Promise<Issue> => {
|
|
return api.post<Issue>(`/api/v1/projects/${projectId}/issues`, data);
|
|
},
|
|
|
|
update: async (
|
|
projectId: string,
|
|
id: string,
|
|
data: UpdateIssueDto
|
|
): Promise<Issue> => {
|
|
return api.put<Issue>(`/api/v1/projects/${projectId}/issues/${id}`, data);
|
|
},
|
|
|
|
changeStatus: async (
|
|
projectId: string,
|
|
id: string,
|
|
status: string
|
|
): Promise<void> => {
|
|
return api.put<void>(
|
|
`/api/v1/projects/${projectId}/issues/${id}/status`,
|
|
{ status }
|
|
);
|
|
},
|
|
|
|
assign: async (
|
|
projectId: string,
|
|
id: string,
|
|
assigneeId: string | null
|
|
): Promise<void> => {
|
|
return api.put<void>(`/api/v1/projects/${projectId}/issues/${id}/assign`, {
|
|
assigneeId,
|
|
});
|
|
},
|
|
|
|
delete: async (projectId: string, id: string): Promise<void> => {
|
|
return api.delete<void>(`/api/v1/projects/${projectId}/issues/${id}`);
|
|
},
|
|
};
|