add comments to tasks
This commit is contained in:
parent
c55a697f6b
commit
4e0a44e5a4
125
src/components/TrackerTaskComment/TrackerTaskComment.jsx
Normal file
125
src/components/TrackerTaskComment/TrackerTaskComment.jsx
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import TrackerTaskSubComment from "../TrackerTaskComment/TrackerTaskComment";
|
||||||
|
import { apiRequest } from "../../api/request";
|
||||||
|
import {urlForLocal} from "../../helper";
|
||||||
|
import {getCorrectDate} from "../Calendar/calendarHelper";
|
||||||
|
import edit from "../../images/edit.svg";
|
||||||
|
import del from "../../images/delete.svg";
|
||||||
|
import accept from "../../images/accept.png";
|
||||||
|
|
||||||
|
export const TrackerTaskComment = ({
|
||||||
|
taskId,
|
||||||
|
comment,
|
||||||
|
commentDelete,
|
||||||
|
addSubComment,
|
||||||
|
subCommentDelete
|
||||||
|
}) => {
|
||||||
|
const [commentsEditOpen, setCommentsEditOpen] = useState(false)
|
||||||
|
const [commentsEditText, setCommentsEditText] = useState(comment.text)
|
||||||
|
const [subCommentsCreateOpen, setSubCommentsCreateOpen] = useState(false)
|
||||||
|
const [subCommentsCreateText, setSubCommentsCreateText] = useState('')
|
||||||
|
|
||||||
|
function editComment() {
|
||||||
|
if (commentsEditText === comment.text) return
|
||||||
|
apiRequest("/comment/update", {
|
||||||
|
method: "PUT",
|
||||||
|
data: {
|
||||||
|
comment_id: comment.id,
|
||||||
|
text: commentsEditText
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteComment() {
|
||||||
|
apiRequest("/comment/update", {
|
||||||
|
method: "PUT",
|
||||||
|
data: {
|
||||||
|
comment_id: comment.id,
|
||||||
|
status: 0
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
if (comment.parent_id) {
|
||||||
|
subCommentDelete(comment)
|
||||||
|
} else {
|
||||||
|
commentDelete(comment)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function createSubComment() {
|
||||||
|
setSubCommentsCreateOpen(false)
|
||||||
|
if(!subCommentsCreateText) return
|
||||||
|
apiRequest("/comment/create", {
|
||||||
|
method: "POST",
|
||||||
|
data: {
|
||||||
|
text: subCommentsCreateText,
|
||||||
|
entity_type: 2,
|
||||||
|
entity_id: taskId,
|
||||||
|
parent_id: comment.id
|
||||||
|
}
|
||||||
|
}).then((res) => {
|
||||||
|
let newSubComment = res
|
||||||
|
newSubComment.created_at = new Date()
|
||||||
|
setSubCommentsCreateText('')
|
||||||
|
addSubComment(comment.id, newSubComment)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={[!comment.parent_id && comment.subComments.length ? 'comments__list__item__main': '',
|
||||||
|
'comments__list__item',
|
||||||
|
comment.parent_id ? 'comments__list__item__subComment' : ''].join(' ')}>
|
||||||
|
<div className='comments__list__item__info'>
|
||||||
|
<div className='comments__list__item__fio'>
|
||||||
|
<img src={urlForLocal(comment.user.avatar)} alt='avatar' />
|
||||||
|
<p>{comment.user.fio}</p>
|
||||||
|
</div>
|
||||||
|
<div className='comments__list__item__date'>
|
||||||
|
<span>{getCorrectDate(comment.created_at)}</span>
|
||||||
|
<div className={commentsEditOpen ? 'edit edit__open' : 'edit'} >
|
||||||
|
<img src={edit} alt='edit' onClick={() => {
|
||||||
|
if (commentsEditOpen) {
|
||||||
|
editComment()
|
||||||
|
}
|
||||||
|
setCommentsEditOpen(!commentsEditOpen)
|
||||||
|
}} />
|
||||||
|
</div>
|
||||||
|
<img src={del} alt='delete' onClick={() => deleteComment()} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{commentsEditOpen ?
|
||||||
|
<input className='comments__list__item__text' value={commentsEditText} onChange={(e) => {
|
||||||
|
setCommentsEditText(e.target.value)
|
||||||
|
}} /> :
|
||||||
|
<p className='comments__list__item__text'>{commentsEditText}</p>}
|
||||||
|
{!comment.parent_id &&
|
||||||
|
<>
|
||||||
|
{
|
||||||
|
subCommentsCreateOpen ?
|
||||||
|
<div className='comments__list__item__answer__new'>
|
||||||
|
<input value={subCommentsCreateText} onChange={(e) => {
|
||||||
|
setSubCommentsCreateText(e.target.value)
|
||||||
|
}}/>
|
||||||
|
<img src={accept} alt='accept'
|
||||||
|
onClick={() => {
|
||||||
|
createSubComment()
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<span onClick={() => {
|
||||||
|
setSubCommentsCreateOpen(true)
|
||||||
|
}} className='comments__list__item__answer'>Ответить</span>
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
{Boolean(comment.subComments?.length) && comment.subComments.map((subComment) => {
|
||||||
|
return <TrackerTaskSubComment key={subComment.id} taskId={taskId} comment={subComment} subCommentDelete={subCommentDelete}/>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TrackerTaskComment
|
@ -1,6 +1,7 @@
|
|||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import TrackerModal from "../TrackerModal/TrackerModal";
|
import TrackerModal from "../TrackerModal/TrackerModal";
|
||||||
|
import TrackerTaskComment from "../../../components/TrackerTaskComment/TrackerTaskComment";
|
||||||
import { apiRequest } from "../../../api/request";
|
import { apiRequest } from "../../../api/request";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
import {
|
import {
|
||||||
@ -8,8 +9,6 @@ import {
|
|||||||
setProjectBoardFetch,
|
setProjectBoardFetch,
|
||||||
} from "../../../redux/projectsTrackerSlice";
|
} from "../../../redux/projectsTrackerSlice";
|
||||||
|
|
||||||
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";
|
||||||
@ -25,7 +24,6 @@ import close from "../../../images/closeProjectPersons.svg";
|
|||||||
|
|
||||||
import "./ModalTicket.scss";
|
import "./ModalTicket.scss";
|
||||||
import {urlForLocal, getCorrectRequestDate} from "../../../helper";
|
import {urlForLocal, getCorrectRequestDate} from "../../../helper";
|
||||||
import accept from "../../../images/accept.png";
|
|
||||||
|
|
||||||
export const ModalTiсket = ({
|
export const ModalTiсket = ({
|
||||||
active,
|
active,
|
||||||
@ -40,9 +38,6 @@ export const ModalTiсket = ({
|
|||||||
const [editOpen, setEditOpen] = useState(false);
|
const [editOpen, setEditOpen] = useState(false);
|
||||||
const [inputsValue, setInputsValue] = useState({title: task.title, description: task.description, comment: ''});
|
const [inputsValue, setInputsValue] = useState({title: task.title, description: task.description, comment: ''});
|
||||||
const [comments, setComments] = useState([]);
|
const [comments, setComments] = useState([]);
|
||||||
const [commentsEditOpen, setCommentsEditOpen] = useState({})
|
|
||||||
const [commentsEditText, setCommentsEditText] = useState({})
|
|
||||||
const [subCommentsCreateOpen, setSubCommentsCreateOpen] = useState({})
|
|
||||||
const [dropListOpen, setDropListOpen] = useState(false)
|
const [dropListOpen, setDropListOpen] = useState(false)
|
||||||
const [dropListMembersOpen, setDropListMembersOpen] = useState(false)
|
const [dropListMembersOpen, setDropListMembersOpen] = useState(false)
|
||||||
const [executor, setExecutor] = useState(task.executor)
|
const [executor, setExecutor] = useState(task.executor)
|
||||||
@ -94,48 +89,47 @@ export const ModalTiсket = ({
|
|||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
let newComment = res
|
let newComment = res
|
||||||
newComment.created_at = new Date()
|
newComment.created_at = new Date()
|
||||||
|
newComment.subComments = []
|
||||||
setInputsValue((prevValue) => ({...prevValue, comment: ''}))
|
setInputsValue((prevValue) => ({...prevValue, comment: ''}))
|
||||||
setComments((prevValue) => ([...prevValue, newComment]))
|
setComments((prevValue) => ([...prevValue, newComment]))
|
||||||
setCommentsEditOpen((prevValue) => ({...prevValue, [res.id]: false}))
|
|
||||||
setCommentsEditText((prevValue) => ({...prevValue, [res.id]: res.text}))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
function deleteComment(commentId) {
|
|
||||||
|
function commentDelete(comment) {
|
||||||
|
setComments((prevValue) => prevValue.filter((item) => item.id !== comment.id))
|
||||||
|
if (comment.subComments.length) {
|
||||||
|
comment.subComments.forEach((subComment) => {
|
||||||
apiRequest("/comment/update", {
|
apiRequest("/comment/update", {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
data: {
|
data: {
|
||||||
comment_id: commentId,
|
comment_id: subComment.id,
|
||||||
status: 0
|
status: 0
|
||||||
}
|
}
|
||||||
}).then((res) => {
|
}).then(() => {
|
||||||
setComments((prevValue) => prevValue.filter((item) => item.id !== commentId))
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function editComment(commentId) {
|
|
||||||
|
|
||||||
apiRequest("/comment/update", {
|
|
||||||
method: "PUT",
|
|
||||||
data: {
|
|
||||||
comment_id: commentId,
|
|
||||||
text: commentsEditText[commentId]
|
|
||||||
}
|
}
|
||||||
}).then((res) => {
|
|
||||||
// createSubComment()
|
function addSubComment(commentId, subComment) {
|
||||||
|
const addSubComment = comments
|
||||||
|
addSubComment.forEach((comment) => {
|
||||||
|
if (comment.id === commentId) {
|
||||||
|
comment.subComments.push(subComment)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
setComments(addSubComment)
|
||||||
}
|
}
|
||||||
|
|
||||||
// function createSubComment() {
|
function subCommentDelete(subComment) {
|
||||||
// apiRequest("/comment/create", {
|
const deleteSubComment = comments
|
||||||
// method: "POST",
|
deleteSubComment.forEach((comment, index) => {
|
||||||
// data: {
|
if (comment.id === subComment.parent_id) {
|
||||||
// text: '12312312',
|
deleteSubComment[index].subComments = comment.subComments.filter((item) => item.id !== subComment.id)
|
||||||
// entity_type: 2,
|
}
|
||||||
// entity_id: task.id,
|
})
|
||||||
// parent_id: 36
|
setComments([...deleteSubComment])
|
||||||
// }
|
}
|
||||||
// }).then((res) => console.log(res))
|
|
||||||
// }
|
|
||||||
|
|
||||||
function startTaskTimer() {
|
function startTaskTimer() {
|
||||||
apiRequest("/timer/create", {
|
apiRequest("/timer/create", {
|
||||||
@ -159,7 +153,7 @@ export const ModalTiсket = ({
|
|||||||
timer_id: timerInfo.id,
|
timer_id: timerInfo.id,
|
||||||
stopped_at: getCorrectRequestDate(new Date())
|
stopped_at: getCorrectRequestDate(new Date())
|
||||||
}
|
}
|
||||||
}).then((res) => {
|
}).then(() => {
|
||||||
setTimerStart(false)
|
setTimerStart(false)
|
||||||
clearInterval(timerId)
|
clearInterval(timerId)
|
||||||
})
|
})
|
||||||
@ -185,7 +179,7 @@ export const ModalTiсket = ({
|
|||||||
task_id: task.id,
|
task_id: task.id,
|
||||||
executor_id: 0
|
executor_id: 0
|
||||||
},
|
},
|
||||||
}).then((res) => {
|
}).then(() => {
|
||||||
setExecutor(null)
|
setExecutor(null)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -210,19 +204,24 @@ export const ModalTiсket = ({
|
|||||||
task_id: task.id,
|
task_id: task.id,
|
||||||
user_id: person.user_id
|
user_id: person.user_id
|
||||||
},
|
},
|
||||||
}).then((res) => {
|
}).then(() => {
|
||||||
setMembers(members.filter((item) => item.user_id !== person.user_id))
|
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)
|
const comments = res.reduce((acc, cur) => {
|
||||||
res.forEach((item) => {
|
if (!cur.parent_id) {
|
||||||
setCommentsEditOpen((prevValue) => ({...prevValue, [item.id]: false}))
|
acc.push({...cur, subComments: []})
|
||||||
setCommentsEditText((prevValue) => ({...prevValue, [item.id]: item.text}))
|
} else {
|
||||||
setSubCommentsCreateOpen((prevValue) => ({...prevValue, [item.id]: false}))
|
acc.forEach((item) => {
|
||||||
|
if (item.id === cur.parent_id) item.subComments.push(cur)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, [])
|
||||||
|
setComments(comments)
|
||||||
})
|
})
|
||||||
apiRequest(`/timer/get-by-entity?entity_type=2&entity_id=${task.id}`).then((res) => {
|
apiRequest(`/timer/get-by-entity?entity_type=2&entity_id=${task.id}`).then((res) => {
|
||||||
let timerSeconds = 0
|
let timerSeconds = 0
|
||||||
@ -347,45 +346,15 @@ export const ModalTiсket = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className='comments__list'>
|
<div className='comments__list'>
|
||||||
{comments.map((comment) => {
|
{comments.map((comment) => {
|
||||||
return <div className='comments__list__item' key={comment.id}>
|
return <TrackerTaskComment
|
||||||
<div className='comments__list__item__info'>
|
key={comment.id}
|
||||||
<div className='comments__list__item__fio'>
|
taskId={task.id}
|
||||||
<img src={urlForLocal(comment.user.avatar)} alt='avatar' />
|
comment={comment}
|
||||||
<p>{comment.user.fio}</p>
|
commentDelete={commentDelete}
|
||||||
</div>
|
addSubComment={addSubComment}
|
||||||
<div className='comments__list__item__date'>
|
subCommentDelete={subCommentDelete}
|
||||||
<span>{getCorrectDate(comment.created_at)}</span>
|
|
||||||
<div className={commentsEditOpen[comment.id] ? 'edit edit__open' : 'edit'} >
|
|
||||||
<img src={edit} alt='edit' onClick={() => {
|
|
||||||
if (commentsEditOpen[comment.id]) {
|
|
||||||
editComment(comment.id)
|
|
||||||
}
|
|
||||||
setCommentsEditOpen((prevValue) => ({...prevValue, [comment.id]: !prevValue[comment.id]}))
|
|
||||||
}} />
|
|
||||||
</div>
|
|
||||||
<img src={del} alt='delete' onClick={() => deleteComment(comment.id)} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{commentsEditOpen[comment.id] ? <input className='comments__list__item__text' value={commentsEditText[comment.id]} onChange={(e) => {
|
|
||||||
setCommentsEditText((prevValue) => ({...prevValue, [comment.id]: e.target.value}))
|
|
||||||
}} /> : <p className='comments__list__item__text'>{commentsEditText[comment.id]}</p>}
|
|
||||||
{subCommentsCreateOpen[comment.id] ?
|
|
||||||
<div className='comments__list__item__answer__new'>
|
|
||||||
<input />
|
|
||||||
<img src={accept} alt='accept'
|
|
||||||
onClick={() => {
|
|
||||||
setSubCommentsCreateOpen((prevValue) => ({...prevValue, [comment.id]: !prevValue[comment.id]}))
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
:
|
|
||||||
<span onClick={() => {
|
|
||||||
setSubCommentsCreateOpen((prevValue) => ({...prevValue, [comment.id]: !prevValue[comment.id]}))
|
|
||||||
}} className='comments__list__item__answer'>Ответить</span>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -81,6 +81,22 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
max-height: 420px;
|
max-height: 420px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 4px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background: #cbd9f9;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
background: #c5c0c6;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
&__item {
|
&__item {
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -89,6 +105,41 @@
|
|||||||
border-radius: 44px;
|
border-radius: 44px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&__subComment {
|
||||||
|
&:before {
|
||||||
|
content: '';
|
||||||
|
background: #E4E4E6;
|
||||||
|
height: 1px;
|
||||||
|
width: 7px;
|
||||||
|
position: absolute;
|
||||||
|
top: 36%;
|
||||||
|
left: 2.5%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__main {
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
background-image: url("../../../images/mainTaskCommentImg.png");
|
||||||
|
width: 10px;
|
||||||
|
height: 8px;
|
||||||
|
top: 50px;
|
||||||
|
left: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
background: #E4E4E6;
|
||||||
|
width: 1px;
|
||||||
|
height: calc(100% - 120px);
|
||||||
|
left: 29px;
|
||||||
|
top: 65px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__fio {
|
&__fio {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -163,6 +214,7 @@
|
|||||||
padding: 3px 5px;
|
padding: 3px 5px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
margin-top: 5px;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
|
@ -5,6 +5,7 @@ import { ProfileBreadcrumbs } from "../../ProfileBreadcrumbs/ProfileBreadcrumbs"
|
|||||||
import { Footer } from "../../Footer/Footer";
|
import { Footer } from "../../Footer/Footer";
|
||||||
import { Link, useParams, useNavigate } from "react-router-dom";
|
import { Link, useParams, useNavigate } from "react-router-dom";
|
||||||
import TrackerModal from "../TrackerModal/TrackerModal";
|
import TrackerModal from "../TrackerModal/TrackerModal";
|
||||||
|
import TrackerTaskComment from "../../../components/TrackerTaskComment/TrackerTaskComment";
|
||||||
import { Navigation } from "../../Navigation/Navigation";
|
import { Navigation } from "../../Navigation/Navigation";
|
||||||
import {Loader} from "../../Loader/Loader";
|
import {Loader} from "../../Loader/Loader";
|
||||||
|
|
||||||
@ -33,12 +34,10 @@ import link from "../../../images/link.svg";
|
|||||||
import archive2 from "../../../images/archive.svg";
|
import archive2 from "../../../images/archive.svg";
|
||||||
import del from "../../../images/delete.svg";
|
import del from "../../../images/delete.svg";
|
||||||
import edit from "../../../images/edit.svg";
|
import edit from "../../../images/edit.svg";
|
||||||
import accept from "../../../images/accept.png"
|
|
||||||
|
|
||||||
import "./ticketFullScreen.scss";
|
import "./ticketFullScreen.scss";
|
||||||
import close from "../../../images/closeProjectPersons.svg";
|
import close from "../../../images/closeProjectPersons.svg";
|
||||||
import {getCorrectRequestDate, urlForLocal} from "../../../helper";
|
import {getCorrectRequestDate, urlForLocal} from "../../../helper";
|
||||||
import {getCorrectDate} from "../../Calendar/calendarHelper";
|
|
||||||
|
|
||||||
export const TicketFullScreen = ({}) => {
|
export const TicketFullScreen = ({}) => {
|
||||||
const [modalAddWorker, setModalAddWorker] = useState(false);
|
const [modalAddWorker, setModalAddWorker] = useState(false);
|
||||||
@ -52,9 +51,6 @@ export const TicketFullScreen = ({}) => {
|
|||||||
const [inputsValue, setInputsValue] = useState({});
|
const [inputsValue, setInputsValue] = useState({});
|
||||||
const [loader, setLoader] = useState(true);
|
const [loader, setLoader] = useState(true);
|
||||||
const [comments, setComments] = useState([]);
|
const [comments, setComments] = useState([]);
|
||||||
const [commentsEditOpen, setCommentsEditOpen] = useState({})
|
|
||||||
const [subCommentsCreateOpen, setSubCommentsCreateOpen] = useState({})
|
|
||||||
const [commentsEditText, setCommentsEditText] = useState({})
|
|
||||||
const [personListOpen, setPersonListOpen] = useState(false)
|
const [personListOpen, setPersonListOpen] = useState(false)
|
||||||
const [timerStart, setTimerStart] = useState(false)
|
const [timerStart, setTimerStart] = useState(false)
|
||||||
const [timerInfo, setTimerInfo] = useState({})
|
const [timerInfo, setTimerInfo] = useState({})
|
||||||
@ -64,12 +60,17 @@ export const TicketFullScreen = ({}) => {
|
|||||||
setTaskInfo(taskInfo);
|
setTaskInfo(taskInfo);
|
||||||
setInputsValue({title: taskInfo.title, description: taskInfo.description, comment: ''})
|
setInputsValue({title: taskInfo.title, description: taskInfo.description, comment: ''})
|
||||||
apiRequest(`/comment/get-by-entity?entity_type=2&entity_id=${taskInfo.id}`).then((res) => {
|
apiRequest(`/comment/get-by-entity?entity_type=2&entity_id=${taskInfo.id}`).then((res) => {
|
||||||
setComments(res)
|
const comments = res.reduce((acc, cur) => {
|
||||||
res.forEach((item) => {
|
if (!cur.parent_id) {
|
||||||
setCommentsEditOpen((prevValue) => ({...prevValue, [item.id]: false}))
|
acc.push({...cur, subComments: []})
|
||||||
setSubCommentsCreateOpen((prevValue) => ({...prevValue, [item.id]: false}))
|
} else {
|
||||||
setCommentsEditText((prevValue) => ({...prevValue, [item.id]: item.text}))
|
acc.forEach((item) => {
|
||||||
|
if (item.id === cur.parent_id) item.subComments.push(cur)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, [])
|
||||||
|
setComments(comments)
|
||||||
})
|
})
|
||||||
taskInfo.timers.forEach((time) => {
|
taskInfo.timers.forEach((time) => {
|
||||||
if (!time.stopped_at) {
|
if (!time.stopped_at) {
|
||||||
@ -102,7 +103,7 @@ export const TicketFullScreen = ({}) => {
|
|||||||
title: inputsValue.title,
|
title: inputsValue.title,
|
||||||
description: inputsValue.description
|
description: inputsValue.description
|
||||||
},
|
},
|
||||||
}).then((res) => {
|
}).then(() => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,33 +118,9 @@ export const TicketFullScreen = ({}) => {
|
|||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
let newComment = res
|
let newComment = res
|
||||||
newComment.created_at = new Date()
|
newComment.created_at = new Date()
|
||||||
|
newComment.subComments = []
|
||||||
setInputsValue((prevValue) => ({...prevValue, comment: ''}))
|
setInputsValue((prevValue) => ({...prevValue, comment: ''}))
|
||||||
setComments((prevValue) => ([...prevValue, newComment]))
|
setComments((prevValue) => ([...prevValue, newComment]))
|
||||||
setCommentsEditOpen((prevValue) => ({...prevValue, [res.id]: false}))
|
|
||||||
setCommentsEditText((prevValue) => ({...prevValue, [res.id]: res.text}))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteComment(commentId) {
|
|
||||||
apiRequest("/comment/update", {
|
|
||||||
method: "PUT",
|
|
||||||
data: {
|
|
||||||
comment_id: commentId,
|
|
||||||
status: 0
|
|
||||||
}
|
|
||||||
}).then((res) => {
|
|
||||||
setComments((prevValue) => prevValue.filter((item) => item.id !== commentId))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function editComment(commentId) {
|
|
||||||
apiRequest("/comment/update", {
|
|
||||||
method: "PUT",
|
|
||||||
data: {
|
|
||||||
comment_id: commentId,
|
|
||||||
text: commentsEditText[commentId]
|
|
||||||
}
|
|
||||||
}).then((res) => {
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,7 +145,7 @@ export const TicketFullScreen = ({}) => {
|
|||||||
timer_id: timerInfo.id,
|
timer_id: timerInfo.id,
|
||||||
stopped_at: getCorrectRequestDate(new Date())
|
stopped_at: getCorrectRequestDate(new Date())
|
||||||
}
|
}
|
||||||
}).then((res) => setTimerStart(false))
|
}).then(() => setTimerStart(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
function deletePerson(userId) {
|
function deletePerson(userId) {
|
||||||
@ -183,6 +160,42 @@ export const TicketFullScreen = ({}) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function commentDelete(comment) {
|
||||||
|
setComments((prevValue) => prevValue.filter((item) => item.id !== comment.id))
|
||||||
|
if (comment.subComments.length) {
|
||||||
|
comment.subComments.forEach((subComment) => {
|
||||||
|
apiRequest("/comment/update", {
|
||||||
|
method: "PUT",
|
||||||
|
data: {
|
||||||
|
comment_id: subComment.id,
|
||||||
|
status: 0
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addSubComment(commentId, subComment) {
|
||||||
|
const addSubComment = comments
|
||||||
|
addSubComment.forEach((comment) => {
|
||||||
|
if (comment.id === commentId) {
|
||||||
|
comment.subComments.push(subComment)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
setComments(addSubComment)
|
||||||
|
}
|
||||||
|
|
||||||
|
function subCommentDelete(subComment) {
|
||||||
|
const deleteSubComment = comments
|
||||||
|
deleteSubComment.forEach((comment, index) => {
|
||||||
|
if (comment.id === subComment.parent_id) {
|
||||||
|
deleteSubComment[index].subComments = comment.subComments.filter((item) => item.id !== subComment.id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
setComments([...deleteSubComment])
|
||||||
|
}
|
||||||
|
|
||||||
const toggleTabs = (index) => {
|
const toggleTabs = (index) => {
|
||||||
dispatch(setToggleTab(index));
|
dispatch(setToggleTab(index));
|
||||||
};
|
};
|
||||||
@ -341,43 +354,14 @@ export const TicketFullScreen = ({}) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className='comments__list'>
|
<div className='comments__list'>
|
||||||
{comments.map((comment) => {
|
{comments.map((comment) => {
|
||||||
return <div className='comments__list__item' key={comment.id}>
|
return <TrackerTaskComment
|
||||||
<div className='comments__list__item__info'>
|
key={comment.id}
|
||||||
<div className='comments__list__item__fio'>
|
taskId={taskInfo.id}
|
||||||
<img src={urlForLocal(comment.user.avatar)} alt='avatar' />
|
comment={comment}
|
||||||
<p>{comment.user.fio}</p>
|
commentDelete={commentDelete}
|
||||||
</div>
|
addSubComment={addSubComment}
|
||||||
<div className='comments__list__item__date'>
|
subCommentDelete={subCommentDelete}
|
||||||
<span>{getCorrectDate(comment.created_at)}</span>
|
|
||||||
<div className={commentsEditOpen[comment.id] ? 'edit edit__open' : 'edit'} >
|
|
||||||
<img src={edit} alt='edit' onClick={() => {
|
|
||||||
if (commentsEditOpen[comment.id]) {
|
|
||||||
editComment(comment.id)
|
|
||||||
}
|
|
||||||
setCommentsEditOpen((prevValue) => ({...prevValue, [comment.id]: !prevValue[comment.id]}))
|
|
||||||
}} />
|
|
||||||
</div>
|
|
||||||
<img src={del} alt='delete' onClick={() => deleteComment(comment.id)} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{commentsEditOpen[comment.id] ? <input className='comments__list__item__text' value={commentsEditText[comment.id]} onChange={(e) => {
|
|
||||||
setCommentsEditText((prevValue) => ({...prevValue, [comment.id]: e.target.value}))
|
|
||||||
}} /> : <p className='comments__list__item__text'>{commentsEditText[comment.id]}</p>}
|
|
||||||
{subCommentsCreateOpen[comment.id] ?
|
|
||||||
<div className='comments__list__item__answer__new'>
|
|
||||||
<input />
|
|
||||||
<img src={accept} alt='accept'
|
|
||||||
onClick={() => {
|
|
||||||
setSubCommentsCreateOpen((prevValue) => ({...prevValue, [comment.id]: !prevValue[comment.id]}))
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
:
|
|
||||||
<span onClick={() => {
|
|
||||||
setSubCommentsCreateOpen((prevValue) => ({...prevValue, [comment.id]: !prevValue[comment.id]}))
|
|
||||||
}} className='comments__list__item__answer'>Ответить</span>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user