Skip to content

Commit 3b4dddd

Browse files
authored
feat/FE: add ws for remove member from task (#24)
1 parent 96f9f5e commit 3b4dddd

File tree

3 files changed

+41
-25
lines changed

3 files changed

+41
-25
lines changed

frontend/src/components/board/AssignMembers.tsx

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ interface AssignMembersProps {
1212
}
1313

1414
const AssignMembers: React.FC<AssignMembersProps> = (props) => {
15-
const {boardId} = useParams();
15+
const { boardId } = useParams();
1616
const [assignedMembers, setAssignedMembers] = useState<Member[]>(props?.assignedMembers || []);
1717
const [members, setMembers] = useState<Member[]>([])
1818
const [isOpen, setIsOpen] = useState(false);
@@ -31,24 +31,24 @@ const AssignMembers: React.FC<AssignMembersProps> = (props) => {
3131
}
3232

3333
const toggleAssign = async (member: Member) => {
34-
try {
35-
const isAssigned = assignedMembers.some(am => am.id === member.id);
36-
37-
if (isAssigned) {
38-
// remove
39-
await taskService.removeMember(Number(boardId), props.taskId, member.id);
40-
setAssignedMembers(prev => prev.filter(am => am.id !== member.id));
41-
notify.success(`${member.name} removed`);
42-
} else {
43-
// assign
44-
await taskService.assignMember(Number(boardId), props.taskId, member.id);
45-
setAssignedMembers(prev => [...prev, member]);
46-
notify.success(`${member.name} assigned`);
34+
try {
35+
const isAssigned = assignedMembers.some(am => am.id === member.id);
36+
37+
if (isAssigned) {
38+
// remove
39+
await taskService.removeMember(Number(boardId), props.taskId, member.id);
40+
setAssignedMembers(prev => prev.filter(am => am.id !== member.id));
41+
notify.success(`${member.name} removed`);
42+
} else {
43+
// assign
44+
await taskService.assignMember(Number(boardId), props.taskId, member.id);
45+
setAssignedMembers(prev => [...prev, member]);
46+
notify.success(`${member.name} assigned`);
47+
}
48+
} catch (error: any) {
49+
notify.error(error.response?.data?.message || "Something went wrong");
4750
}
48-
} catch (error: any) {
49-
notify.error(error.response?.data?.message || "Something went wrong");
50-
}
51-
};
51+
};
5252

5353
useEffect(() => {
5454
fetchMemebers();
@@ -164,7 +164,7 @@ const AssignMembers: React.FC<AssignMembersProps> = (props) => {
164164
<li
165165
key={m.id}
166166
onClick={() => toggleAssign(m)}
167-
className="flex items-center justify-between px-2 py-1 rounded bg-gray-800"
167+
className="flex items-center justify-between px-2 py-1 rounded bg-gray-800 cursor-pointer hover:bg-gray-700"
168168
>
169169
<span className="text-white">{m.name}</span>
170170
<span className="text-green-400 text-xs"></span>

frontend/src/store/slices/tasksSlice.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,20 @@ const tasksSlice = createSlice({
6363
assignedMemberToTask: (state, action: PayloadAction<{ taskId: number; memberId: number }>) => {
6464
const { taskId, memberId } = action.payload;
6565
const task = state.byId[taskId];
66-
if (task) {
66+
if (task && !task.memberIds.includes(memberId)) {
6767
task.memberIds.push(memberId);
6868
}
69+
},
70+
71+
removeMemberFromTask: (state, action: PayloadAction<{ taskId: number; userId: number }>) => {
72+
const { taskId, userId } = action.payload;
73+
const task = state.byId[taskId];
74+
if (task && task.memberIds.includes(userId)) {
75+
const index = task.memberIds.indexOf(userId);
76+
if (index !== -1) {
77+
task.memberIds.splice(index, 1);
78+
}
79+
}
6980
}
7081
}
7182
});
@@ -78,5 +89,6 @@ export const {
7889
taskRemoved,
7990
taskRestored,
8091
assignedMemberToTask,
92+
removeMemberFromTask
8193
} = tasksSlice.actions;
8294
export default tasksSlice.reducer;

frontend/src/websocket/boardHandler.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { RootState, AppDispatch } from "@/store";
33
import { columnArchived, archivedColumnRestored, columnDeleted } from "@/store/slices/archiveColumnsSlice";
44
import { taskArchived, taskDeleted, archivedTaskRestored } from "@/store/slices/archiveTasksSlice";
55
import { addTaskToColumn, columnCreated, columnRemoved, columnReplaced, columnRestored, columnUpdated, removeTaskFromColumn } from "@/store/slices/columnsSlice";
6-
import { assignedMemberToTask, taskCreated, taskRemoved, taskReplaced, taskRestored, taskUpdated } from "@/store/slices/tasksSlice";
6+
import { assignedMemberToTask, removeMemberFromTask, taskCreated, taskRemoved, taskReplaced, taskRestored, taskUpdated } from "@/store/slices/tasksSlice";
77

88
export const handleBoardWSMessage = (
99
message: any,
@@ -115,10 +115,14 @@ export const handleBoardWSMessage = (
115115
case "MEMBER_ASSIGNED_TO_TASK": {
116116
console.log("Member assigned to task", message);
117117
const { taskId, assignData }: { taskId: number, assignData: { userId: number, username: string } } = message.payload;
118-
const task = getState().tasks.byId[taskId];
119-
if (task && !task.memberIds.includes(assignData.userId)) {
120-
dispatch(assignedMemberToTask({ taskId, memberId: assignData.userId }));
121-
}
118+
dispatch(assignedMemberToTask({ taskId, memberId: assignData.userId }));
119+
break;
120+
}
121+
122+
case "MEMBER_UNASSIGNED_TO_TASK": {
123+
console.log("Member unassigned to task", message);
124+
const { taskId, userId } = message.payload;
125+
dispatch(removeMemberFromTask({ taskId, userId }));
122126
break;
123127
}
124128

0 commit comments

Comments
 (0)