@@ -11,15 +11,29 @@ import changeEpicListToStoryList from "../../utils/changeEpicListToStoryList";
11
11
import getDragElementIndex from "../../utils/getDragElementIndex" ;
12
12
import { BacklogSocketData } from "../../types/common/backlog" ;
13
13
import { BacklogDTO } from "../../types/DTO/backlogDTO" ;
14
- import DragContainer from "../../components/backlog/DragContainer" ;
14
+ import StoryDragContainer from "../../components/backlog/StoryDragContainer" ;
15
+ import TaskBlock from "../../components/backlog/TaskBlock" ;
16
+ import TaskDragContainer from "../../components/backlog/TaskDragContainer" ;
17
+ import TaskContainer from "../../components/backlog/TaskContainer" ;
18
+ import TaskHeader from "../../components/backlog/TaskHeader" ;
19
+ import TaskCreateBlock from "../../components/backlog/TaskCreateBlock" ;
15
20
16
21
const UnfinishedStoryPage = ( ) => {
17
22
const { socket, backlog } : { socket : Socket ; backlog : BacklogDTO } =
18
23
useOutletContext ( ) ;
19
24
const { showDetail, handleShowDetail } = useShowDetail ( ) ;
20
25
const [ storyElementIndex , setStoryElementIndex ] = useState < number > ( ) ;
26
+ const [ taskElementIndex , setTaskElementIndex ] = useState < {
27
+ storyId ?: number ;
28
+ taskIndex ?: number ;
29
+ } > ( {
30
+ storyId : undefined ,
31
+ taskIndex : undefined ,
32
+ } ) ;
33
+ const [ draggingStoryId , setDraggingStoryId ] = useState < number > ( ) ;
34
+ const [ draggingTaskId , setDraggingTaskId ] = useState < number > ( ) ;
21
35
const storyComponentRefList = useRef < HTMLDivElement [ ] > ( [ ] ) ;
22
- const draggingComponentIdRef = useRef < number > ( ) ;
36
+ const taskComponentRefList = useRef < HTMLDivElement [ ] [ ] > ( [ ] ) ;
23
37
const storyList = useMemo (
24
38
( ) =>
25
39
changeEpicListToStoryList ( backlog . epicList )
@@ -51,30 +65,44 @@ const UnfinishedStoryPage = () => {
51
65
storyComponentRefList . current [ index ] = element ;
52
66
} ;
53
67
68
+ const setTaskComponentRef =
69
+ ( storyIndex : number , taskIndex : number ) => ( element : HTMLDivElement ) => {
70
+ taskComponentRefList . current [ storyIndex ] [ taskIndex ] = element ;
71
+ } ;
72
+
54
73
const handleDragOver = ( event : DragEvent ) => {
74
+ if ( draggingTaskId ) {
75
+ return ;
76
+ }
77
+
55
78
event . preventDefault ( ) ;
56
79
const index = getDragElementIndex (
57
80
storyComponentRefList . current ,
58
- draggingComponentIdRef . current ,
81
+ storyList . findIndex ( ( { id } ) => id === draggingStoryId ) ,
59
82
event . clientY
60
83
) ;
61
84
62
85
setStoryElementIndex ( index ) ;
63
86
} ;
64
87
65
88
const handleDragStart = ( id : number ) => {
66
- draggingComponentIdRef . current = id ;
89
+ if ( draggingTaskId ) {
90
+ return ;
91
+ }
92
+ setDraggingStoryId ( id ) ;
67
93
} ;
68
94
69
95
const handleDragEnd = ( event : DragEvent ) => {
96
+ if ( draggingTaskId ) {
97
+ return ;
98
+ }
99
+
70
100
event . stopPropagation ( ) ;
71
- const targetIndex = storyList . findIndex (
72
- ( { id } ) => id === draggingComponentIdRef . current
73
- ) ;
101
+ const targetIndex = storyList . findIndex ( ( { id } ) => id === draggingStoryId ) ;
74
102
let rankValue ;
75
103
76
104
if ( storyElementIndex === targetIndex ) {
77
- draggingComponentIdRef . current = undefined ;
105
+ setDraggingStoryId ( undefined ) ;
78
106
setStoryElementIndex ( undefined ) ;
79
107
return ;
80
108
}
@@ -96,11 +124,11 @@ const UnfinishedStoryPage = () => {
96
124
}
97
125
98
126
emitStoryUpdateEvent ( {
99
- id : draggingComponentIdRef . current as number ,
127
+ id : draggingStoryId as number ,
100
128
rankValue,
101
129
} ) ;
102
130
103
- draggingComponentIdRef . current = undefined ;
131
+ setDraggingStoryId ( undefined ) ;
104
132
setStoryElementIndex ( undefined ) ;
105
133
} ;
106
134
@@ -113,7 +141,7 @@ const UnfinishedStoryPage = () => {
113
141
if (
114
142
domain === "story" &&
115
143
action === "delete" &&
116
- content . id === draggingComponentIdRef . current
144
+ content . id === draggingStoryId
117
145
) {
118
146
setStoryElementIndex ( undefined ) ;
119
147
}
@@ -126,6 +154,37 @@ const UnfinishedStoryPage = () => {
126
154
} ;
127
155
} , [ ] ) ;
128
156
157
+ const handleTaskDragOver = ( event : DragEvent , storyIndex : number ) => {
158
+ if ( draggingStoryId ) {
159
+ return ;
160
+ }
161
+
162
+ event . preventDefault ( ) ;
163
+ const mouseIndex = storyList [ storyIndex ] . taskList . findIndex (
164
+ ( { id } ) => id === draggingTaskId
165
+ ) ;
166
+
167
+ const index = getDragElementIndex (
168
+ taskComponentRefList . current [ storyIndex ] ,
169
+ mouseIndex ,
170
+ event . clientY
171
+ ) ;
172
+
173
+ setTaskElementIndex ( {
174
+ storyId : storyList [ storyIndex ] . id ,
175
+ taskIndex : index ,
176
+ } ) ;
177
+ } ;
178
+
179
+ const handleTaskDragStart = ( taskId : number ) => {
180
+ setDraggingTaskId ( taskId ) ;
181
+ } ;
182
+
183
+ const handleTaskDragEnd = ( ) => {
184
+ setDraggingTaskId ( undefined ) ;
185
+ setTaskElementIndex ( { storyId : undefined , taskIndex : undefined } ) ;
186
+ } ;
187
+
129
188
return (
130
189
< div className = "flex flex-col items-center gap-4" >
131
190
< div className = "w-full border-b" onDragOver = { handleDragOver } >
@@ -138,26 +197,63 @@ const UnfinishedStoryPage = () => {
138
197
100
139
198
)
140
199
: 0 ;
200
+ taskComponentRefList . current [ index ] = [ ] ;
141
201
142
202
return (
143
- < DragContainer
144
- index = { index }
145
- setRef = { setStoryComponentRef }
146
- onDragStart = { ( ) => handleDragStart ( id ) }
147
- onDragEnd = { handleDragEnd }
148
- currentlyDraggedOver = { index === storyElementIndex }
203
+ < div
204
+ className = "relative"
205
+ onDragOver = { ( event ) => handleTaskDragOver ( event , index ) }
149
206
>
150
- < StoryBlock
151
- { ...{ id, title, point, status, epic, progress, taskList } }
152
- taskExist = { taskList . length > 0 }
153
- epicList = { epicCategoryList }
154
- lastTaskRankValue = {
155
- taskList . length
156
- ? taskList [ taskList . length - 1 ] . rankValue
157
- : undefined
158
- }
159
- />
160
- </ DragContainer >
207
+ < StoryDragContainer
208
+ index = { index }
209
+ setRef = { setStoryComponentRef }
210
+ onDragStart = { ( ) => handleDragStart ( id ) }
211
+ onDragEnd = { handleDragEnd }
212
+ currentlyDraggedOver = { index === storyElementIndex }
213
+ >
214
+ < StoryBlock
215
+ key = { id }
216
+ { ...{ id, title, point, status, epic, progress } }
217
+ taskExist = { taskList . length > 0 }
218
+ epicList = { epicCategoryList }
219
+ />
220
+ </ StoryDragContainer >
221
+ < TaskContainer >
222
+ < TaskHeader />
223
+ { ...taskList . map ( ( task , taskIndex ) => (
224
+ < TaskDragContainer
225
+ storyIndex = { index }
226
+ taskIndex = { taskIndex }
227
+ setRef = { setTaskComponentRef }
228
+ onDragEnd = { handleTaskDragEnd }
229
+ onDragStart = { ( ) => handleTaskDragStart ( task . id ) }
230
+ currentlyDraggedOver = {
231
+ id === taskElementIndex . storyId &&
232
+ taskIndex === taskElementIndex . taskIndex
233
+ }
234
+ >
235
+ < TaskBlock key = { task . id } { ...task } />
236
+ </ TaskDragContainer >
237
+ ) ) }
238
+ < div
239
+ ref = { setTaskComponentRef ( index , taskList . length ) }
240
+ className = { `${
241
+ id === taskElementIndex . storyId &&
242
+ taskElementIndex . taskIndex === taskList . length
243
+ ? "w-[67.9rem] h-1 bg-blue-400"
244
+ : ""
245
+ } absolute`}
246
+ />
247
+ < TaskCreateBlock
248
+ storyId = { id }
249
+ lastTaskRankValue = {
250
+ taskList . length
251
+ ? taskList [ taskList . length - 1 ] . rankValue
252
+ : undefined
253
+ }
254
+ />
255
+ </ TaskContainer >
256
+ </ div >
161
257
) ;
162
258
}
163
259
) }
0 commit comments