commit
5c47c78599
@ -13,7 +13,6 @@ import {getCorrectDate} from '../../../components/Calendar/calendarHelper'
|
|||||||
import category from "../../../images/category.png";
|
import category from "../../../images/category.png";
|
||||||
import watch from "../../../images/watch.png";
|
import watch from "../../../images/watch.png";
|
||||||
import file from "../../../images/fileModal.svg";
|
import file from "../../../images/fileModal.svg";
|
||||||
import taskImg from "../../../images/tasksMock.png";
|
|
||||||
import arrow from "../../../images/arrowStart.png";
|
import arrow from "../../../images/arrowStart.png";
|
||||||
import link from "../../../images/link.svg";
|
import link from "../../../images/link.svg";
|
||||||
import archive from "../../../images/archive.svg";
|
import archive from "../../../images/archive.svg";
|
||||||
@ -22,8 +21,10 @@ import edit from "../../../images/edit.svg";
|
|||||||
import send from "../../../images/send.svg";
|
import send from "../../../images/send.svg";
|
||||||
import plus from "../../../images/plus.svg";
|
import plus from "../../../images/plus.svg";
|
||||||
import fullScreen from "../../../images/inFullScreen.svg";
|
import fullScreen from "../../../images/inFullScreen.svg";
|
||||||
|
import close from "../../../images/closeProjectPersons.svg";
|
||||||
|
|
||||||
import "./ModalTicket.scss";
|
import "./ModalTicket.scss";
|
||||||
|
import {urlForLocal} from "../../../helper";
|
||||||
|
|
||||||
export const ModalTiсket = ({
|
export const ModalTiсket = ({
|
||||||
active,
|
active,
|
||||||
@ -31,6 +32,7 @@ export const ModalTiсket = ({
|
|||||||
task,
|
task,
|
||||||
projectId,
|
projectId,
|
||||||
projectName,
|
projectName,
|
||||||
|
projectUsers
|
||||||
}) => {
|
}) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [addSubtask, setAddSubtask] = useState(false);
|
const [addSubtask, setAddSubtask] = useState(false);
|
||||||
@ -39,6 +41,11 @@ export const ModalTiсket = ({
|
|||||||
const [comments, setComments] = useState([]);
|
const [comments, setComments] = useState([]);
|
||||||
const [commentsEditOpen, setCommentsEditOpen] = useState({})
|
const [commentsEditOpen, setCommentsEditOpen] = useState({})
|
||||||
const [commentsEditText, setCommentsEditText] = useState({})
|
const [commentsEditText, setCommentsEditText] = useState({})
|
||||||
|
const [dropListOpen, setDropListOpen] = useState(false)
|
||||||
|
const [dropListMembersOpen, setDropListMembersOpen] = useState(false)
|
||||||
|
const [executor, setExecutor] = useState(task.executor)
|
||||||
|
const [members, setMembers] = useState(task.taskUsers)
|
||||||
|
const [users, setUsers] = useState([])
|
||||||
|
|
||||||
function deleteTask() {
|
function deleteTask() {
|
||||||
apiRequest("/task/update-task", {
|
apiRequest("/task/update-task", {
|
||||||
@ -107,6 +114,56 @@ export const ModalTiсket = ({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function taskExecutor(person) {
|
||||||
|
apiRequest("/task/update-task", {
|
||||||
|
method: "PUT",
|
||||||
|
data: {
|
||||||
|
task_id: task.id,
|
||||||
|
executor_id: person.user_id
|
||||||
|
},
|
||||||
|
}).then((res) => {
|
||||||
|
setDropListOpen(false)
|
||||||
|
setExecutor(res.executor)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteTaskExecutor() {
|
||||||
|
apiRequest("/task/update-task", {
|
||||||
|
method: "PUT",
|
||||||
|
data: {
|
||||||
|
task_id: task.id,
|
||||||
|
executor_id: null
|
||||||
|
},
|
||||||
|
}).then((res) => {
|
||||||
|
setExecutor(null)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addMember(person) {
|
||||||
|
apiRequest("/task/add-user-to-task", {
|
||||||
|
method: "POST",
|
||||||
|
data: {
|
||||||
|
task_id: task.id,
|
||||||
|
user_id: person.user_id
|
||||||
|
},
|
||||||
|
}).then((res) => {
|
||||||
|
setDropListMembersOpen(false)
|
||||||
|
setMembers((prevValue) => ([...prevValue, res]))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteMember(person) {
|
||||||
|
apiRequest("/task/del-user", {
|
||||||
|
method: "DELETE",
|
||||||
|
data: {
|
||||||
|
task_id: task.id,
|
||||||
|
user_id: person.user_id
|
||||||
|
},
|
||||||
|
}).then((res) => {
|
||||||
|
setMembers(members.filter((item) => item.user_id !== person.user_id))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
apiRequest(`/comment/get-by-entity?entity_type=2&entity_id=${task.id}`).then((res) => {
|
apiRequest(`/comment/get-by-entity?entity_type=2&entity_id=${task.id}`).then((res) => {
|
||||||
setComments(res)
|
setComments(res)
|
||||||
@ -117,6 +174,15 @@ export const ModalTiсket = ({
|
|||||||
})
|
})
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let ids = members.map((user) => user.user_id)
|
||||||
|
setUsers(projectUsers.reduce((acc, cur) => {
|
||||||
|
if (!ids.includes(cur.user_id)) acc.push(cur)
|
||||||
|
return acc
|
||||||
|
}, []))
|
||||||
|
}, [members])
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={active ? "modal-tiket active" : "modal-tiket"}
|
className={active ? "modal-tiket active" : "modal-tiket"}
|
||||||
@ -202,25 +268,66 @@ export const ModalTiсket = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="workers">
|
<div className="workers">
|
||||||
<div className="workers_box">
|
<div className="workers_box task__info">
|
||||||
<span className="exit" onClick={() => setActive(false)}></span>
|
<span className="exit" onClick={() => setActive(false)}></span>
|
||||||
<span>{task.title}</span>
|
<span className='nameProject'>{task.title}</span>
|
||||||
<p className="workers__creator">Создатель : {task.user?.fio}</p>
|
<p className="workers__creator">Создатель : {task.user?.fio}</p>
|
||||||
<div>
|
|
||||||
{Boolean(task.taskUsers?.length) &&
|
{executor ?
|
||||||
task.taskUsers.map((worker, index) => {
|
<div className='executor'>
|
||||||
return (
|
<p>Исполнитель: {executor.fio}</p>
|
||||||
<div className="worker" key={index}>
|
<img src={urlForLocal(executor.avatar)} alt='avatar' />
|
||||||
<img src={worker.avatar}></img>
|
<img src={close} className='delete' onClick={() => deleteTaskExecutor()} />
|
||||||
<p>{worker.name}</p>
|
</div> :
|
||||||
|
<div className="add-worker moreItems ">
|
||||||
|
<button onClick={() => setDropListOpen(true)}>+</button>
|
||||||
|
<span>Добавить исполнителя</span>
|
||||||
|
{dropListOpen &&
|
||||||
|
<div className='dropdownList'>
|
||||||
|
<img src={close} className='dropdownList__close' onClick={() => setDropListOpen(false)} />
|
||||||
|
{projectUsers.map((person) => {
|
||||||
|
return <div className='dropdownList__person' key={person.user_id} onClick={() => taskExecutor(person)}>
|
||||||
|
<span>{person.user.fio}</span>
|
||||||
|
<img src={urlForLocal(person.user.avatar)} />
|
||||||
</div>
|
</div>
|
||||||
);
|
})
|
||||||
})}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
{Boolean(members.length) &&
|
||||||
|
<div className='members'>
|
||||||
|
<p>Участники:</p>
|
||||||
|
<div className='members__list'>
|
||||||
|
{members.map((member) => {
|
||||||
|
return <div className='worker' key={member.user_id}>
|
||||||
|
<p>{member.fio}</p>
|
||||||
|
<img src={urlForLocal(member.avatar)} />
|
||||||
|
<img src={close} className='delete' onClick={() => deleteMember(member)} />
|
||||||
|
</div>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<div className="add-worker moreItems">
|
<div className="add-worker moreItems">
|
||||||
<button>+</button>
|
<button onClick={() => setDropListMembersOpen(true)}>+</button>
|
||||||
<span>Добавить участников</span>
|
<span>Добавить участников</span>
|
||||||
|
{dropListMembersOpen &&
|
||||||
|
<div className='dropdownList'>
|
||||||
|
<img src={close} className='dropdownList__close' onClick={() => setDropListMembersOpen(false)} />
|
||||||
|
{users.length ? users.map((person) => {
|
||||||
|
return <div className='dropdownList__person' key={person.user_id} onClick={() => addMember(person)}>
|
||||||
|
<span>{person.user.fio}</span>
|
||||||
|
<img src={urlForLocal(person.user.avatar)} />
|
||||||
|
</div>
|
||||||
|
}) : <p className='noUsers'>Нет пользователей</p>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -228,7 +335,7 @@ export const ModalTiсket = ({
|
|||||||
<div className="time">
|
<div className="time">
|
||||||
<img src={watch}></img>
|
<img src={watch}></img>
|
||||||
<span>Длительность : </span>
|
<span>Длительность : </span>
|
||||||
<p>{"8:30:22"}</p>
|
<p>{"0:00:00"}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button className="start">
|
<button className="start">
|
||||||
|
@ -73,6 +73,10 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
color: #1a1919;
|
color: #1a1919;
|
||||||
|
max-width: 500px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,6 +228,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.members {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
&__list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
row-gap: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.workers {
|
.workers {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-left: 1px solid #f1f1f1;
|
border-left: 1px solid #f1f1f1;
|
||||||
@ -258,9 +274,17 @@
|
|||||||
color: #807777;
|
color: #807777;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nameProject {
|
||||||
|
max-width: 200px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
.add-worker {
|
.add-worker {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -295,6 +319,8 @@
|
|||||||
color: white;
|
color: white;
|
||||||
background: #1458dd;
|
background: #1458dd;
|
||||||
border-radius: 44px;
|
border-radius: 44px;
|
||||||
|
opacity: 0.5;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
@ -320,7 +346,6 @@
|
|||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #2d4a17;
|
color: #2d4a17;
|
||||||
display: flex;
|
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@ -339,12 +364,85 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 15px;
|
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0 0 0 11px;
|
max-width: 170px;
|
||||||
font-size: 12px;
|
overflow: hidden;
|
||||||
color: #807777;
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 25px;
|
||||||
|
max-height: 25px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.task__info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
row-gap: 5px;
|
||||||
|
|
||||||
|
.delete {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.executor {
|
||||||
|
display: flex;
|
||||||
|
font-size: 14px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
p {
|
||||||
|
max-width: 170px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin-left: 5px;
|
||||||
|
max-width: 25px;
|
||||||
|
max-height: 25px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdownList {
|
||||||
|
position: absolute;
|
||||||
|
background: white;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
top: 0;
|
||||||
|
z-index: 10;
|
||||||
|
border: 1px solid gray;
|
||||||
|
width: 260px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
row-gap: 8px;
|
||||||
|
|
||||||
|
.noUsers {
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__close {
|
||||||
|
cursor: pointer;
|
||||||
|
margin-left: auto;
|
||||||
|
width: 12px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__person {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 30px;
|
||||||
|
max-height: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,6 +347,17 @@ export const TicketFullScreen = ({}) => {
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="add-worker moreItems">
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
dispatch(modalToggle("addWorker"));
|
||||||
|
setModalAddWorker(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
+
|
||||||
|
</button>
|
||||||
|
<span>Добавить исполнителя</span>
|
||||||
|
</div>
|
||||||
<div className="add-worker moreItems">
|
<div className="add-worker moreItems">
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -364,7 +375,7 @@ export const TicketFullScreen = ({}) => {
|
|||||||
<div className="time">
|
<div className="time">
|
||||||
<img src={watch}></img>
|
<img src={watch}></img>
|
||||||
<span>Длительность : </span>
|
<span>Длительность : </span>
|
||||||
<p>{"8:30:22"}</p>
|
<p>{"0:00:00"}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button className="start">
|
<button className="start">
|
||||||
|
@ -297,6 +297,7 @@ export const ProjectTracker = () => {
|
|||||||
task={selectedTicket}
|
task={selectedTicket}
|
||||||
projectId={projectBoard.id}
|
projectId={projectBoard.id}
|
||||||
projectName={projectBoard.name}
|
projectName={projectBoard.name}
|
||||||
|
projectUsers={projectBoard.projectUsers}
|
||||||
/>}
|
/>}
|
||||||
|
|
||||||
<div className="tasks__container">
|
<div className="tasks__container">
|
||||||
|
@ -555,6 +555,10 @@
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 140%;
|
line-height: 140%;
|
||||||
|
max-width: 295px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__info {
|
&__info {
|
||||||
|
Loading…
Reference in New Issue
Block a user