Files
towercontrol/components/kanban/Board.tsx
Julien Froidefond 64cc665f78 feat: add task editing and title updating features
- Introduced `onEditTask` and `onUpdateTitle` props in `KanbanBoard`, `KanbanColumn`, and `TaskCard` components for enhanced task management.
- Implemented editing functionality in `TaskCard` to allow users to update task titles directly.
- Added `EditTaskForm` in `KanbanBoardContainer` to handle task editing state and submission.
- Updated `TasksService` to ensure all task properties can be modified during updates.
2025-09-14 08:56:41 +02:00

124 lines
3.4 KiB
TypeScript

'use client';
import { Task, TaskStatus } from '@/lib/types';
import { KanbanColumn } from './Column';
import { Button } from '@/components/ui/Button';
import { CreateTaskForm } from '@/components/forms/CreateTaskForm';
import { CreateTaskData } from '@/clients/tasks-client';
import { useMemo, useState } from 'react';
interface KanbanBoardProps {
tasks: Task[];
onCreateTask?: (data: CreateTaskData) => Promise<Task | null>;
onDeleteTask?: (taskId: string) => Promise<void>;
onEditTask?: (task: Task) => void;
onUpdateTitle?: (taskId: string, newTitle: string) => Promise<void>;
loading?: boolean;
}
export function KanbanBoard({ tasks, onCreateTask, onDeleteTask, onEditTask, onUpdateTitle, loading = false }: KanbanBoardProps) {
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
// Organiser les tâches par statut
const tasksByStatus = useMemo(() => {
const grouped = tasks.reduce((acc, task) => {
if (!acc[task.status]) {
acc[task.status] = [];
}
acc[task.status].push(task);
return acc;
}, {} as Record<TaskStatus, Task[]>);
return grouped;
}, [tasks]);
// Configuration des colonnes
const columns: Array<{
id: TaskStatus;
title: string;
color: string;
tasks: Task[];
}> = [
{
id: 'todo',
title: 'À faire',
color: 'gray',
tasks: tasksByStatus.todo || []
},
{
id: 'in_progress',
title: 'En cours',
color: 'blue',
tasks: tasksByStatus.in_progress || []
},
{
id: 'done',
title: 'Terminé',
color: 'green',
tasks: tasksByStatus.done || []
},
{
id: 'cancelled',
title: 'Annulé',
color: 'red',
tasks: tasksByStatus.cancelled || []
}
];
const handleCreateTask = async (data: CreateTaskData) => {
if (onCreateTask) {
await onCreateTask(data);
}
};
return (
<div className="h-full flex flex-col bg-slate-950">
{/* Header avec bouton nouvelle tâche */}
<div className="flex justify-between items-center p-6 pb-0">
<div className="flex items-center gap-3">
<div className="w-2 h-2 bg-cyan-400 rounded-full animate-pulse"></div>
<h2 className="text-lg font-mono font-bold text-slate-100 uppercase tracking-wider">
Kanban Board
</h2>
</div>
{onCreateTask && (
<Button
variant="primary"
onClick={() => setIsCreateModalOpen(true)}
disabled={loading}
>
+ Nouvelle tâche
</Button>
)}
</div>
{/* Board tech dark */}
<div className="flex-1 flex gap-6 overflow-x-auto p-6">
{columns.map((column) => (
<KanbanColumn
key={column.id}
id={column.id}
title={column.title}
color={column.color}
tasks={column.tasks}
onCreateTask={onCreateTask ? handleCreateTask : undefined}
onDeleteTask={onDeleteTask}
onEditTask={onEditTask}
onUpdateTitle={onUpdateTitle}
/>
))}
</div>
{/* Modal de création */}
{onCreateTask && (
<CreateTaskForm
isOpen={isCreateModalOpen}
onClose={() => setIsCreateModalOpen(false)}
onSubmit={handleCreateTask}
loading={loading}
/>
)}
</div>
);
}