525 lines
25 KiB
JavaScript
525 lines
25 KiB
JavaScript
import { useState, useEffect } from 'react';
|
||
import { useParams } from 'react-router-dom';
|
||
import { useBoardLogic } from './BoardLogic';
|
||
import Header from './../Header';
|
||
import './../css/Board.css';
|
||
|
||
const KBBoard = () => {
|
||
const { id } = useParams();
|
||
const [error, setError] = useState('');
|
||
const [loading, setLoading] = useState(false);
|
||
const [info, setInfo] = useState({});
|
||
const [categories, setCategories] = useState([]);
|
||
|
||
const [crTask, setCrTask] = useState(false);
|
||
const [crCateg, setCrCateg] = useState(false);
|
||
const [edTask, setEdTask] = useState(false);
|
||
const [edCateg, setEdCateg] = useState(false);
|
||
const [edBoard, setEdBoard] = useState(false);
|
||
const [delTask, setDelTask] = useState(false);
|
||
const [delCateg, setDelCateg] = useState(false);
|
||
const [asgnMember, setAsgnMember] = useState(false);
|
||
const [assignAction, setAssignAction] = useState(false);
|
||
const [addMemb, setAddMemb] = useState(false);
|
||
const [delBoards, setDelBoards] = useState(false);
|
||
|
||
const [boardTitle, setBoardTitle] = useState('');
|
||
const [boardDescription, setBoardDescription] = useState('');
|
||
const [categoryTitle, setCategoryTitle] = useState('');
|
||
const [taskTitle, setTaskTitle] = useState('');
|
||
const [taskDescription, setTaskDescription] = useState('');
|
||
const [taskCategory, setTaskCategory] = useState(null);
|
||
const [taskCategori, setTaskCategori] = useState(null);
|
||
const [editedTask, setEditedTask] = useState({});
|
||
const [editedCateg, setEditedCateg] = useState({});
|
||
const [taskPosition, setTaskPosition] = useState(null);
|
||
const [categoryPosition, setCategoryPosition] = useState(null);
|
||
const [assignedMember, setAssignedMember] = useState(0);
|
||
const [addedUsername, setAddedUsername] = useState('');
|
||
|
||
const {
|
||
loadBoardData,
|
||
createTask,
|
||
checkOwner,
|
||
createCategory,
|
||
editBoard,
|
||
editTask,
|
||
editCategory,
|
||
deleteCategory,
|
||
deleteTask,
|
||
assignMember,
|
||
addMember,
|
||
deleteBoards
|
||
} = useBoardLogic(id, setError, setInfo, setCategories, setLoading);
|
||
|
||
useEffect(() => {
|
||
if (id) loadBoardData();
|
||
}, [id, loadBoardData]);
|
||
|
||
const modalCrTask = (categori) => () => {
|
||
setCrTask(!crTask);
|
||
setTaskCategori(categori);
|
||
setTaskTitle('');
|
||
setTaskDescription('');
|
||
}
|
||
const modalCrCateg = () => {
|
||
setCrCateg(!crCateg);
|
||
setCategoryTitle('');
|
||
}
|
||
const modalEditBoard = () => {
|
||
setEdBoard(!edBoard);
|
||
setBoardTitle(info.title);
|
||
setBoardDescription(info.description);
|
||
}
|
||
const modalEditTask = (task, id_categ) => () => {
|
||
setEdTask(!edTask);
|
||
setTaskCategori(id_categ);
|
||
setEditedTask(task);
|
||
setTaskTitle(task.title);
|
||
setTaskDescription(task.description);
|
||
setTaskPosition(task.position);
|
||
setTaskCategory(task.category_id);
|
||
//setAssignedMember(task.assigned_users.id)
|
||
}
|
||
const modalEditCateg = (categ) => () => {
|
||
setEdCateg(!edCateg);
|
||
setEditedCateg(categ);
|
||
setCategoryTitle(categ.title);
|
||
setCategoryPosition(categ.position);
|
||
}
|
||
const modalDelTask = () => {
|
||
setDelTask(!delTask);
|
||
}
|
||
const modalDelCateg = () => {
|
||
setDelCateg(!delCateg);
|
||
}
|
||
const modalAssignMember = (action) => () => {
|
||
setAsgnMember(!asgnMember);
|
||
setAssignAction(action)
|
||
}
|
||
const modalAddMember = () => {
|
||
setAddMemb(!addMemb);
|
||
}
|
||
const modalDeleteBoards = () => {
|
||
setDelBoards(!delBoards);
|
||
}
|
||
|
||
|
||
|
||
const handleCreateCategory = async (e) => {
|
||
e.preventDefault();
|
||
await createCategory(categoryTitle, modalCrCateg);
|
||
};
|
||
const handleCreateTask = async (e) => {
|
||
e.preventDefault();
|
||
await createTask(taskCategori, taskTitle, taskDescription, modalCrTask);
|
||
};
|
||
const handleEditBoard = async (e) => {
|
||
e.preventDefault();
|
||
await editBoard(id, boardTitle, boardDescription, modalEditBoard);
|
||
};
|
||
|
||
const handleEditCategory = async (e) => {
|
||
e.preventDefault();
|
||
await editCategory(editedCateg.id, categoryTitle, modalEditCateg);
|
||
};
|
||
const handleEditTask = async (e) => {
|
||
e.preventDefault();
|
||
await editTask(editedTask.id, taskTitle, taskDescription, taskCategory, modalEditTask);
|
||
};
|
||
const handleDeleteTask = async (e) => {
|
||
e.preventDefault();
|
||
await deleteTask(editedTask.id, modalDelTask, modalEditTask);
|
||
};
|
||
const handleDeleteCategory = async (e) => {
|
||
e.preventDefault();
|
||
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);
|
||
};
|
||
const handleDeleteBoards = async (e) => {
|
||
e.preventDefault();
|
||
await deleteBoards(id, modalDeleteBoards);
|
||
};
|
||
|
||
|
||
return (
|
||
<div className="app-container">
|
||
<Header />
|
||
<div className="page-container">
|
||
{
|
||
error && <div className="error">{error}</div>
|
||
}
|
||
<div className="inf-panel" >
|
||
<div className="row">
|
||
<h3>{info.title}</h3>
|
||
<p>
|
||
<strong>Участники: </strong> В разработке
|
||
</p>
|
||
<p>
|
||
<strong>Владелец: </strong> {" "+info.owner?.display_name}
|
||
<img className="nav-avatar" src={info.owner?.avatar_url} alt=''></img>
|
||
</p>
|
||
</div>
|
||
<div className="row">
|
||
<p><strong>Описание: </strong> {info.description ? info.description : 'Отсутствует'}</p>
|
||
</div>
|
||
</div>
|
||
<div className="set-panel" >
|
||
{checkOwner(info?.owner?.id) ? (
|
||
<>
|
||
<button onClick={modalAddMember}>
|
||
Добавить участника
|
||
</button>
|
||
<button onClick={null}>
|
||
Выгнать участника
|
||
</button>
|
||
<button onClick={modalEditBoard}>
|
||
Настройки доски
|
||
</button>
|
||
<button className='Important-button' onClick={modalDeleteBoards}>
|
||
Удаление доски
|
||
</button>
|
||
</>
|
||
) : (
|
||
<>
|
||
<button onClick={null}>
|
||
Покинуть доску
|
||
</button>
|
||
</>
|
||
)}
|
||
</div>
|
||
<div className="board-panel" >
|
||
{categories.map((category) => (
|
||
<div className="categori" key={category.position}>
|
||
<button onClick={modalEditCateg(category)}><h3>{category.title}</h3></button>
|
||
<div className="categ-h">
|
||
<p>Позиция: {category.position}</p>
|
||
<p>Задач: {category.tasks.length}</p>
|
||
</div>
|
||
<div className='task create'>
|
||
<button onClick={modalCrTask(category.id)}>
|
||
Новая задача
|
||
</button>
|
||
</div>
|
||
<div className='task-list'>
|
||
{category.tasks.length > 0 ? (
|
||
category.tasks.map((task) => (
|
||
<button className='task' onClick={modalEditTask(task, category.id)} key={task.id}>
|
||
<div>{task.title}</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>
|
||
))
|
||
) : (
|
||
<p>Нет задач</p>
|
||
)}
|
||
</div>
|
||
</div>
|
||
))}
|
||
{categories.length < 10 ? (
|
||
<div className="categori create">
|
||
<div className="bib">
|
||
<button onClick={modalCrCateg}>
|
||
<div>
|
||
+
|
||
</div>
|
||
Новая категория
|
||
</button>
|
||
</div>
|
||
</div>
|
||
) : (
|
||
<></>
|
||
)}
|
||
</div>
|
||
|
||
{crCateg && (
|
||
<div className="confirm-modal">
|
||
<div className="modal-content">
|
||
<div><h3>Новая категория</h3></div>
|
||
<form onSubmit={handleCreateCategory}>
|
||
<div>
|
||
<label >Название:</label>
|
||
<input
|
||
type="text"
|
||
value={categoryTitle}
|
||
onChange={(e) => setCategoryTitle(e.target.value)}
|
||
required
|
||
/>
|
||
</div>
|
||
<button type="submit" disabled={loading}>
|
||
{loading ? 'Создание...' : 'Создать'}
|
||
</button>
|
||
</form>
|
||
<button onClick={modalCrCateg}>Отменить</button>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{crTask && (
|
||
<div className="confirm-modal">
|
||
<div className="modal-content">
|
||
<div><h3>Новая задача</h3></div>
|
||
<form onSubmit={handleCreateTask}>
|
||
<div>
|
||
<label >Название:</label>
|
||
<input
|
||
type="text"
|
||
value={taskTitle}
|
||
onChange={(e) => setTaskTitle(e.target.value)}
|
||
required
|
||
/>
|
||
<label >Описание:</label>
|
||
<input
|
||
type="text"
|
||
value={taskDescription}
|
||
onChange={(e) => setTaskDescription(e.target.value)}
|
||
/>
|
||
</div>
|
||
<button type="submit" disabled={loading}>
|
||
{loading ? 'Создание...' : 'Создать'}
|
||
</button>
|
||
</form>
|
||
<button onClick={modalCrTask(null)}>Отменить</button>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{edBoard && (
|
||
<div className="confirm-modal">
|
||
<div className="modal-content">
|
||
<div><h3>Изменение доски</h3></div>
|
||
<form onSubmit={handleEditBoard}>
|
||
<div>
|
||
<label >Название:</label>
|
||
<input
|
||
type="text"
|
||
value={boardTitle}
|
||
onChange={(e) => setBoardTitle(e.target.value)}
|
||
required
|
||
/>
|
||
<label >Описание:</label>
|
||
<input
|
||
type="text"
|
||
value={boardDescription}
|
||
onChange={(e) => setBoardDescription(e.target.value)}
|
||
/>
|
||
</div>
|
||
<button type="submit" disabled={loading}>
|
||
{loading ? 'Изменение...' : 'Изменить'}
|
||
</button>
|
||
</form>
|
||
<button onClick={modalEditBoard}>Отменить</button>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{edCateg && (
|
||
<div className="confirm-modal">
|
||
<div className="modal-content">
|
||
<div><h3>Изменение категории</h3></div>
|
||
<form onSubmit={handleEditCategory}>
|
||
<div>
|
||
<label >Название:</label>
|
||
<input
|
||
type="text"
|
||
value={categoryTitle}
|
||
onChange={(e) => setCategoryTitle(e.target.value)}
|
||
required
|
||
/>
|
||
</div>
|
||
<button type="submit" disabled={loading}>
|
||
{loading ? 'Изменение...' : 'Изменить'}
|
||
</button>
|
||
</form>
|
||
<button onClick={modalEditCateg({})}>Отменить</button>
|
||
<button className="Important-button" onClick={modalDelCateg}>Удалить</button>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{edTask && (
|
||
<div className="confirm-modal">
|
||
<div className="modal-content">
|
||
<div><h3>Изменение задачи</h3></div>
|
||
<form onSubmit={handleEditTask}>
|
||
<div>
|
||
<label >Название:</label>
|
||
<input
|
||
type="text"
|
||
value={taskTitle}
|
||
onChange={(e) => setTaskTitle(e.target.value)}
|
||
required
|
||
/>
|
||
<label >Описание:</label>
|
||
<input
|
||
type="text"
|
||
value={taskDescription}
|
||
onChange={(e) => setTaskDescription(e.target.value)}
|
||
required
|
||
/>
|
||
<div>
|
||
<label >Категория:</label>
|
||
<select value={taskCategory} onChange={(e) => setTaskCategory(e.target.value)}>
|
||
{categories.map((category) => (
|
||
<option key={category.position} value={category.id}>
|
||
{category.title}
|
||
</option>
|
||
))}
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label >Исполнитель:</label>
|
||
<button type="button" onClick={modalAssignMember(true)}>Назначить</button>
|
||
<button type="button" onClick={modalAssignMember(false)}>Снять</button>
|
||
</div>
|
||
</div>
|
||
<button type="submit" disabled={loading}>
|
||
{loading ? 'Изменение...' : 'Изменить'}
|
||
</button>
|
||
</form>
|
||
<button onClick={modalEditTask({},null)}>Отменить</button>
|
||
<button className="Important-button" onClick={modalDelTask}>Удалить</button>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{delTask && (
|
||
<div className="confirm-modal">
|
||
<div className="modal-content">
|
||
<div><h3>Удаление задачи</h3></div>
|
||
<form onSubmit={handleDeleteTask}>
|
||
<label >Вы точно хотите удалить задачу {editedTask.title}</label>
|
||
<button onClick={modalDelTask}>Отменить</button>
|
||
<button className="Important-button" type="submit" disabled={loading}>
|
||
{loading ? 'Удаление...' : 'Удалить'}
|
||
</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{delCateg && (
|
||
<div className="confirm-modal">
|
||
<div className="modal-content">
|
||
<div><h3>Удаление категории</h3></div>
|
||
<form onSubmit={handleDeleteCategory}>
|
||
<label >Вы точно хотите удалить эту категорию</label>
|
||
<button onClick={modalDelCateg}>Отменить</button>
|
||
<button className="Important-button" type="submit" disabled={loading}>
|
||
{loading ? 'Удаление...' : 'Удалить'}
|
||
</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{delBoards && (
|
||
<div className="confirm-modal">
|
||
<div className="modal-content">
|
||
<div><h3>Удаление доски</h3></div>
|
||
<form onSubmit={handleDeleteBoards}>
|
||
<label >Вы точно хотите удалить эту Канбан доску</label>
|
||
<button onClick={modalDeleteBoards} type='reset'>Отменить</button>
|
||
<button className="Important-button" type="submit" disabled={loading}>
|
||
{loading ? 'Удаление...' : 'Удалить'}
|
||
</button>
|
||
</form>
|
||
</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>
|
||
);
|
||
}
|
||
|
||
export default KBBoard; |