From ca0a509077c6afe3585857da95c389371a34f33d Mon Sep 17 00:00:00 2001 From: Gubar Nikita Date: Thu, 25 Jul 2024 18:17:39 +0300 Subject: [PATCH] fix ModalTicket logic --- .../Modal/Tracker/ModalTicket/ModalTicket.jsx | 236 +++++++------ .../TrackerCardTask/TrackerCardTask.jsx | 328 +++++++++--------- src/pages/ProjectTracker/ProjectTracker.jsx | 84 +++-- src/pages/roles/DeveloperPage.jsx | 1 + 4 files changed, 364 insertions(+), 285 deletions(-) diff --git a/src/components/Modal/Tracker/ModalTicket/ModalTicket.jsx b/src/components/Modal/Tracker/ModalTicket/ModalTicket.jsx index 82d780a1..c3e3fad8 100644 --- a/src/components/Modal/Tracker/ModalTicket/ModalTicket.jsx +++ b/src/components/Modal/Tracker/ModalTicket/ModalTicket.jsx @@ -122,15 +122,6 @@ export const ModalTiсket = ({ setShowModalToReport(!showModalToReport); }; - const closeModal = () => { - setActive(false); - const currentUrl = window.location.pathname; - const newUrl = currentUrl.replace(/\/task\/\d+$/, ""); - window.history.replaceState({}, "", newUrl); - document.body.style.overflow = "auto"; - console.log(task); - }; - const [isExpanded, setIsExpanded] = useState(false); const toggleModalSize = () => { @@ -310,6 +301,17 @@ export const ModalTiсket = ({ }); } + const closeModal = () => { + if (timerStart) { + stopTaskTimer(); + } + setActive(false); + const currentUrl = window.location.pathname; + const newUrl = currentUrl.replace(/\/task\/\d+$/, ""); + window.history.replaceState({}, "", newUrl); + document.body.style.overflow = "auto"; + }; + function taskExecutor(person) { apiRequest("/task/update-task", { method: "PUT", @@ -380,82 +382,111 @@ export const ModalTiсket = ({ } useEffect(() => { - initListeners(); - apiRequest( - `/comment/get-by-entity?entity_type=2&entity_id=${task.id}` - ).then((res) => { - const comments = res.reduce((acc, cur) => { - if (!cur.parent_id) { - acc.push({ ...cur, subComments: [] }); - } else { - 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) => { - let timerSeconds = 0; - res.length && - res.forEach((time) => { - timerSeconds += time.deltaSeconds; - setCurrentTimerCount({ - hours: Math.floor(timerSeconds / 60 / 60), - minute: Math.floor((timerSeconds / 60) % 60), - seconds: timerSeconds % 60 + if (active) { + setStartDate(task.dead_line ? new Date(task.dead_line) : new Date()); + setTaskPriority(task.execution_priority); + setMembers(task.taskUsers); + setTaskTags(task.mark); + setExecutorId(task.executor_id); + setDeadLine(task.dead_line); + setExecutor(task.executor); + setInputsValue({ + title: task.title, + description: task.description, + comment: "" + }); + + initListeners(); + + apiRequest( + `/comment/get-by-entity?entity_type=2&entity_id=${task.id}` + ).then((res) => { + const comments = res.reduce((acc, cur) => { + if (!cur.parent_id) { + acc.push({ ...cur, subComments: [] }); + } else { + acc.forEach((item) => { + if (item.id === cur.parent_id) item.subComments.push(cur); }); - updateTimerHours = Math.floor(timerSeconds / 60 / 60); - updateTimerMinute = Math.floor((timerSeconds / 60) % 60); - updateTimerSec = timerSeconds % 60; - if (!time.stopped_at) { - setTimerStart(true); - startTimer(); - setTimerInfo(time); - } - }); - } - ); + } + return acc; + }, []); + setComments(comments); + }); - apiRequest(`/file/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) => { if (Array.isArray(res)) { - setTaskFiles(res); - } - } - ); + let timerSeconds = 0; + res.length && + res.forEach((time) => { + timerSeconds += time.deltaSeconds; + setCurrentTimerCount({ + hours: Math.floor(timerSeconds / 60 / 60), + minute: Math.floor((timerSeconds / 60) % 60), + seconds: timerSeconds % 60 + }); + updateTimerHours = Math.floor(timerSeconds / 60 / 60); + updateTimerMinute = Math.floor((timerSeconds / 60) % 60); + updateTimerSec = timerSeconds % 60; - if ( - localStorage.getItem("role_status") !== "18" && - Boolean( + if (!time.stopped_at) { + setTimerStart(true); + startTimer(); + setTimerInfo(time); + } + }); + } else { + setCurrentTimerCount({ + hours: 0, + minute: 0, + seconds: 0 + }); + } + }); + + apiRequest(`/file/get-by-entity?entity_type=2&entity_id=${task.id}`).then( + (res) => { + if (Array.isArray(res)) { + setTaskFiles(res); + } else { + setTaskFiles([]); + } + } + ); + + if ( + localStorage.getItem("role_status") !== "18" && + Array.isArray(correctProjectUsers) && !correctProjectUsers.find( (item) => item.user_id === profileInfo.id_user ) - ) - ) { - setCorrectProjectUsers((prevState) => [ - ...prevState, - { - user: { - avatar: profileInfo.photo, - fio: profileInfo.fio - }, - user_id: profileInfo.id_user - } - ]); + ) { + setCorrectProjectUsers((prevState) => [ + ...prevState, + { + user: { + avatar: profileInfo.photo, + fio: profileInfo.fio + }, + user_id: profileInfo.id_user + } + ]); + } } - }, []); + }, [active]); useEffect(() => { - let tagIds = taskTags.map((tag) => tag.id); - setCorrectProjectTags( - projectMarks.reduce((acc, cur) => { - if (!tagIds.includes(cur.id)) acc.push(cur); - return acc; - }, []) - ); + if (Array.isArray(taskTags)) { + const tagIds = taskTags.map((tag) => tag.id); + setCorrectProjectTags( + projectMarks.reduce((acc, cur) => { + if (!tagIds.includes(cur.id)) acc.push(cur); + return acc; + }, []) + ); + } }, [taskTags]); async function handleUpload(event) { @@ -534,13 +565,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; - }, []) - ); + if (Array.isArray(members)) { + const ids = members.map((user) => user.user_id); + setUsers( + projectUsers.reduce((acc, cur) => { + if (!ids.includes(cur.user_id)) acc.push(cur); + return acc; + }, []) + ); + } }, [members]); function copyTicketLink() { @@ -717,7 +750,7 @@ export const ModalTiсket = ({ )} {/**/} - {Boolean(taskFiles.length) && ( + {Boolean(taskFiles?.length) && (
{taskFiles.map((file) => { return ( @@ -877,7 +910,7 @@ export const ModalTiсket = ({ )}
)} - {Boolean(members.length) && ( + {Boolean(members?.length) && (
Участники:
@@ -1009,23 +1042,24 @@ export const ModalTiсket = ({
- {taskTags.map((tag) => { - return ( -
-

{tag.slug}

- delete deleteTagFromTask(tag.id)} - /> -
- ); - })} + {Array.isArray(taskTags) && + taskTags.map((tag) => { + return ( +
+

{tag.slug}

+ delete deleteTagFromTask(tag.id)} + /> +
+ ); + })}
{ - const dispatch = useDispatch(); - const [taskHover, setTaskHover] = useState({}); +const TrackerCardTask = forwardRef( + ( + { + task, + projectBoard, + titleColor, + column, + openTicket, + startWrapperIndexTest, + setWrapperHover + }, + ref + ) => { + const dispatch = useDispatch(); + const [taskHover, setTaskHover] = useState({}); - const priority = { - 2: "Высокий", - 1: "Средний", - 0: "Низкий" - }; + const priority = { + 2: "Высокий", + 1: "Средний", + 0: "Низкий" + }; - const priorityClass = { - 2: "high", - 1: "middle", - 0: "low" - }; + const priorityClass = { + 2: "high", + 1: "middle", + 0: "low" + }; - function dragDropTaskHandler(e, task, column) { - e.preventDefault(); - if (task.id === startWrapperIndexTest.current.task.id) { - return; + function dragDropTaskHandler(e, task, column) { + e.preventDefault(); + if (task.id === startWrapperIndexTest.current.task.id) { + return; + } + + const finishTask = column.tasks.indexOf(task); + + dispatch( + movePositionProjectTask({ + startTask: startWrapperIndexTest.current.task, + finishTask: task, + finishIndex: finishTask + }) + ); } - const finishTask = column.tasks.indexOf(task); + function dragOverTaskHandler(e, task) { + e.preventDefault(); + if (startWrapperIndexTest.current.task.id === task.id) { + return; + } + setTaskHover((prevState) => ({ [prevState]: false, [task.id]: true })); + } - dispatch( - movePositionProjectTask({ - startTask: startWrapperIndexTest.current.task, - finishTask: task, - finishIndex: finishTask - }) + function dragStartHandler(e, task, columnId) { + startWrapperIndexTest.current = { task: task, index: columnId }; + } + + function dragLeaveTaskHandler() { + setTaskHover((prevState) => ({ [prevState]: false })); + } + + function dragEndTaskHandler() { + setTaskHover((prevState) => ({ [prevState]: false })); + setWrapperHover((prevState) => ({ + [prevState]: false + })); + } + + useEffect(() => { + const tasksHover = {}; + const columnHover = {}; + + if (Object.keys(projectBoard).length) { + projectBoard.columns.forEach((column) => { + columnHover[column.id] = false; + column.tasks.forEach((task) => (tasksHover[task.id] = false)); + }); + } + setWrapperHover(columnHover); + setTaskHover(tasksHover); + }, [projectBoard]); + + return ( +
dragStartHandler(e, task, column.id)} + onDragOver={(e) => dragOverTaskHandler(e, task)} + onDragLeave={(e) => dragLeaveTaskHandler(e)} + onDragEnd={() => dragEndTaskHandler()} + onDrop={(e) => dragDropTaskHandler(e, task, column)} + onClick={() => openTicket(task)} + > +
+

{task.title}

+
+

+ {Boolean(task.mark.length) && ( +
+ {task.mark.map((tag) => { + return ( +
+

{tag.slug}

+
+ ); + })} +
+ )} +
+ {typeof task.execution_priority === "number" && ( +
+

+ + {priority[task.execution_priority]} + +
+ )} + {task.dead_line && ( +
+

+ + {getCorrectDate(task.dead_line)} + +
+ )} +
+ +
+
+ avatar + + {removeLast(task.executor?.fio) || "Исполнитель не назначен"} + +
+
+
+ commentsImg + {task.comment_count} +
+
+ filesImg + {task.file_count} +
+
+
+ item.id !== column.id)} + currentColumn={column} + task={task} + /> +
); } +); - function dragOverTaskHandler(e, task) { - e.preventDefault(); - if (startWrapperIndexTest.current.task.id === task.id) { - return; - } - setTaskHover((prevState) => ({ [prevState]: false, [task.id]: true })); - } - - function dragStartHandler(e, task, columnId) { - startWrapperIndexTest.current = { task: task, index: columnId }; - } - - function dragLeaveTaskHandler() { - setTaskHover((prevState) => ({ [prevState]: false })); - } - - function dragEndTaskHandler() { - setTaskHover((prevState) => ({ [prevState]: false })); - setWrapperHover((prevState) => ({ - [prevState]: false - })); - } - - useEffect(() => { - const tasksHover = {}; - const columnHover = {}; - - if (Object.keys(projectBoard).length) { - projectBoard.columns.forEach((column) => { - columnHover[column.id] = false; - column.tasks.forEach((task) => (tasksHover[task.id] = false)); - }); - } - setWrapperHover(columnHover); - setTaskHover(tasksHover); - }, [projectBoard]); - - return ( -
dragStartHandler(e, task, column.id)} - onDragOver={(e) => dragOverTaskHandler(e, task)} - onDragLeave={(e) => dragLeaveTaskHandler(e)} - onDragEnd={() => dragEndTaskHandler()} - onDrop={(e) => dragDropTaskHandler(e, task, column)} - onClick={(e) => openTicket(e, task)} - > -
-

{task.title}

-
-

- {Boolean(task.mark.length) && ( -
- {task.mark.map((tag) => { - return ( -
-

{tag.slug}

-
- ); - })} -
- )} -
- {typeof task.execution_priority === "number" && ( -
-

- - {priority[task.execution_priority]} - -
- )} - {task.dead_line && ( -
-

- - {getCorrectDate(task.dead_line)} - -
- )} -
- -
-
- avatar - - {removeLast(task.executor?.fio) || "Исполнитель не назначен"} - -
-
-
- commentsImg - {task.comment_count} -
-
- filesImg - {task.file_count} -
-
-
- item.id !== column.id)} - currentColumn={column} - task={task} - /> -
- ); -}; +TrackerCardTask.displayName = "TrackerCardTask"; export default TrackerCardTask; diff --git a/src/pages/ProjectTracker/ProjectTracker.jsx b/src/pages/ProjectTracker/ProjectTracker.jsx index 85ed1653..1e4e75ec 100644 --- a/src/pages/ProjectTracker/ProjectTracker.jsx +++ b/src/pages/ProjectTracker/ProjectTracker.jsx @@ -1,7 +1,7 @@ import moment from "moment"; import React, { useEffect, useRef, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; -import { Link, useParams } from "react-router-dom"; +import { Link, useLocation, useParams } from "react-router-dom"; import { activeLoader, @@ -51,6 +51,8 @@ import avatarMok from "assets/images/avatarMok.webp"; export const ProjectTracker = () => { const dispatch = useDispatch(); const projectId = useParams(); + const taskParams = useParams(); + const taskRefs = useRef([]); const [openColumnSelect, setOpenColumnSelect] = useState({}); const [selectedTab, setSelectedTab] = useState(0); @@ -78,6 +80,29 @@ export const ProjectTracker = () => { initListeners(); }, []); + useEffect(() => { + // const observer = new MutationObserver(() => { + // if (taskParams.taskId && taskRefs.current[taskParams.taskId]) { + // taskRefs.current[taskParams.taskId].click(); + // console.log(taskRefs.current[taskParams.taskId]); + // } + // }); + + // observer.observe(document.body, { childList: true, subtree: true }); + + // return () => observer.disconnect(); + if (projectBoard.columns && taskParams.taskId) { + for (const column of projectBoard.columns) { + const task = column.tasks.find((task) => task.id == taskParams.taskId); + if (task) { + openTicket(task); + return; + } + } + console.log(projectBoard); + } + }, [projectBoard]); + useEffect(() => { let columnsTasksEmpty = true; if (Object.keys(projectBoard).length) { @@ -145,21 +170,32 @@ export const ProjectTracker = () => { setPriorityTask(length); } - function openTicket(e, task) { + const updateUrlWithTaskId = (taskId) => { + const currentUrl = window.location.pathname; + const taskUrlSegment = `/task/`; + + if (currentUrl.includes(taskUrlSegment)) { + // Если URL содержит '/task/', заменяем старый ID на новый + const baseUrl = currentUrl.substring( + 0, + currentUrl.indexOf(taskUrlSegment) + taskUrlSegment.length + ); + const newUrl = `${baseUrl}${taskId}`; + window.history.pushState({}, "", newUrl); + } else { + // Если URL не содержит '/task/', добавляем '/task/${taskId}' + const newUrl = `${currentUrl}${taskUrlSegment}${taskId}`; + window.history.pushState({}, "", newUrl); + } + }; + + function openTicket(task) { setSelectedTicket(task); setModalActiveTicket(true); - const currentUrl = window.location.pathname; - const newUrl = `${currentUrl}/task/${task.id}`; - window.history.pushState({}, "", newUrl); + updateUrlWithTaskId(task.id); document.body.style.overflow = "hidden"; } - useEffect(() => { - const currentUrl = window.location.pathname; - const newUrl = currentUrl.replace(/\/task\/\d+$/, ""); - window.history.replaceState({}, "", newUrl); - }, []); - function deleteColumn(column) { const priorityColumns = []; apiRequest("/project-column/update-column", { @@ -421,19 +457,16 @@ export const ProjectTracker = () => {
- - {Boolean(modalActiveTicket) && ( - - )} +
{Boolean(projectBoard?.columns) && @@ -535,6 +568,9 @@ export const ProjectTracker = () => { startWrapperIndexTest={startWrapperIndexTest} task={task} titleColor={titleColor} + ref={(el) => { + taskRefs.current[task.id] = el; + }} /> ); })} diff --git a/src/pages/roles/DeveloperPage.jsx b/src/pages/roles/DeveloperPage.jsx index 5d847922..12e95663 100644 --- a/src/pages/roles/DeveloperPage.jsx +++ b/src/pages/roles/DeveloperPage.jsx @@ -24,6 +24,7 @@ export const DeveloperPage = () => { return ( } /> +