Skip to content

Commit a7c0b4e

Browse files
committed
feat: 스토리를 닫힌 에픽으로 드롭하거나 태스크를 닫힌 스토리로 드롭할 시 가장 마지막에 추가되는 기능 추가
1 parent e1758e9 commit a7c0b4e

File tree

2 files changed

+82
-73
lines changed

2 files changed

+82
-73
lines changed

frontend/src/pages/backlog/EpicPage.tsx

Lines changed: 77 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,11 @@ const EpicPage = () => {
221221
};
222222

223223
const handleEpicDragEnd = (event: DragEvent) => {
224-
event.preventDefault();
225-
226224
if (draggingTaskId || draggingStoryId) {
227225
return;
228226
}
229227

228+
event.preventDefault();
230229
const targetIndex = epicList.findIndex(({ id }) => id === draggingEpicId);
231230
let rankValue;
232231

@@ -262,12 +261,11 @@ const EpicPage = () => {
262261
};
263262

264263
const handleStoryDragOver = (event: DragEvent, epicIndex: number) => {
265-
event.preventDefault();
266-
267264
if (draggingTaskId || draggingEpicId) {
268265
return;
269266
}
270267

268+
event.preventDefault();
271269
const mouseIndex = epicList[epicIndex].storyList.findIndex(
272270
({ id }) => id === draggingStoryId
273271
);
@@ -299,26 +297,26 @@ const EpicPage = () => {
299297
}
300298

301299
const { epicId, storyIndex } = storyElementIndex;
302-
const storyList = epicList.find(({ id }) => id === epicId)
303-
?.storyList as StoryDTO[];
300+
const targetEpic = epicList.find(({ id }) => id === epicId);
301+
const storyList = targetEpic?.storyList as StoryDTO[];
304302
const currentIndex = storyList?.findIndex(
305303
({ id }) => id === draggingStoryId
306304
);
307305

308306
let rankValue;
309307

310-
if (storyIndex === currentIndex) {
308+
if (storyIndex !== -1 && storyIndex === currentIndex) {
311309
setDraggingStoryId(undefined);
312310
setStoryElementIndex({ epicId: undefined, storyIndex: undefined });
313311
return;
314312
}
315313

316-
if (storyIndex === 0 && !storyList.length) {
314+
if ((storyIndex === -1 || storyIndex === 0) && !storyList.length) {
317315
rankValue = LexoRank.middle().toString();
318316
} else if (storyIndex === 0) {
319317
const firstStoryRank = storyList[0].rankValue;
320318
rankValue = LexoRank.parse(firstStoryRank).genPrev().toString();
321-
} else if (storyIndex === storyList.length) {
319+
} else if (storyIndex === -1 || storyIndex === storyList.length) {
322320
const lastStoryRank = storyList[storyList.length - 1].rankValue;
323321
rankValue = LexoRank.parse(lastStoryRank).genNext().toString();
324322
} else {
@@ -341,61 +339,16 @@ const EpicPage = () => {
341339
setStoryElementIndex({ epicId: undefined, storyIndex: undefined });
342340
};
343341

344-
useEffect(() => {
345-
const handleDragEvent = ({
346-
domain,
347-
action,
348-
content,
349-
}: BacklogSocketData) => {
350-
if (
351-
domain === "epic" &&
352-
action === "delete" &&
353-
content.id === draggingEpicId
354-
) {
355-
setEpicElementIndex(undefined);
356-
return;
357-
}
358-
359-
if (
360-
domain === "story" &&
361-
action === "delete" &&
362-
content.id === draggingStoryId
363-
) {
364-
setStoryElementIndex({ epicId: undefined, storyIndex: undefined });
365-
366-
return;
367-
}
368-
369-
if (
370-
domain === "task" &&
371-
action === "delete" &&
372-
content.id === draggingTaskId
373-
) {
374-
setTaskElementIndex({
375-
epicId: undefined,
376-
storyId: undefined,
377-
taskIndex: undefined,
378-
});
379-
}
380-
};
381-
382-
socket.on("backlog", handleDragEvent);
383-
384-
return () => {
385-
socket.off("backlog", handleDragEvent);
386-
};
387-
}, []);
388-
389342
const handleTaskDragOver = (
390343
event: DragEvent,
391344
epicIndex: number,
392345
storyIndex: number
393346
) => {
394-
event.preventDefault();
395-
396347
if (draggingStoryId || draggingEpicId) {
397348
return;
398349
}
350+
351+
event.preventDefault();
399352
const { storyList } = epicList[epicIndex];
400353

401354
const mouseIndex = storyList[storyIndex].taskList.findIndex(
@@ -425,15 +378,14 @@ const EpicPage = () => {
425378

426379
const handleTaskDragEnd = () => {
427380
const { epicId, storyId, taskIndex } = taskElementIndex;
428-
const storyList = epicList.find(({ id }) => epicId === id)
429-
?.storyList as StoryDTO[];
430-
const taskList = storyList.find(({ id }) => id === storyId)
431-
?.taskList as TaskDTO[];
381+
const targetEpic = epicList.find(({ id }) => epicId === id);
382+
const targetStory = targetEpic?.storyList.find(({ id }) => id === storyId);
383+
const taskList = targetStory?.taskList as TaskDTO[];
432384
const currentIndex = taskList?.findIndex(({ id }) => id === draggingTaskId);
433385

434386
let rankValue;
435387

436-
if (taskIndex === currentIndex) {
388+
if (!taskIndex || (taskIndex !== -1 && taskIndex === currentIndex)) {
437389
setDraggingTaskId(undefined);
438390
setTaskElementIndex({
439391
epicId: undefined,
@@ -443,12 +395,12 @@ const EpicPage = () => {
443395
return;
444396
}
445397

446-
if (taskIndex === 0 && !taskList.length) {
398+
if ((taskIndex === -1 || taskIndex === 0) && !taskList.length) {
447399
rankValue = LexoRank.middle().toString();
448400
} else if (taskIndex === 0) {
449401
const firstTaskRank = taskList[0].rankValue;
450402
rankValue = LexoRank.parse(firstTaskRank).genPrev().toString();
451-
} else if (taskIndex === taskList.length) {
403+
} else if (taskIndex === -1 || taskIndex === taskList.length) {
452404
const lastTaskRank = taskList[taskList.length - 1].rankValue;
453405
rankValue = LexoRank.parse(lastTaskRank).genNext().toString();
454406
} else {
@@ -475,6 +427,59 @@ const EpicPage = () => {
475427
});
476428
};
477429

430+
const handleDropTaskOnEpic = () => {
431+
setTaskElementIndex({
432+
epicId: undefined,
433+
storyId: undefined,
434+
taskIndex: undefined,
435+
});
436+
};
437+
438+
useEffect(() => {
439+
const handleDragEvent = ({
440+
domain,
441+
action,
442+
content,
443+
}: BacklogSocketData) => {
444+
if (
445+
domain === "epic" &&
446+
action === "delete" &&
447+
content.id === draggingEpicId
448+
) {
449+
setEpicElementIndex(undefined);
450+
return;
451+
}
452+
453+
if (
454+
domain === "story" &&
455+
action === "delete" &&
456+
content.id === draggingStoryId
457+
) {
458+
setStoryElementIndex({ epicId: undefined, storyIndex: undefined });
459+
460+
return;
461+
}
462+
463+
if (
464+
domain === "task" &&
465+
action === "delete" &&
466+
content.id === draggingTaskId
467+
) {
468+
setTaskElementIndex({
469+
epicId: undefined,
470+
storyId: undefined,
471+
taskIndex: undefined,
472+
});
473+
}
474+
};
475+
476+
socket.on("backlog", handleDragEvent);
477+
478+
return () => {
479+
socket.off("backlog", handleDragEvent);
480+
};
481+
}, []);
482+
478483
return (
479484
<div className="gap-4 pb-10 border-t" onDragOver={handleEpicDragOver}>
480485
{!epicList.length && (
@@ -494,7 +499,11 @@ const EpicPage = () => {
494499
taskComponentRefList.current[epicIndex] = [];
495500

496501
return (
497-
<div className="py-2 border-t border-b">
502+
<div
503+
className="py-2 border-t border-b"
504+
onDragOver={(event) => handleStoryDragOver(event, epicIndex)}
505+
onDrop={handleDropTaskOnEpic}
506+
>
498507
<EpicDragContainer
499508
{...{ epicIndex }}
500509
onDragStart={() => handleEpicDragStart(epicId)}
@@ -511,10 +520,7 @@ const EpicPage = () => {
511520
/>
512521
</EpicDragContainer>
513522
{showStory[epicId]?.showStoryList && (
514-
<div
515-
className="w-[65rem] ml-auto"
516-
onDragOver={(event) => handleStoryDragOver(event, epicIndex)}
517-
>
523+
<div className="w-[65rem] ml-auto">
518524
{...storyList.map(
519525
(
520526
{ id: storyId, title, point, status, taskList },
@@ -536,6 +542,9 @@ const EpicPage = () => {
536542
onDragOver={(event) =>
537543
handleTaskDragOver(event, epicIndex, storyIndex)
538544
}
545+
onDrop={(event) => {
546+
event.stopPropagation();
547+
}}
539548
>
540549
<EpicPageStoryDragContainer
541550
{...{ epicIndex, storyIndex }}

frontend/src/pages/backlog/UnfinishedStoryPage.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,24 +221,24 @@ const UnfinishedStoryPage = () => {
221221

222222
const handleTaskDragEnd = () => {
223223
const { storyId, taskIndex } = taskElementIndex;
224-
const taskList = storyList.find(({ id }) => id === storyId)
225-
?.taskList as TaskDTO[];
224+
const targetStory = storyList.find(({ id }) => id === storyId);
225+
const taskList = targetStory?.taskList as TaskDTO[];
226226
const targetIndex = taskList?.findIndex(({ id }) => id === draggingTaskId);
227227

228228
let rankValue;
229229

230-
if (taskIndex === targetIndex) {
230+
if (taskIndex !== -1 && taskIndex === targetIndex) {
231231
setDraggingTaskId(undefined);
232232
setTaskElementIndex({ storyId: undefined, taskIndex: undefined });
233233
return;
234234
}
235235

236-
if (taskIndex === 0 && !taskList.length) {
236+
if ((taskIndex === -1 || taskIndex === 0) && !taskList.length) {
237237
rankValue = LexoRank.middle().toString();
238238
} else if (taskIndex === 0) {
239239
const firstTaskRank = taskList[0].rankValue;
240240
rankValue = LexoRank.parse(firstTaskRank).genPrev().toString();
241-
} else if (taskIndex === taskList.length) {
241+
} else if (taskIndex === -1 || taskIndex === taskList.length) {
242242
const lastTaskRank = taskList[taskList.length - 1].rankValue;
243243
rankValue = LexoRank.parse(lastTaskRank).genNext().toString();
244244
} else {

0 commit comments

Comments
 (0)