diff --git a/TODO.md b/TODO.md index 5b2e8c5..378dbfe 100644 --- a/TODO.md +++ b/TODO.md @@ -148,7 +148,7 @@ - [x] Refactorer les couleurs des priorités dans un seul endroit - [x] Settings synchro Jira : ajouter une liste de projet à ignorer, doit etre pris en compte par le service bien sur - [x] Faire des pages à part entière pour les sous-pages de la page config + SSR -- [ ] Afficher dans l'édition de task les todo reliés. Pouvoir en ajouter directement avec une date ou sans. +- [x] Afficher dans l'édition de task les todo reliés. Pouvoir en ajouter directement avec une date ou sans. - [ ] Dans les titres de colonnes des swimlanes, je n'ai pas les couleurs des statuts - [ ] Système de sauvegarde automatique base de données - [ ] Sauvegarde automatique toutes les 6 heures (configurable) diff --git a/clients/tasks-client.ts b/clients/tasks-client.ts index b8d2fd7..364b51b 100644 --- a/clients/tasks-client.ts +++ b/clients/tasks-client.ts @@ -1,5 +1,5 @@ import { httpClient } from './base/http-client'; -import { Task, TaskStatus, TaskPriority, TaskStats } from '@/lib/types'; +import { Task, TaskStatus, TaskPriority, TaskStats, DailyCheckbox } from '@/lib/types'; export interface TaskFilters { status?: TaskStatus[]; @@ -65,6 +65,14 @@ export class TasksClient { return httpClient.get('/tasks', params); } + /** + * Récupère les daily checkboxes liées à une tâche + */ + async getTaskCheckboxes(taskId: string): Promise { + const response = await httpClient.get<{ data: DailyCheckbox[] }>(`/tasks/${taskId}/checkboxes`); + return response.data; + } + // Note: Les méthodes createTask, updateTask et deleteTask ont été migrées vers Server Actions // Voir /src/actions/tasks.ts pour createTask, updateTask, updateTaskTitle, updateTaskStatus, deleteTask } diff --git a/components/forms/EditTaskForm.tsx b/components/forms/EditTaskForm.tsx index c6d4fbf..0ad1b89 100644 --- a/components/forms/EditTaskForm.tsx +++ b/components/forms/EditTaskForm.tsx @@ -5,6 +5,7 @@ import { Modal } from '@/components/ui/Modal'; import { Button } from '@/components/ui/Button'; import { Input } from '@/components/ui/Input'; import { TagInput } from '@/components/ui/TagInput'; +import { RelatedTodos } from '@/components/forms/RelatedTodos'; import { Task, TaskPriority, TaskStatus } from '@/lib/types'; // UpdateTaskData removed - using Server Actions directly import { getAllStatuses, getAllPriorities } from '@/lib/status-config'; @@ -95,7 +96,7 @@ export function EditTaskForm({ isOpen, onClose, onSubmit, task, loading = false return ( -
+ {/* Titre */} + {/* Todos reliés */} + + {/* Actions */}
+ ) : ( +
+
+
+ Nouveau todo +
+ +
+ + setNewTodoText(e.target.value)} + disabled={isPending} + autoFocus + /> + +
+ setNewTodoDate(e.target.value)} + disabled={isPending} + placeholder="Date (optionnel)" + className="flex-1" + /> + +
+ + {!newTodoDate && ( +
+ 💡 Sans date, le todo sera ajouté à aujourd'hui +
+ )} +
+ )} +
+ + ); +} diff --git a/services/tasks.ts b/services/tasks.ts index a242099..9152887 100644 --- a/services/tasks.ts +++ b/services/tasks.ts @@ -1,5 +1,5 @@ import { prisma } from './database'; -import { Task, TaskStatus, TaskPriority, TaskSource, BusinessError } from '@/lib/types'; +import { Task, TaskStatus, TaskPriority, TaskSource, BusinessError, DailyCheckbox, DailyCheckboxType } from '@/lib/types'; import { Prisma } from '@prisma/client'; /** @@ -185,6 +185,50 @@ export class TasksService { return this.updateTask(taskId, { status: newStatus }); } + /** + * Récupère les daily checkboxes liées à une tâche + */ + async getTaskRelatedCheckboxes(taskId: string): Promise { + const checkboxes = await prisma.dailyCheckbox.findMany({ + where: { taskId: taskId }, + include: { task: true }, + orderBy: [ + { date: 'desc' }, + { order: 'asc' } + ] + }); + + return checkboxes.map(checkbox => ({ + id: checkbox.id, + date: checkbox.date, + text: checkbox.text, + isChecked: checkbox.isChecked, + type: checkbox.type as DailyCheckboxType, + order: checkbox.order, + taskId: checkbox.taskId ?? undefined, + task: checkbox.task ? { + id: checkbox.task.id, + title: checkbox.task.title, + description: checkbox.task.description ?? undefined, + status: checkbox.task.status as TaskStatus, + priority: checkbox.task.priority as TaskPriority, + source: checkbox.task.source as TaskSource, + sourceId: checkbox.task.sourceId ?? undefined, + tags: [], // Les tags ne sont pas nécessaires dans ce contexte + dueDate: checkbox.task.dueDate ?? undefined, + completedAt: checkbox.task.completedAt ?? undefined, + createdAt: checkbox.task.createdAt, + updatedAt: checkbox.task.updatedAt, + jiraProject: checkbox.task.jiraProject ?? undefined, + jiraKey: checkbox.task.jiraKey ?? undefined, + jiraType: checkbox.task.jiraType ?? undefined, + assignee: checkbox.task.assignee ?? undefined + } : undefined, + createdAt: checkbox.createdAt, + updatedAt: checkbox.updatedAt + })); + } + /** * Récupère les statistiques des tâches */ diff --git a/src/actions/daily.ts b/src/actions/daily.ts index 16cb4c3..d1835dd 100644 --- a/src/actions/daily.ts +++ b/src/actions/daily.ts @@ -1,7 +1,7 @@ 'use server'; import { dailyService } from '@/services/daily'; -import { UpdateDailyCheckboxData, DailyCheckbox } from '@/lib/types'; +import { UpdateDailyCheckboxData, DailyCheckbox, CreateDailyCheckboxData } from '@/lib/types'; import { revalidatePath } from 'next/cache'; /** @@ -198,6 +198,40 @@ export async function deleteCheckbox(checkboxId: string): Promise<{ } } +/** + * Ajoute un todo lié à une tâche + */ +export async function addTodoToTask(taskId: string, text: string, date?: Date): Promise<{ + success: boolean; + data?: DailyCheckbox; + error?: string; +}> { + try { + const targetDate = date || new Date(); + targetDate.setHours(0, 0, 0, 0); + + const checkboxData: CreateDailyCheckboxData = { + date: targetDate, + text: text.trim(), + type: 'task', + taskId: taskId, + isChecked: false + }; + + const checkbox = await dailyService.addCheckbox(checkboxData); + + revalidatePath('/daily'); + revalidatePath('/kanban'); + return { success: true, data: checkbox }; + } catch (error) { + console.error('Erreur addTodoToTask:', error); + return { + success: false, + error: error instanceof Error ? error.message : 'Erreur inconnue' + }; + } +} + /** * Réorganise les checkboxes d'une date */ diff --git a/src/app/api/tasks/[id]/checkboxes/route.ts b/src/app/api/tasks/[id]/checkboxes/route.ts new file mode 100644 index 0000000..01745ad --- /dev/null +++ b/src/app/api/tasks/[id]/checkboxes/route.ts @@ -0,0 +1,28 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { tasksService } from '@/services/tasks'; + +export async function GET( + request: NextRequest, + { params }: { params: Promise<{ id: string }> } +) { + try { + const { id } = await params; + + if (!id) { + return NextResponse.json( + { error: 'ID de tâche requis' }, + { status: 400 } + ); + } + + const checkboxes = await tasksService.getTaskRelatedCheckboxes(id); + + return NextResponse.json({ data: checkboxes }); + } catch (error) { + console.error('Erreur lors de la récupération des checkboxes:', error); + return NextResponse.json( + { error: 'Erreur lors de la récupération des checkboxes' }, + { status: 500 } + ); + } +}