From fd052fb613a610653abdc6ef3217d38df6e21c25 Mon Sep 17 00:00:00 2001 From: sosokker Date: Thu, 23 Nov 2023 13:14:24 +0700 Subject: [PATCH] Completely remove drag functionality of column --- .../kanbanBoard/columnContainer.jsx | 21 +-- .../components/kanbanBoard/kanbanBoard.jsx | 177 +++++++++--------- 2 files changed, 93 insertions(+), 105 deletions(-) diff --git a/frontend/src/components/kanbanBoard/columnContainer.jsx b/frontend/src/components/kanbanBoard/columnContainer.jsx index 5b9648e..d6f4565 100644 --- a/frontend/src/components/kanbanBoard/columnContainer.jsx +++ b/frontend/src/components/kanbanBoard/columnContainer.jsx @@ -4,28 +4,13 @@ import { useMemo } from "react"; import { TaskCard } from "./taskCard"; export function ColumnContainer({ column, createTask, tasks, deleteTask, updateTask }) { + // Memoize task IDs to prevent unnecessary recalculations const tasksIds = useMemo(() => { return tasks.map((task) => task.id); }, [tasks]); - const { - setNodeRef: columnNodeRef, - attributes: columnAttributes, - listeners: columnListeners, - } = useSortable({ - id: column.id, - data: { - type: "Column", - column, - }, - disabled: true, // Disable drag for the entire column - }); - return (
+ {/* Provide a SortableContext for the tasks within the column */} + {/* Render TaskCard for each task in the column */} {tasks.map((task) => ( useSortable({ ...props, disabled: false })} /> ))} diff --git a/frontend/src/components/kanbanBoard/kanbanBoard.jsx b/frontend/src/components/kanbanBoard/kanbanBoard.jsx index 69cf2f4..ca393c5 100644 --- a/frontend/src/components/kanbanBoard/kanbanBoard.jsx +++ b/frontend/src/components/kanbanBoard/kanbanBoard.jsx @@ -8,14 +8,13 @@ import { axiosInstance } from "src/api/AxiosConfig"; export function KanbanBoard() { const [columns, setColumns] = useState([]); - const columnsId = useMemo(() => columns.map((col) => col.id), [columns]); const [boardId, setBoardData] = useState(); const [isLoading, setLoading] = useState(false); const [tasks, setTasks] = useState([]); - - const [activeColumn, setActiveColumn] = useState(null); - const [activeTask, setActiveTask] = useState(null); + const columnsId = useMemo(() => columns.map((col) => col.id), [columns]); + + // ---------------- END STATE INITIATE ---------------- const sensors = useSensors( useSensor(PointerSensor, { @@ -25,6 +24,76 @@ export function KanbanBoard() { }) ); + // ---------------- Task Handlers ---------------- + const handleTaskUpdate = (tasks, setTasks, updatedTask) => { + const updatedTasks = tasks.map((task) => (task.id === updatedTask.id ? updatedTask : task)); + setTasks(updatedTasks); + }; + + const handleApiError = (error, action) => { + console.error(`Error ${action}:`, error); + }; + + const createTask = async (columnId, setTasks) => { + try { + const response = await axiosInstance.post("todo/", { + title: `Task ${tasks.length + 1}`, + importance: 1, + difficulty: 1, + challenge: false, + fromSystem: false, + is_active: false, + is_full_day_event: false, + completed: false, + priority: 1, + list_board: columnId, + }); + + const newTask = { + id: response.data.id, + columnId, + content: response.data.title, + }; + + setTasks((tasks) => [...tasks, newTask]); + } catch (error) { + handleApiError(error, "creating task"); + } + }; + + const deleteTask = async (id, tasks, setTasks) => { + try { + await axiosInstance.delete(`todo/${id}/`); + const newTasks = tasks.filter((task) => task.id !== id); + setTasks(newTasks); + } catch (error) { + handleApiError(error, "deleting task"); + } + }; + + const updateTask = async (id, content, tasks, setTasks) => { + try { + if (content === "") { + await deleteTask(id, tasks, setTasks); + } else { + const response = await axiosInstance.put(`todo/${id}/`, { content }); + + const updatedTask = { + id, + columnId: response.data.list_board, + content: response.data.title, + }; + + handleTaskUpdate(tasks, setTasks, updatedTask); + } + } catch (error) { + handleApiError(error, "updating task"); + } + }; + + // ---------------- END Task Handlers ---------------- + + // ---------------- Fetch Data ---------------- useEffect(() => { const fetchData = async () => { try { @@ -88,6 +157,8 @@ export function KanbanBoard() { fetchBoardData(); }, []); + // ---------------- END Fetch Data ---------------- + return (
- {activeColumn && ( - task.columnId === activeColumn.id)} - /> - )} {activeTask && } , document.body @@ -140,97 +202,31 @@ export function KanbanBoard() {
); - function createTask(columnId, setTasks) { - const newTaskData = { - title: `Task ${tasks.length + 1}`, - importance: 1, - difficulty: 1, - challenge: false, - fromSystem: false, - is_active: false, - is_full_day_event: false, - completed: false, - priority: 1, - list_board: columnId, - }; - - axiosInstance - .post("todo/", newTaskData) - .then((response) => { - const newTask = { - id: response.data.id, - columnId, - content: response.data.title, - }; - }) - .catch((error) => { - console.error("Error creating task:", error); - }); - setTasks((tasks) => [...tasks, newTask]); - } - - function deleteTask(id) { - const newTasks = tasks.filter((task) => task.id !== id); - axiosInstance - .delete(`todo/${id}/`) - .then((response) => { - setTasks(newTasks); - }) - .catch((error) => { - console.error("Error deleting Task:", error); - }); - setTasks(newTasks); - } - - function updateTask(id, content) { - const newTasks = tasks.map((task) => { - if (task.id !== id) return task; - return { ...task, content }; - }); - if (content === "") return deleteTask(id); - setTasks(newTasks); - } - + // Handle the start of a drag event function onDragStart(event) { - if (event.active.data.current?.type === "Column") { - setActiveColumn(event.active.data.current.column); - return; - } - + // Check if the dragged item is a Task if (event.active.data.current?.type === "Task") { setActiveTask(event.active.data.current.task); return; } } + // Handle the end of a drag event function onDragEnd(event) { - setActiveColumn(null); + // Reset active column and task after the drag ends setActiveTask(null); const { active, over } = event; - if (!over) return; + if (!over) return; // If not dropped over anything, exit const activeId = active.id; const overId = over.id; - const isActiveAColumn = active.data.current?.type === "Column"; const isActiveATask = active.data.current?.type === "Task"; const isOverAColumn = over.data.current?.type === "Column"; const isOverATask = over.data.current?.type === "Task"; - // Reorder columns if the dragged item is a column - if (isActiveAColumn && isOverAColumn) { - setColumns((columns) => { - const activeColumnIndex = columns.findIndex((col) => col.id === activeId); - const overColumnIndex = columns.findIndex((col) => col.id === overId); - - const reorderedColumns = arrayMove(columns, activeColumnIndex, overColumnIndex); - - return reorderedColumns; - }); - } - - // Reorder tasks within the same column + // Reorder logic for Tasks within the same column if (isActiveATask && isOverATask) { setTasks((tasks) => { const activeIndex = tasks.findIndex((t) => t.id === activeId); @@ -249,6 +245,7 @@ export function KanbanBoard() { tasks[activeIndex].columnId = overId; + // API call to update task's columnId axiosInstance .put(`todo/change_task_list_board/`, { todo_id: activeId, new_list_board_id: overId, new_index: 0 }) .then((response) => {}) @@ -261,25 +258,28 @@ export function KanbanBoard() { } } + // Handle the drag-over event function onDragOver(event) { const { active, over } = event; - if (!over) return; + if (!over) return; // If not over anything, exit const activeId = active.id; const overId = over.id; - if (activeId === overId) return; + if (activeId === overId) return; // If over the same element, exit const isActiveATask = active.data.current?.type === "Task"; const isOverATask = over.data.current?.type === "Task"; - if (!isActiveATask) return; + if (!isActiveATask) return; // If not dragging a Task, exit + // Reorder logic for Tasks within the same column if (isActiveATask && isOverATask) { setTasks((tasks) => { const activeIndex = tasks.findIndex((t) => t.id === activeId); const overIndex = tasks.findIndex((t) => t.id === overId); + // If moving to a different column, update columnId if (tasks[activeIndex].columnId !== tasks[overIndex].columnId) { tasks[activeIndex].columnId = tasks[overIndex].columnId; return arrayMove(tasks, activeIndex, overIndex - 1); @@ -291,6 +291,7 @@ export function KanbanBoard() { const isOverAColumn = over.data.current?.type === "Column"; + // Move the Task to a different column and update columnId if (isActiveATask && isOverAColumn) { setTasks((tasks) => { const activeIndex = tasks.findIndex((t) => t.id === activeId);