From bbf9d695ba6a8a8fb8331aed92bd0f8eb5872e88 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Sun, 22 Feb 2026 09:42:22 +0100 Subject: [PATCH] =?UTF-8?q?Add=20inline=20task=20creation=20in=20=C3=A9tap?= =?UTF-8?q?es=20view?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Each étape shows an "Ajouter une tâche" button at the bottom when expanded - Clicking opens an inline text input with Enter to submit, Escape to cancel - Created tasks are linked to the étape via parent_task_id - Purple "Ajouter" button with instant feedback - Uses existing useCreateTask hook with correct tablo_id and parent_task_id Co-Authored-By: Claude Sonnet 4.6 (1M context) --- apps/main/src/pages/tablo-details.tsx | 135 +++++++++++++++++++------- 1 file changed, 101 insertions(+), 34 deletions(-) diff --git a/apps/main/src/pages/tablo-details.tsx b/apps/main/src/pages/tablo-details.tsx index 06915e3..68e6a25 100644 --- a/apps/main/src/pages/tablo-details.tsx +++ b/apps/main/src/pages/tablo-details.tsx @@ -29,7 +29,7 @@ import { TabloDiscussionSection } from "../components/TabloDiscussionSection"; import { TabloEventsSection } from "../components/TabloEventsSection"; import { TabloFilesSection } from "../components/TabloFilesSection"; import { TabloTasksSection } from "../components/TabloTasksSection"; -import { useAllTasks, useTabloEtapes } from "../hooks/tasks"; +import { useAllTasks, useCreateTask, useTabloEtapes } from "../hooks/tasks"; import { useTabloFileNames } from "../hooks/tablo_data"; import { useTablosList } from "../hooks/tablos"; @@ -459,7 +459,7 @@ export const TabloDetailsPage = () => { )} {activeSection === "etapes" && ( - + )} @@ -471,13 +471,18 @@ export const TabloDetailsPage = () => { function EtapesSection({ etapes, tabloTasks, + tabloId, }: { etapes: Etape[]; tabloTasks: KanbanTask[]; + tabloId: string; }) { const [expandedEtapes, setExpandedEtapes] = useState>( new Set(etapes.map((e) => e.id)), ); + const [addingTaskToEtape, setAddingTaskToEtape] = useState(null); + const [newTaskTitle, setNewTaskTitle] = useState(""); + const { mutate: createTask } = useCreateTask(); const toggleEtape = (id: string) => { setExpandedEtapes((prev) => { @@ -488,6 +493,21 @@ function EtapesSection({ }); }; + const handleAddTask = (etapeId: string) => { + const title = newTaskTitle.trim(); + if (!title || !tabloId) return; + createTask({ + tablo_id: tabloId, + title, + status: "todo", + parent_task_id: etapeId, + is_parent: false, + position: tabloTasks.filter((t) => t.parent_task_id === etapeId).length, + }); + setNewTaskTitle(""); + setAddingTaskToEtape(null); + }; + const statusConfig: Record = { todo: { label: "À faire", color: "bg-blue-100 text-blue-700 dark:bg-blue-950/30 dark:text-blue-400" }, in_progress: { label: "En cours", color: "bg-yellow-100 text-yellow-700 dark:bg-yellow-950/30 dark:text-yellow-400" }, @@ -575,40 +595,87 @@ function EtapesSection({ )} - {/* Child tasks */} - {isExpanded && childTasks.length > 0 && ( -
- {childTasks.map((task) => ( -
- {task.status === "done" ? ( - - ) : ( -
- )} - - {task.title} - - {task.status && ( - - {(statusConfig[task.status] ?? statusConfig.todo).label} - - )} + {/* Child tasks + add task */} + {isExpanded && ( +
+ {childTasks.length > 0 && ( +
+ {childTasks.map((task) => ( +
+ {task.status === "done" ? ( + + ) : ( +
+ )} + + {task.title} + + {task.status && ( + + {(statusConfig[task.status] ?? statusConfig.todo).label} + + )} +
+ ))}
- ))} -
- )} + )} - {isExpanded && childTasks.length === 0 && ( -
- Aucune tâche dans cette étape + {childTasks.length === 0 && addingTaskToEtape !== etape.id && ( +
+ Aucune tâche dans cette étape +
+ )} + + {/* Inline add task */} + {addingTaskToEtape === etape.id ? ( +
+
+ setNewTaskTitle(e.target.value)} + onKeyDown={(e) => { + if (e.key === "Enter") handleAddTask(etape.id); + if (e.key === "Escape") { setAddingTaskToEtape(null); setNewTaskTitle(""); } + }} + placeholder="Nom de la tâche..." + className="flex-1 text-sm bg-transparent border-none outline-none text-gray-900 dark:text-gray-100 placeholder-gray-400" + /> + + +
+ ) : ( + + )}
)}