diff --git a/src/pages/project/KanbanPage.tsx b/src/pages/project/KanbanPage.tsx index 7487d2fb..0bd318d6 100644 --- a/src/pages/project/KanbanPage.tsx +++ b/src/pages/project/KanbanPage.tsx @@ -7,17 +7,34 @@ import { TASK_DUMMY } from '@mocks/mockData'; import type { DropResult } from '@hello-pangea/dnd'; import type { Task, TaskWithStatus } from '@/types/TaskType'; +const DND_TYPE = { + STATUS: 'STATUS', + TASK: 'TASK', +}; + // ToDo: 유틸리티로 분리할지 고려하기 function generatorPrefixId(id: number | string, prefix: string, delimiter: string = '-') { - const result = prefix + delimiter + id; - return result; + return `${prefix}${delimiter}${id}`; } function parserPrefixId(prefixId: string, delimiter: string = '-') { const result = prefixId.split(delimiter); return result[result.length - 1]; } -function createChangedStatusTasks(statusTasks: TaskWithStatus[], dropResult: DropResult, isSameStatus: boolean) { +function createChangedStatus(statusTasks: TaskWithStatus[], dropResult: DropResult) { + const { source, destination } = dropResult; + + if (!destination) throw Error('Error: DnD destination is null'); + + const newStatusTasks = deepClone(statusTasks); + const stausTask = newStatusTasks[source.index]; + newStatusTasks.splice(source.index, 1); + newStatusTasks.splice(destination.index, 0, stausTask); + newStatusTasks.forEach((status, index) => (status.order = index + 1)); + return newStatusTasks; +} + +function createChangedTasks(statusTasks: TaskWithStatus[], dropResult: DropResult, isSameStatus: boolean) { const { source, destination, draggableId } = dropResult; // ToDo: 메세지 포맷 정하고 수정하기 @@ -43,81 +60,100 @@ function createChangedStatusTasks(statusTasks: TaskWithStatus[], dropResult: Dro return newStatusTasks; } -// ToDo: 할일 상태 Vertical DnD 추가할 것 // ToDo: DnD시 가시성을 위한 애니메이션 처리 추가할 것 // ToDo: 칸반보드 ItemList, Item 컴포넌트로 분리할 것 export default function KanbanPage() { const [statusTasks, setStatusTasks] = useState(TASK_DUMMY); const handleDragEnd = (dropResult: DropResult) => { - const { source, destination } = dropResult; + const { source, destination, type } = dropResult; if (!destination) return; + if (source.droppableId === destination.droppableId && source.index === destination.index) return; - const isSameStatus = source.droppableId === destination.droppableId; - const isSameTask = source.index === destination.index; - if (isSameStatus && isSameTask) return; + if (type === DND_TYPE.STATUS) { + const newStatusTasks = createChangedStatus(statusTasks, dropResult); + return setStatusTasks(newStatusTasks); + } - const newStatusTasks = createChangedStatusTasks(statusTasks, dropResult, isSameStatus); - setStatusTasks(newStatusTasks); + if (type === DND_TYPE.TASK) { + const isSameStatus = source.droppableId === destination.droppableId; + const newStatusTasks = createChangedTasks(statusTasks, dropResult, isSameStatus); + return setStatusTasks(newStatusTasks); + } }; return ( -
- - {statusTasks.map((data) => { - const { statusId, name, color, tasks } = data; - const droppableId = generatorPrefixId(statusId, 'status'); - return ( -
-
-

{name}

- - - -
-
- - {(dropProvided) => { - return ( -
- {tasks.map((task) => { - const { taskId, name, order } = task; - const draggableId = generatorPrefixId(taskId, 'task'); - const index = order - 1; - return ( - - {(dragProvided) => { - return ( -
-
-
{name}
-
- ); - }} - - ); - })} - {dropProvided.placeholder} -
- ); - }} -
-
-
- ); - })} -
-
+ + + {(statusDropProvided) => ( +
+ {statusTasks.map((data) => { + const { statusId, name, color, order, tasks } = data; + const draggableId = generatorPrefixId(statusId, 'status-drag'); + const droppableId = generatorPrefixId(statusId, 'status'); + const index = order - 1; + return ( + + {(statusDragProvided) => ( +
+
+

{name}

+ + + +
+ + {(taskDropProvided) => ( +
+ {tasks.map((task) => { + const { taskId, name, order } = task; + const draggableId = generatorPrefixId(taskId, 'task'); + const index = order - 1; + return ( + + {(dragProvided) => ( +
+
+
+ {name} +
+
+ )} + + ); + })} + {taskDropProvided.placeholder} +
+ )} +
+
+ )} +
+ ); + })} + {statusDropProvided.placeholder} +
+ )} +
+
); }