feat: добавление работы с пользователями
- добавление участников в канбан доску - назначение исполнителя на задачу - снятие исполнителя с задачи
This commit is contained in:
@@ -31,3 +31,15 @@ export const deleteTaskAPI = async (taskId) => {
|
|||||||
data: { id: taskId }
|
data: { id: taskId }
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const assignMemberAPI = async (updateData) => {
|
||||||
|
return axios.put('/api/boards/categories/tasks/assign', updateData);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const unassignMemberAPI = async (updateData) => {
|
||||||
|
return axios.put('/api/boards/categories/tasks/unassign', updateData);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const addMemberAPI = async (updateData) => {
|
||||||
|
return axios.post('/api/boards/members/add', updateData);
|
||||||
|
};
|
||||||
@@ -7,7 +7,10 @@ import {
|
|||||||
updateTaskAPI,
|
updateTaskAPI,
|
||||||
updateCategoryAPI,
|
updateCategoryAPI,
|
||||||
deleteCategoryAPI,
|
deleteCategoryAPI,
|
||||||
deleteTaskAPI
|
deleteTaskAPI,
|
||||||
|
assignMemberAPI,
|
||||||
|
unassignMemberAPI,
|
||||||
|
addMemberAPI
|
||||||
} from './BoardAPI';
|
} from './BoardAPI';
|
||||||
|
|
||||||
export const useBoardLogic = (id, setError, setInfo, setCategories, setLoading) => {
|
export const useBoardLogic = (id, setError, setInfo, setCategories, setLoading) => {
|
||||||
@@ -88,6 +91,7 @@ export const useBoardLogic = (id, setError, setInfo, setCategories, setLoading)
|
|||||||
update_method: 'category',
|
update_method: 'category',
|
||||||
value: Number(taskCategory)
|
value: Number(taskCategory)
|
||||||
});
|
});
|
||||||
|
|
||||||
await loadBoardData();
|
await loadBoardData();
|
||||||
modalEditTask({}, null)();
|
modalEditTask({}, null)();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -147,6 +151,45 @@ export const useBoardLogic = (id, setError, setInfo, setCategories, setLoading)
|
|||||||
}
|
}
|
||||||
}, [loadBoardData, setLoading, setError]);
|
}, [loadBoardData, setLoading, setError]);
|
||||||
|
|
||||||
|
const assignMember = useCallback(async (editedTaskId, memberId, act, modalAssignMember) => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
if (act) {
|
||||||
|
await assignMemberAPI({
|
||||||
|
id: editedTaskId,
|
||||||
|
member_id: memberId
|
||||||
|
});
|
||||||
|
} else if (!act) {
|
||||||
|
await unassignMemberAPI({
|
||||||
|
id: editedTaskId,
|
||||||
|
member_id: memberId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await loadBoardData();
|
||||||
|
modalAssignMember();
|
||||||
|
} catch {
|
||||||
|
setError('Ошибка');
|
||||||
|
} finally{
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, [loadBoardData, setLoading, setError]);
|
||||||
|
|
||||||
|
const addMember = useCallback(async (username, boardId, modalAddMember) => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
await addMemberAPI({
|
||||||
|
username: username,
|
||||||
|
board_id: boardId
|
||||||
|
});
|
||||||
|
await loadBoardData();
|
||||||
|
modalAddMember();
|
||||||
|
} catch {
|
||||||
|
setError('Ошибка');
|
||||||
|
} finally{
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, [loadBoardData, setLoading, setError]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
loadBoardData,
|
loadBoardData,
|
||||||
createTask,
|
createTask,
|
||||||
@@ -154,6 +197,8 @@ export const useBoardLogic = (id, setError, setInfo, setCategories, setLoading)
|
|||||||
editTask,
|
editTask,
|
||||||
editCategory,
|
editCategory,
|
||||||
deleteCategory,
|
deleteCategory,
|
||||||
deleteTask
|
deleteTask,
|
||||||
|
assignMember,
|
||||||
|
addMember
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -17,6 +17,9 @@ const KBBoard = () => {
|
|||||||
const [edCateg, setEdCateg] = useState(false);
|
const [edCateg, setEdCateg] = useState(false);
|
||||||
const [delTask, setDelTask] = useState(false);
|
const [delTask, setDelTask] = useState(false);
|
||||||
const [delCateg, setDelCateg] = useState(false);
|
const [delCateg, setDelCateg] = useState(false);
|
||||||
|
const [asgnMember, setAsgnMember] = useState(false);
|
||||||
|
const [assignAction, setAssignAction] = useState(false);
|
||||||
|
const [addMemb, setAddMemb] = useState(false);
|
||||||
|
|
||||||
const [categoryTitle, setCategoryTitle] = useState('');
|
const [categoryTitle, setCategoryTitle] = useState('');
|
||||||
const [taskTitle, setTaskTitle] = useState('');
|
const [taskTitle, setTaskTitle] = useState('');
|
||||||
@@ -27,6 +30,10 @@ const KBBoard = () => {
|
|||||||
const [editedCateg, setEditedCateg] = useState({});
|
const [editedCateg, setEditedCateg] = useState({});
|
||||||
const [taskPosition, setTaskPosition] = useState(null);
|
const [taskPosition, setTaskPosition] = useState(null);
|
||||||
const [categoryPosition, setCategoryPosition] = useState(null);
|
const [categoryPosition, setCategoryPosition] = useState(null);
|
||||||
|
const [assignedMember, setAssignedMember] = useState(0);
|
||||||
|
const [addedUsername, setAddedUsername] = useState('');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
loadBoardData,
|
loadBoardData,
|
||||||
@@ -35,7 +42,9 @@ const KBBoard = () => {
|
|||||||
editTask,
|
editTask,
|
||||||
editCategory,
|
editCategory,
|
||||||
deleteCategory,
|
deleteCategory,
|
||||||
deleteTask
|
deleteTask,
|
||||||
|
assignMember,
|
||||||
|
addMember
|
||||||
} = useBoardLogic(id, setError, setInfo, setCategories, setLoading);
|
} = useBoardLogic(id, setError, setInfo, setCategories, setLoading);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -60,6 +69,7 @@ const KBBoard = () => {
|
|||||||
setTaskDescription(task.description);
|
setTaskDescription(task.description);
|
||||||
setTaskPosition(task.position);
|
setTaskPosition(task.position);
|
||||||
setTaskCategory(task.category_id);
|
setTaskCategory(task.category_id);
|
||||||
|
//setAssignedMember(task.assigned_users.id)
|
||||||
}
|
}
|
||||||
const modalEditCateg = (categ) => () => {
|
const modalEditCateg = (categ) => () => {
|
||||||
setEdCateg(!edCateg);
|
setEdCateg(!edCateg);
|
||||||
@@ -73,6 +83,14 @@ const KBBoard = () => {
|
|||||||
const modalDelCateg = () => {
|
const modalDelCateg = () => {
|
||||||
setDelCateg(!delCateg);
|
setDelCateg(!delCateg);
|
||||||
}
|
}
|
||||||
|
const modalAssignMember = (action) => () => {
|
||||||
|
setAsgnMember(!asgnMember);
|
||||||
|
setAssignAction(action)
|
||||||
|
}
|
||||||
|
const modalAddMember = () => {
|
||||||
|
setAddMemb(!addMemb);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const handleCreateCategory = async (e) => {
|
const handleCreateCategory = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -98,6 +116,16 @@ const KBBoard = () => {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
await deleteCategory(editedCateg.id, modalDelCateg, modalEditCateg);
|
await deleteCategory(editedCateg.id, modalDelCateg, modalEditCateg);
|
||||||
};
|
};
|
||||||
|
const handleAssignMember = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
await assignMember(editedTask.id, assignedMember, assignAction, modalAssignMember);
|
||||||
|
};
|
||||||
|
const handleAddMember = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
await addMember(addedUsername, id, modalAddMember);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="app-container">
|
<div className="app-container">
|
||||||
@@ -122,7 +150,9 @@ const KBBoard = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="set-panel" >
|
<div className="set-panel" >
|
||||||
<p>SetingPanel:В разработке</p>
|
<button onClick={modalAddMember}>
|
||||||
|
Добавить участника
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="board-panel" >
|
<div className="board-panel" >
|
||||||
{categories.map((category) => (
|
{categories.map((category) => (
|
||||||
@@ -143,6 +173,12 @@ const KBBoard = () => {
|
|||||||
<button className='task' onClick={modalEditTask(task, category.id)} key={task.id}>
|
<button className='task' onClick={modalEditTask(task, category.id)} key={task.id}>
|
||||||
<div>{task.title}</div>
|
<div>{task.title}</div>
|
||||||
<div>{task.description}</div>
|
<div>{task.description}</div>
|
||||||
|
<div>Исполнители
|
||||||
|
{task.assigned_users.map((member) => (
|
||||||
|
<img key={member.id} className='members-avatar' src={member.avatar_url}></img>
|
||||||
|
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</button>
|
</button>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
@@ -173,6 +209,7 @@ const KBBoard = () => {
|
|||||||
<div><h3>Новая категория</h3></div>
|
<div><h3>Новая категория</h3></div>
|
||||||
<form onSubmit={handleCreateCategory}>
|
<form onSubmit={handleCreateCategory}>
|
||||||
<div>
|
<div>
|
||||||
|
<label >Название:</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={categoryTitle}
|
value={categoryTitle}
|
||||||
@@ -195,12 +232,14 @@ const KBBoard = () => {
|
|||||||
<div><h3>Новая задача</h3></div>
|
<div><h3>Новая задача</h3></div>
|
||||||
<form onSubmit={handleCreateTask}>
|
<form onSubmit={handleCreateTask}>
|
||||||
<div>
|
<div>
|
||||||
|
<label >Название:</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={taskTitle}
|
value={taskTitle}
|
||||||
onChange={(e) => setTaskTitle(e.target.value)}
|
onChange={(e) => setTaskTitle(e.target.value)}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
<label >Описание:</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={taskDescription}
|
value={taskDescription}
|
||||||
@@ -222,6 +261,7 @@ const KBBoard = () => {
|
|||||||
<div><h3>Изменение категории</h3></div>
|
<div><h3>Изменение категории</h3></div>
|
||||||
<form onSubmit={handleEditCategory}>
|
<form onSubmit={handleEditCategory}>
|
||||||
<div>
|
<div>
|
||||||
|
<label >Название:</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={categoryTitle}
|
value={categoryTitle}
|
||||||
@@ -245,12 +285,14 @@ const KBBoard = () => {
|
|||||||
<div><h3>Изменение задачи</h3></div>
|
<div><h3>Изменение задачи</h3></div>
|
||||||
<form onSubmit={handleEditTask}>
|
<form onSubmit={handleEditTask}>
|
||||||
<div>
|
<div>
|
||||||
|
<label >Название:</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={taskTitle}
|
value={taskTitle}
|
||||||
onChange={(e) => setTaskTitle(e.target.value)}
|
onChange={(e) => setTaskTitle(e.target.value)}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
<label >Описание:</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={taskDescription}
|
value={taskDescription}
|
||||||
@@ -267,6 +309,11 @@ const KBBoard = () => {
|
|||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label >Исполнитель:</label>
|
||||||
|
<button type="button" onClick={modalAssignMember(true)}>Назначить</button>
|
||||||
|
<button type="button" onClick={modalAssignMember(false)}>Снять</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" disabled={loading}>
|
<button type="submit" disabled={loading}>
|
||||||
{loading ? 'Изменение...' : 'Изменить'}
|
{loading ? 'Изменение...' : 'Изменить'}
|
||||||
@@ -307,6 +354,85 @@ const KBBoard = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{addMemb && (
|
||||||
|
<div className="confirm-modal">
|
||||||
|
<div className="modal-content">
|
||||||
|
<div><h3>Удаление категории</h3></div>
|
||||||
|
<form onSubmit={handleAddMember}>
|
||||||
|
<label >Введите логин человека которого хотитепригласить</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Поиск по названию..."
|
||||||
|
value={addedUsername}
|
||||||
|
onChange={(e) => setAddedUsername(e.target.value)}
|
||||||
|
/>
|
||||||
|
<button onClick={modalAddMember}>Отменить</button>
|
||||||
|
<button type="submit" disabled={loading}>
|
||||||
|
{loading ? 'Добавление...' : 'Добавить'}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{asgnMember && (
|
||||||
|
<div className="confirm-modal">
|
||||||
|
{assignAction ? (
|
||||||
|
<div className="modal-content">
|
||||||
|
<div><h3>Назначение пользователя</h3></div>
|
||||||
|
<form onSubmit={handleAssignMember}>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<label >Исполнитель:</label>
|
||||||
|
<select value={assignedMember} onChange={(e) => setAssignedMember(e.target.value)}>
|
||||||
|
<option value={0}>
|
||||||
|
Выберите пользователя
|
||||||
|
</option>
|
||||||
|
{info.members.map((member) => (
|
||||||
|
<option key={member.display_name} value={member.id}>
|
||||||
|
{member.display_name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="submit" disabled={loading}>
|
||||||
|
{loading ? 'Назначение...' : 'Назначить'}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<button onClick={modalAssignMember(null)}>Отменить</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="modal-content">
|
||||||
|
<div><h3>Снятие пользователя</h3></div>
|
||||||
|
<form onSubmit={handleAssignMember}>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<label >Исполнитель:</label>
|
||||||
|
<select value={assignedMember} onChange={(e) => setAssignedMember(e.target.value)}>
|
||||||
|
<option value={0}>
|
||||||
|
Выберите пользователя
|
||||||
|
</option>
|
||||||
|
{info.members.map((member) => (
|
||||||
|
<option key={member.display_name} value={member.id}>
|
||||||
|
{member.display_name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="submit" disabled={loading}>
|
||||||
|
{loading ? 'Снятие...' : 'Снять'}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<button onClick={modalAssignMember(null)}>Отменить</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -31,9 +31,17 @@
|
|||||||
margin: 20px 0px 0px 0px;
|
margin: 20px 0px 0px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-content h3 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.members-avatar {
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
margin-left: 8px;
|
||||||
|
border-radius: 1000px;
|
||||||
|
margin-right: -24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -208,7 +216,9 @@
|
|||||||
margin-right: 0px;
|
margin-right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user