Merge pull request #83 from apuc/fix-modal-state
Fix modal state and modal window redesign
This commit is contained in:
		| @@ -1,20 +1,22 @@ | |||||||
| import React, { useEffect, useState } from "react"; | import React, { useEffect, useState } from "react"; | ||||||
| import {Link} from "react-router-dom"; | import { useDispatch } from "react-redux"; | ||||||
| import ModalSettings from "../UI/ModalSettings/ModalSettings"; | import { Link } from "react-router-dom"; | ||||||
|  | import { apiRequest } from "../../api/request"; | ||||||
|  | import { deleteProject, modalToggle } from "../../redux/projectsTrackerSlice"; | ||||||
|  | 
 | ||||||
|  | import { ModalSelect } from "../UI/ModalSelect/ModalSelect"; | ||||||
|  | import ModalAdd from "../UI/ModalAdd/ModalAdd"; | ||||||
| 
 | 
 | ||||||
| import link from "../../images/link.svg"; | import link from "../../images/link.svg"; | ||||||
| import archiveSet from "../../images/archive.svg"; | import archiveSet 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 {apiRequest} from "../../api/request"; |  | ||||||
| import {useDispatch} from "react-redux"; |  | ||||||
| import { deleteProject } from "../../redux/projectsTrackerSlice"; |  | ||||||
| 
 |  | ||||||
| import "./projectTiket.scss"; | import "./projectTiket.scss"; | ||||||
| 
 | 
 | ||||||
| export const ProjectTiket = ({ project, index }) => { | export const ProjectTiket = ({ project, index }) => { | ||||||
|   const [modalSettings, setModalSettings] = useState(false); |   const [modalSelect, setModalSelect] = useState(false); | ||||||
|  |   const [modalAdd, setModalAdd] = useState(false); | ||||||
|   const dispatch = useDispatch(); |   const dispatch = useDispatch(); | ||||||
| 
 | 
 | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
| @@ -32,20 +34,20 @@ export const ProjectTiket = ({ project, index }) => { | |||||||
|       event && |       event && | ||||||
|       !path.find((item) => item.classList && item.classList.contains("project")) |       !path.find((item) => item.classList && item.classList.contains("project")) | ||||||
|     ) { |     ) { | ||||||
|       setModalSettings(false); |       setModalSelect(false); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   function removeProject() { |   function removeProject() { | ||||||
|     apiRequest('/project/update', { |     apiRequest("/project/update", { | ||||||
|       method: 'PUT', |       method: "PUT", | ||||||
|       data: { |       data: { | ||||||
|         project_id: project.id, |         project_id: project.id, | ||||||
|         status: 0 |         status: 0, | ||||||
|       } |       }, | ||||||
|     }).then((res) => { |     }).then((res) => { | ||||||
|       dispatch(deleteProject(project)) |       dispatch(deleteProject(project)); | ||||||
|     }) |     }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
| @@ -53,16 +55,33 @@ export const ProjectTiket = ({ project, index }) => { | |||||||
|       <Link to={`/tracker/project/${project.id}`}>{project.name}</Link> |       <Link to={`/tracker/project/${project.id}`}>{project.name}</Link> | ||||||
|       <div className="project__info"> |       <div className="project__info"> | ||||||
|         <p>Открытые задачи</p> |         <p>Открытые задачи</p> | ||||||
|         <span className="count">{project.columns.reduce((accumulator, currentValue) => accumulator + currentValue.tasks.length, 0)}</span> |         <span className="count"> | ||||||
|         {/*<span className="add">{project.columns.length ? '+' : ''}</span>*/} |           {project.columns.reduce( | ||||||
|         <span className="menu-settings" onClick={() => setModalSettings(true)}> |             (accumulator, currentValue) => | ||||||
|  |               accumulator + currentValue.tasks.length, | ||||||
|  |             0 | ||||||
|  |           )} | ||||||
|  |         </span> | ||||||
|  |         <span className="menu-settings" onClick={() => setModalSelect(true)}> | ||||||
|           ... |           ... | ||||||
|         </span> |         </span> | ||||||
|       </div> |       </div> | ||||||
| 
 | 
 | ||||||
|       <ModalSettings active={modalSettings}> |       <ModalAdd | ||||||
|  |         active={modalAdd} | ||||||
|  |         setActive={setModalAdd} | ||||||
|  |         defautlInput={project.name} | ||||||
|  |       ></ModalAdd> | ||||||
|  | 
 | ||||||
|  |       <ModalSelect active={modalSelect}> | ||||||
|         <div className="project__settings-menu"> |         <div className="project__settings-menu"> | ||||||
|           <div> |           <div | ||||||
|  |             onClick={() => { | ||||||
|  |               dispatch(modalToggle("editProject")); | ||||||
|  |               setModalAdd(true); | ||||||
|  |               setModalSelect(false); | ||||||
|  |             }} | ||||||
|  |           > | ||||||
|             <img src={edit}></img> |             <img src={edit}></img> | ||||||
|             <p>редактировать</p> |             <p>редактировать</p> | ||||||
|           </div> |           </div> | ||||||
| @@ -74,13 +93,12 @@ export const ProjectTiket = ({ project, index }) => { | |||||||
|             <img src={archiveSet}></img> |             <img src={archiveSet}></img> | ||||||
|             <p>в архив</p> |             <p>в архив</p> | ||||||
|           </div> |           </div> | ||||||
|           <div |           <div onClick={removeProject}> | ||||||
|             onClick={removeProject}> |  | ||||||
|             <img src={del}></img> |             <img src={del}></img> | ||||||
|             <p>удалить</p> |             <p>удалить</p> | ||||||
|           </div> |           </div> | ||||||
|         </div> |         </div> | ||||||
|       </ModalSettings> |       </ModalSelect> | ||||||
|     </div> |     </div> | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
| @@ -83,7 +83,6 @@ | |||||||
|       color: #6f6f6f; |       color: #6f6f6f; | ||||||
|       right: 0; |       right: 0; | ||||||
|       top: -35%; |       top: -35%; | ||||||
|       z-index: 999; |  | ||||||
|  |  | ||||||
|       @media (max-width: 430px) { |       @media (max-width: 430px) { | ||||||
|         display: none; |         display: none; | ||||||
|   | |||||||
| @@ -1,17 +1,200 @@ | |||||||
| import React from "react"; | import React, { useState } from "react"; | ||||||
|  |  | ||||||
|  | import { useDispatch, useSelector } from "react-redux"; | ||||||
|  | import { apiRequest } from "../../../api/request"; | ||||||
|  | import { | ||||||
|  |   getProjectBoard, | ||||||
|  |   getValueModalType, | ||||||
|  |   setProjectBoardFetch, | ||||||
|  | } from "../../../redux/projectsTrackerSlice"; | ||||||
|  |  | ||||||
| import "./modalAdd.scss"; | import "./modalAdd.scss"; | ||||||
|  |  | ||||||
| export const ModalAdd = ({ children, active, setActive }) => { | export const ModalAdd = ({ active, setActive, selectedTab, defautlInput }) => { | ||||||
|  |   const dispatch = useDispatch(); | ||||||
|  |   const projectBoard = useSelector(getProjectBoard); | ||||||
|  |  | ||||||
|  |   const modalType = useSelector(getValueModalType); | ||||||
|  |  | ||||||
|  |   const [valueTiket, setValueTiket] = useState(""); | ||||||
|  |   const [valueColl, setValueColl] = useState(""); | ||||||
|  |   const [descriptionTicket, setDescriptionTicket] = useState(""); | ||||||
|  |  | ||||||
|  |   function createTab() { | ||||||
|  |     if (!valueColl) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     apiRequest("/project-column/create-column", { | ||||||
|  |       method: "POST", | ||||||
|  |       data: { | ||||||
|  |         project_id: projectBoard.id, | ||||||
|  |         title: valueColl, | ||||||
|  |       }, | ||||||
|  |     }).then((res) => { | ||||||
|  |       dispatch(setProjectBoardFetch(projectBoard.id)); | ||||||
|  |     }); | ||||||
|  |     setValueColl(""); | ||||||
|  |     setActive(false); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   function createTiket() { | ||||||
|  |     if (!valueTiket || !descriptionTicket) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     apiRequest("/task/create-task", { | ||||||
|  |       method: "POST", | ||||||
|  |       data: { | ||||||
|  |         project_id: projectBoard.id, | ||||||
|  |         title: valueTiket, | ||||||
|  |         description: descriptionTicket, | ||||||
|  |         status: 1, | ||||||
|  |         user_id: localStorage.getItem("id"), | ||||||
|  |         column_id: selectedTab, | ||||||
|  |       }, | ||||||
|  |     }).then((res) => { | ||||||
|  |       dispatch(setProjectBoardFetch(projectBoard.id)); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     setActive(false); | ||||||
|  |     setValueTiket(""); | ||||||
|  |     setDescriptionTicket(""); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   function getModal() { | ||||||
|  |     switch (modalType) { | ||||||
|  |       case "createColumn": | ||||||
|  |         return ( | ||||||
|  |           <div | ||||||
|  |             className="modal-add__content" | ||||||
|  |             onClick={(e) => e.stopPropagation()} | ||||||
|  |           > | ||||||
|  |             <div className="title-project"> | ||||||
|  |               <h4>Введите название колонки</h4> | ||||||
|  |               <div className="input-container"> | ||||||
|  |                 <input | ||||||
|  |                   className="name-project" | ||||||
|  |                   value={valueColl} | ||||||
|  |                   onChange={(e) => setValueColl(e.target.value)} | ||||||
|  |                 ></input> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |             <button className="button-add" onClick={createTab}> | ||||||
|  |               Создать | ||||||
|  |             </button> | ||||||
|  |             <span className="exit" onClick={() => setActive(false)}></span> | ||||||
|  |           </div> | ||||||
|  |         ); | ||||||
|  |       case "addWorker": | ||||||
|  |         return ( | ||||||
|  |           <div | ||||||
|  |             className="modal-add__content" | ||||||
|  |             onClick={(e) => e.stopPropagation()} | ||||||
|  |           > | ||||||
|  |             <div className="title-project"> | ||||||
|  |               <h4>Добавьте участника</h4> | ||||||
|  |               <p className="title-project__decs">Введите имя или e-mail </p> | ||||||
|  |               <div className="input-container"> | ||||||
|  |                 <input | ||||||
|  |                   className="name-project" | ||||||
|  |                   value={valueTiket} | ||||||
|  |                   onChange={(e) => setValueTiket(e.target.value)} | ||||||
|  |                 ></input> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |             <button className="button-add" onClick={(e) => e.preventDefault()}> | ||||||
|  |               Добавить | ||||||
|  |             </button> | ||||||
|  |             <span className="exit" onClick={() => setActive(false)}></span> | ||||||
|  |           </div> | ||||||
|  |         ); | ||||||
|  |       case "createTiketProject": | ||||||
|  |         return ( | ||||||
|  |           <div | ||||||
|  |             className="modal-add__content" | ||||||
|  |             onClick={(e) => e.stopPropagation()} | ||||||
|  |           > | ||||||
|  |             <div className="title-project"> | ||||||
|  |               <h4>Введите название и описание задачи</h4> | ||||||
|  |               <div className="input-container"> | ||||||
|  |                 <input | ||||||
|  |                   className="name-project" | ||||||
|  |                   value={valueTiket} | ||||||
|  |                   onChange={(e) => setValueTiket(e.target.value)} | ||||||
|  |                   placeholder="Название задачи" | ||||||
|  |                 ></input> | ||||||
|  |               </div> | ||||||
|  |               <div className="input-container"> | ||||||
|  |                 <input | ||||||
|  |                   className="name-project" | ||||||
|  |                   value={descriptionTicket} | ||||||
|  |                   onChange={(e) => setDescriptionTicket(e.target.value)} | ||||||
|  |                   placeholder="Описание задачи" | ||||||
|  |                 ></input> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |             <button className="button-add" onClick={createTiket}> | ||||||
|  |               Создать | ||||||
|  |             </button> | ||||||
|  |             <span className="exit" onClick={() => setActive(false)}></span> | ||||||
|  |           </div> | ||||||
|  |         ); | ||||||
|  |       case "editProject": | ||||||
|  |         return ( | ||||||
|  |           <div | ||||||
|  |             className="modal-add__content" | ||||||
|  |             onClick={(e) => e.stopPropagation()} | ||||||
|  |           > | ||||||
|  |             <div className="title-project"> | ||||||
|  |               <h4>Введите новое название</h4> | ||||||
|  |               <div className="input-container"> | ||||||
|  |                 <input | ||||||
|  |                   className="name-project" | ||||||
|  |                   value={defautlInput} | ||||||
|  |                   onChange={(e) => setValueTiket(e.target.value)} | ||||||
|  |                 ></input> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |             <button className="button-add" onClick={(e) => e.preventDefault()}> | ||||||
|  |               Сохранить | ||||||
|  |             </button> | ||||||
|  |             <span className="exit" onClick={() => setActive(false)}></span> | ||||||
|  |           </div> | ||||||
|  |         ); | ||||||
|  |       case "editColumn": | ||||||
|  |         return ( | ||||||
|  |           <div | ||||||
|  |             className="modal-add__content" | ||||||
|  |             onClick={(e) => e.stopPropagation()} | ||||||
|  |           > | ||||||
|  |             <div className="title-project"> | ||||||
|  |               <h4>Введите новое название</h4> | ||||||
|  |               <div className="input-container"> | ||||||
|  |                 <input | ||||||
|  |                   className="name-project" | ||||||
|  |                   value={defautlInput} | ||||||
|  |                   onChange={(e) => setValueTiket(e.target.value)} | ||||||
|  |                 ></input> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |             <button className="button-add" onClick={(e) => e.preventDefault()}> | ||||||
|  |               Сохранить | ||||||
|  |             </button> | ||||||
|  |             <span className="exit" onClick={() => setActive(false)}></span> | ||||||
|  |           </div> | ||||||
|  |         ); | ||||||
|  |       default: | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <div |     <div | ||||||
|       className={active ? "modal-add active" : "modal-add"} |       className={active ? "modal-add active" : "modal-add"} | ||||||
|       onClick={() => setActive(false)} |       onClick={() => setActive(false)} | ||||||
|     > |     > | ||||||
|       <div className="modal-add__content" onClick={(e) => e.stopPropagation()}> |       {getModal()} | ||||||
|         {children} |  | ||||||
|         <span className="exit" onClick={() => setActive(false)}></span> |  | ||||||
|       </div> |  | ||||||
|     </div> |     </div> | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -48,7 +48,7 @@ | |||||||
|       font-weight: 300; |       font-weight: 300; | ||||||
|       font-size: 12px; |       font-size: 12px; | ||||||
|       line-height: 14px; |       line-height: 14px; | ||||||
|       margin: -13px 0 16px 0; |       margin: 12px 0 16px 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     &__textarea { |     &__textarea { | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								src/components/UI/ModalSelect/ModalSelect.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/components/UI/ModalSelect/ModalSelect.jsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | import React from "react"; | ||||||
|  |  | ||||||
|  | import "./modalSelect.scss"; | ||||||
|  |  | ||||||
|  | export const ModalSelect = ({ active, children }) => { | ||||||
|  |   return ( | ||||||
|  |     <div className={active ? "project__settings active" : "project__settings "}> | ||||||
|  |       <span className="project__settings-ellipsis">...</span> | ||||||
|  |       {children} | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default ModalSelect; | ||||||
| @@ -21,6 +21,14 @@ | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     &-ellipsis { | ||||||
|  |       position: absolute; | ||||||
|  |       top: -2px; | ||||||
|  |       left: 10px; | ||||||
|  |       font-size: 21px; | ||||||
|  |       color: #6f6f6f; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   &__settings.active { |   &__settings.active { | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| import React from "react"; |  | ||||||
|  |  | ||||||
| import "./modalSettings.scss"; |  | ||||||
|  |  | ||||||
| export const ModalSettings = ({ active, children }) => { |  | ||||||
|   return ( |  | ||||||
|     <div className={active ? "project__settings active" : "project__settings "}> |  | ||||||
|       {children} |  | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| export default ModalSettings; |  | ||||||
| @@ -1,13 +1,15 @@ | |||||||
| import React, {useEffect, useState} from "react"; | import React, { useEffect, useState } from "react"; | ||||||
|  |  | ||||||
| import { ProfileHeader } from "../../ProfileHeader/ProfileHeader"; | import { ProfileHeader } from "../../ProfileHeader/ProfileHeader"; | ||||||
| import { ProfileBreadcrumbs } from "../../ProfileBreadcrumbs/ProfileBreadcrumbs"; | 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 ModalAdd from "../ModalAdd/ModalAdd"; | import ModalAdd from "../ModalAdd/ModalAdd"; | ||||||
|  | import { Navigation } from "../../Navigation/Navigation"; | ||||||
|  |  | ||||||
| import { useDispatch } from "react-redux"; | import { useDispatch } from "react-redux"; | ||||||
| import { setToggleTab } from "../../../redux/projectsTrackerSlice"; | import { setToggleTab } from "../../../redux/projectsTrackerSlice"; | ||||||
| import {apiRequest} from "../../../api/request"; | import { apiRequest } from "../../../api/request"; | ||||||
|  |  | ||||||
| import project from "../../../images/trackerProject.svg"; | import project from "../../../images/trackerProject.svg"; | ||||||
| import watch from "../../../images/watch.png"; | import watch from "../../../images/watch.png"; | ||||||
| @@ -32,20 +34,22 @@ export const TicketFullScreen = ({}) => { | |||||||
|   const [addSubtask, setAddSubtask] = useState(false); |   const [addSubtask, setAddSubtask] = useState(false); | ||||||
|   const [modalAddWorker, setModalAddWorker] = useState(false); |   const [modalAddWorker, setModalAddWorker] = useState(false); | ||||||
|   const [valueTiket, setValueTiket] = useState(""); |   const [valueTiket, setValueTiket] = useState(""); | ||||||
|   const ticketId = useParams() |   const ticketId = useParams(); | ||||||
|   const dispatch = useDispatch(); |   const dispatch = useDispatch(); | ||||||
|   const navigate = useNavigate(); |   const navigate = useNavigate(); | ||||||
|   const [projectInfo, setProjectInfo] = useState({}) |   const [projectInfo, setProjectInfo] = useState({}); | ||||||
|   const [taskInfo, setTaskInfo] = useState({}) |   const [taskInfo, setTaskInfo] = useState({}); | ||||||
|  |  | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     apiRequest(`/task/get-task?task_id=${ticketId.id}`).then((taskInfo) => { |     apiRequest(`/task/get-task?task_id=${ticketId.id}`).then((taskInfo) => { | ||||||
|       setTaskInfo(taskInfo) |       setTaskInfo(taskInfo); | ||||||
|       apiRequest(`/project/get-project?project_id=${taskInfo.project_id}`).then((project) => { |       apiRequest(`/project/get-project?project_id=${taskInfo.project_id}`).then( | ||||||
|         setProjectInfo(project) |         (project) => { | ||||||
|       }) |           setProjectInfo(project); | ||||||
|     }) |         } | ||||||
|   }, []) |       ); | ||||||
|  |     }); | ||||||
|  |   }, []); | ||||||
|  |  | ||||||
|   function deleteTask() { |   function deleteTask() { | ||||||
|     apiRequest("/task/update-task", { |     apiRequest("/task/update-task", { | ||||||
| @@ -55,7 +59,7 @@ export const TicketFullScreen = ({}) => { | |||||||
|         status: 0, |         status: 0, | ||||||
|       }, |       }, | ||||||
|     }).then((res) => { |     }).then((res) => { | ||||||
|       navigate(`/tracker/project/${taskInfo.project_id}`) |       navigate(`/tracker/project/${taskInfo.project_id}`); | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -66,6 +70,7 @@ export const TicketFullScreen = ({}) => { | |||||||
|   return ( |   return ( | ||||||
|     <section className="ticket-full-screen"> |     <section className="ticket-full-screen"> | ||||||
|       <ProfileHeader /> |       <ProfileHeader /> | ||||||
|  |       <Navigation /> | ||||||
|       <div className="container"> |       <div className="container"> | ||||||
|         <div className="tracker__content"> |         <div className="tracker__content"> | ||||||
|           <ProfileBreadcrumbs |           <ProfileBreadcrumbs | ||||||
| @@ -80,7 +85,7 @@ export const TicketFullScreen = ({}) => { | |||||||
|       <div className="tracker__tabs"> |       <div className="tracker__tabs"> | ||||||
|         <div className="tracker__tabs__head"> |         <div className="tracker__tabs__head"> | ||||||
|           <Link |           <Link | ||||||
|             to='/profile/tracker' |             to="/profile/tracker" | ||||||
|             className="tab active-tab" |             className="tab active-tab" | ||||||
|             onClick={() => toggleTabs(1)} |             onClick={() => toggleTabs(1)} | ||||||
|           > |           > | ||||||
| @@ -88,7 +93,7 @@ export const TicketFullScreen = ({}) => { | |||||||
|             <p>Проекты </p> |             <p>Проекты </p> | ||||||
|           </Link> |           </Link> | ||||||
|           <Link |           <Link | ||||||
|             to='/profile/tracker' |             to="/profile/tracker" | ||||||
|             className="tab" |             className="tab" | ||||||
|             onClick={() => toggleTabs(2)} |             onClick={() => toggleTabs(2)} | ||||||
|           > |           > | ||||||
| @@ -96,7 +101,7 @@ export const TicketFullScreen = ({}) => { | |||||||
|             <p>Все мои задачи</p> |             <p>Все мои задачи</p> | ||||||
|           </Link> |           </Link> | ||||||
|           <Link |           <Link | ||||||
|             to='/profile/tracker' |             to="/profile/tracker" | ||||||
|             className="tab" |             className="tab" | ||||||
|             onClick={() => toggleTabs(3)} |             onClick={() => toggleTabs(3)} | ||||||
|           > |           > | ||||||
| @@ -189,16 +194,19 @@ export const TicketFullScreen = ({}) => { | |||||||
|           </div> |           </div> | ||||||
|           <div className="workers"> |           <div className="workers"> | ||||||
|             <div className="workers_box"> |             <div className="workers_box"> | ||||||
|               <p className="workers__creator">Создатель :  <span>{taskInfo.user?.fio}</span></p> |               <p className="workers__creator"> | ||||||
|  |                 Создатель : <span>{taskInfo.user?.fio}</span> | ||||||
|  |               </p> | ||||||
|               <div> |               <div> | ||||||
|                 {Boolean(taskInfo.taskUsers?.length) && taskInfo.taskUsers.map((worker, index) => { |                 {Boolean(taskInfo.taskUsers?.length) && | ||||||
|                   return ( |                   taskInfo.taskUsers.map((worker, index) => { | ||||||
|                     <div className="worker" key={index}> |                     return ( | ||||||
|                       <img src={worker.avatar}></img> |                       <div className="worker" key={index}> | ||||||
|                       <p>{worker.name}</p> |                         <img src={worker.avatar}></img> | ||||||
|                     </div> |                         <p>{worker.name}</p> | ||||||
|                   ); |                       </div> | ||||||
|                 })} |                     ); | ||||||
|  |                   })} | ||||||
|               </div> |               </div> | ||||||
|  |  | ||||||
|               <div className="add-worker moreItems"> |               <div className="add-worker moreItems"> | ||||||
|   | |||||||
| @@ -1,11 +1,19 @@ | |||||||
| import React, {useEffect, useRef, useState} from "react"; | import React, { useEffect, useRef, useState } from "react"; | ||||||
| import {Link, useParams} from "react-router-dom"; | import { Link, useParams } from "react-router-dom"; | ||||||
| import { ProfileHeader } from "../../components/ProfileHeader/ProfileHeader"; | import { ProfileHeader } from "../../components/ProfileHeader/ProfileHeader"; | ||||||
| import { ProfileBreadcrumbs } from "../../components/ProfileBreadcrumbs/ProfileBreadcrumbs"; | import { ProfileBreadcrumbs } from "../../components/ProfileBreadcrumbs/ProfileBreadcrumbs"; | ||||||
| import { Footer } from "../../components/Footer/Footer"; | import { Footer } from "../../components/Footer/Footer"; | ||||||
|  | import { Navigation } from "../../components/Navigation/Navigation"; | ||||||
|  |  | ||||||
| import { useDispatch, useSelector } from "react-redux"; | import { useDispatch, useSelector } from "react-redux"; | ||||||
| import {getProjectBoard, moveProjectTask, setProjectBoardFetch, setToggleTab} from "../../redux/projectsTrackerSlice"; | import { apiRequest } from "../../api/request"; | ||||||
|  | import { | ||||||
|  |   getProjectBoard, | ||||||
|  |   modalToggle, | ||||||
|  |   moveProjectTask, | ||||||
|  |   setProjectBoardFetch, | ||||||
|  |   setToggleTab, | ||||||
|  | } from "../../redux/projectsTrackerSlice"; | ||||||
|  |  | ||||||
| import ModalTicket from "../../components/UI/ModalTicket/ModalTicket"; | import ModalTicket from "../../components/UI/ModalTicket/ModalTicket"; | ||||||
| import ModalAdd from "../../components/UI/ModalAdd/ModalAdd"; | import ModalAdd from "../../components/UI/ModalAdd/ModalAdd"; | ||||||
| @@ -21,422 +29,347 @@ import arrow from "../../images/arrowCalendar.png"; | |||||||
| 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 {apiRequest} from "../../api/request"; |  | ||||||
| import { Navigation } from "../../components/Navigation/Navigation"; |  | ||||||
|  |  | ||||||
| export const ProjectTracker = () => { | export const ProjectTracker = () => { | ||||||
|     const dispatch = useDispatch(); |   const dispatch = useDispatch(); | ||||||
|     const projectId = useParams() |   const projectId = useParams(); | ||||||
|     const [openColumnSelect, setOpenColumnSelect] = useState({}) |  | ||||||
|     const [selectedTab, setSelectedTab] = useState(0); |  | ||||||
|     const startWrapperIndexTest = useRef({}) |  | ||||||
|     const [wrapperHover, setWrapperHover] = useState({}); |  | ||||||
|     const projectBoard = useSelector(getProjectBoard); |  | ||||||
|     useEffect(() => { |  | ||||||
|         dispatch(setProjectBoardFetch(projectId.id)) |  | ||||||
|     }, []) |  | ||||||
|  |  | ||||||
|     useEffect(() => { |   const [openColumnSelect, setOpenColumnSelect] = useState({}); | ||||||
|         if (Object.keys(projectBoard).length) { |   const [selectedTab, setSelectedTab] = useState(0); | ||||||
|             projectBoard.columns.forEach(column => { |   const [wrapperHover, setWrapperHover] = useState({}); | ||||||
|                 setOpenColumnSelect(prevState => ({...prevState, [column.id]: false})) |   const [modalAdd, setModalAdd] = useState(false); | ||||||
|                 setWrapperHover(prevState => ({...prevState, [column.id]: false})) |   const [modalActiveTicket, setModalActiveTicket] = useState(false); | ||||||
|             }) |   const [selectedTicket, setSelectedTicket] = useState({}); | ||||||
|         } |  | ||||||
|     }, [projectBoard]) |  | ||||||
|  |  | ||||||
|     // Modal State |   const startWrapperIndexTest = useRef({}); | ||||||
|     const [modalActiveTicket, setModalActiveTicket] = useState(false); |   const projectBoard = useSelector(getProjectBoard); | ||||||
|     const [selectedTicket, setSelectedTicket] = useState({}); |  | ||||||
|     const [modalAddWorker, setModalAddWorker] = useState(false); |  | ||||||
|     const [modalCreateColl, setModalCreateColl] = useState(false); |  | ||||||
|     const [modalCreateTiket, setModalCreateTiket] = useState(false); |  | ||||||
|     const [valueTiket, setValueTiket] = useState(""); |  | ||||||
|     const [descriptionTicket, setDescriptionTicket] = useState("") |  | ||||||
|     const [valueColl, setValueColl] = useState(""); |  | ||||||
|     // |  | ||||||
|  |  | ||||||
|     // function toggleMoreTasks(columnId) { |   useEffect(() => { | ||||||
|     //     setTabTaskMok((prevArray) => |     dispatch(setProjectBoardFetch(projectId.id)); | ||||||
|     //         prevArray.map((elem, index) => { |   }, []); | ||||||
|     //             if (columnId === index) { |  | ||||||
|     //                 return { ...elem, open: !elem.open }; |  | ||||||
|     //             } else { |  | ||||||
|     //                 return elem; |  | ||||||
|     //             } |  | ||||||
|     //         }) |  | ||||||
|     //     ); |  | ||||||
|     // } |  | ||||||
|  |  | ||||||
|     function dragStartHandler(e, task, columnId) { |   useEffect(() => { | ||||||
|         startWrapperIndexTest.current = { task: task, index: columnId }; |     if (Object.keys(projectBoard).length) { | ||||||
|         setTimeout(() => { |       projectBoard.columns.forEach((column) => { | ||||||
|             e.target.classList.add("tasks__board__item__hide"); |         setOpenColumnSelect((prevState) => ({ | ||||||
|         }, 0); |           ...prevState, | ||||||
|  |           [column.id]: false, | ||||||
|  |         })); | ||||||
|  |         setWrapperHover((prevState) => ({ ...prevState, [column.id]: false })); | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   }, [projectBoard]); | ||||||
|  |  | ||||||
|  |   // function toggleMoreTasks(columnId) { | ||||||
|  |   //     setTabTaskMok((prevArray) => | ||||||
|  |   //         prevArray.map((elem, index) => { | ||||||
|  |   //             if (columnId === index) { | ||||||
|  |   //                 return { ...elem, open: !elem.open }; | ||||||
|  |   //             } else { | ||||||
|  |   //                 return elem; | ||||||
|  |   //             } | ||||||
|  |   //         }) | ||||||
|  |   //     ); | ||||||
|  |   // } | ||||||
|  |  | ||||||
|  |   function dragStartHandler(e, task, columnId) { | ||||||
|  |     startWrapperIndexTest.current = { task: task, index: columnId }; | ||||||
|  |     setTimeout(() => { | ||||||
|  |       e.target.classList.add("tasks__board__item__hide"); | ||||||
|  |     }, 0); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   function dragEndHandler(e) { | ||||||
|  |     setWrapperHover((prevState) => ({ | ||||||
|  |       [prevState]: false, | ||||||
|  |     })); | ||||||
|  |     e.target.classList.remove("tasks__board__item__hide"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   function dragOverHandler(e) { | ||||||
|  |     e.preventDefault(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   function dragEnterHandler(columnId) { | ||||||
|  |     if (columnId === startWrapperIndexTest.current.index) { | ||||||
|  |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     function dragEndHandler(e) { |     setWrapperHover((prevState) => ({ | ||||||
|         setWrapperHover(prevState => ({ |       [prevState]: false, | ||||||
|                 [prevState]: false |       [columnId]: true, | ||||||
|             }) |     })); | ||||||
|         ); |   } | ||||||
|         e.target.classList.remove("tasks__board__item__hide"); |   function dragDropHandler(e, columnId) { | ||||||
|  |     e.preventDefault(); | ||||||
|  |     if (startWrapperIndexTest.current.index === columnId) { | ||||||
|  |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     function dragOverHandler(e) { |     setWrapperHover((prevState) => ({ | ||||||
|         e.preventDefault(); |       [prevState]: false, | ||||||
|     } |     })); | ||||||
|  |  | ||||||
|     function dragEnterHandler(columnId) { |     if (columnId !== startWrapperIndexTest.current.index) { | ||||||
|         if (columnId === startWrapperIndexTest.current.index) { |       dispatch( | ||||||
|             return; |         moveProjectTask({ | ||||||
|         } |           startWrapperIndex: startWrapperIndexTest.current, | ||||||
|  |           columnId, | ||||||
|         setWrapperHover(prevState => ({ |  | ||||||
|             [prevState]: false, [columnId]: true |  | ||||||
|         })) |  | ||||||
|     } |  | ||||||
|     function dragDropHandler(e, columnId) { |  | ||||||
|         e.preventDefault(); |  | ||||||
|         if (startWrapperIndexTest.current.index === columnId) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         setWrapperHover(prevState => ({ |  | ||||||
|                 [prevState]: false |  | ||||||
|             }) |  | ||||||
|         ); |  | ||||||
|  |  | ||||||
|         if (columnId !== startWrapperIndexTest.current.index) { |  | ||||||
|             dispatch(moveProjectTask({startWrapperIndex: startWrapperIndexTest.current, columnId})) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     function selectedTabTask(columnId) { |  | ||||||
|         setSelectedTab(columnId); |  | ||||||
|         setModalCreateTiket(true); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     function openTicket(e, task) { |  | ||||||
|         setSelectedTicket(task); |  | ||||||
|         setModalActiveTicket(true); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     function createTiket() { |  | ||||||
|         if (!valueTiket || !descriptionTicket) { |  | ||||||
|             return |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         apiRequest('/task/create-task', { |  | ||||||
|             method: 'POST', |  | ||||||
|             data: { |  | ||||||
|                 project_id: projectBoard.id, |  | ||||||
|                 title: valueTiket, |  | ||||||
|                 description: descriptionTicket, |  | ||||||
|                 status: 1, |  | ||||||
|                 user_id: localStorage.getItem('id'), |  | ||||||
|                 column_id: selectedTab |  | ||||||
|             } |  | ||||||
|         }).then((res) => { |  | ||||||
|             dispatch(setProjectBoardFetch(projectBoard.id)) |  | ||||||
|         }) |         }) | ||||||
|  |       ); | ||||||
|         setModalCreateTiket(false); |  | ||||||
|         setValueTiket(""); |  | ||||||
|         setDescriptionTicket("") |  | ||||||
|     } |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|     function createTab() { |   function selectedTabTask(columnId) { | ||||||
|         if (!valueColl) { |     setSelectedTab(columnId); | ||||||
|             return |     dispatch(modalToggle("createTiketProject")); | ||||||
|         } |     setModalAdd(true); | ||||||
|  |   } | ||||||
|  |  | ||||||
|         apiRequest('/project-column/create-column', { |   function openTicket(e, task) { | ||||||
|             method: 'POST', |     setSelectedTicket(task); | ||||||
|             data: { |     setModalActiveTicket(true); | ||||||
|                 project_id: projectBoard.id, |   } | ||||||
|                 title: valueColl |  | ||||||
|             } |  | ||||||
|         }).then((res) => { |  | ||||||
|             dispatch(setProjectBoardFetch(projectBoard.id)) |  | ||||||
|         }) |  | ||||||
|         setValueColl(""); |  | ||||||
|         setModalCreateColl(false); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     function deleteColumn(id) { |   function deleteColumn(id) { | ||||||
|         apiRequest('/project-column/update-column', { |     apiRequest("/project-column/update-column", { | ||||||
|             method: 'PUT', |       method: "PUT", | ||||||
|             data: { |       data: { | ||||||
|                 column_id: id, |         column_id: id, | ||||||
|                 project_id: projectBoard.id, |         project_id: projectBoard.id, | ||||||
|                 status: 0 |         status: 0, | ||||||
|             } |       }, | ||||||
|         }).then((res) => { |     }).then((res) => { | ||||||
|             dispatch(setProjectBoardFetch(projectBoard.id)) |       dispatch(setProjectBoardFetch(projectBoard.id)); | ||||||
|         }) |     }); | ||||||
|     } |   } | ||||||
|  |  | ||||||
|     return ( |   return ( | ||||||
|         <div className="tracker"> |     <div className="tracker"> | ||||||
|             <ProfileHeader /> |       <ProfileHeader /> | ||||||
|             <Navigation /> |       <Navigation /> | ||||||
|             <div className="container"> |       <div className="container"> | ||||||
|                 <div className="tracker__content"> |         <div className="tracker__content"> | ||||||
|                     <ProfileBreadcrumbs |           <ProfileBreadcrumbs | ||||||
|                         links={[ |             links={[ | ||||||
|                             { name: "Главная", link: "/profile" }, |               { name: "Главная", link: "/profile" }, | ||||||
|                             { name: "Трекер", link: "/profile/tracker" }, |               { name: "Трекер", link: "/profile/tracker" }, | ||||||
|                         ]} |             ]} | ||||||
|                     /> |           /> | ||||||
|                     <h2 className="tracker__title">Управление проектами с трекером</h2> |           <h2 className="tracker__title">Управление проектами с трекером</h2> | ||||||
|                 </div> |         </div> | ||||||
|             </div> |       </div> | ||||||
|             <div className="tracker__tabs"> |       <div className="tracker__tabs"> | ||||||
|                 <div className="tracker__tabs__head"> |         <div className="tracker__tabs__head"> | ||||||
|                     <Link |           <Link | ||||||
|                         to='/profile/tracker' |             to="/profile/tracker" | ||||||
|                         className="tab active-tab tab" |             className="tab active-tab tab" | ||||||
|                         onClick={() => dispatch(setToggleTab(1))} |             onClick={() => dispatch(setToggleTab(1))} | ||||||
|                     > |           > | ||||||
|                         <img src={project} alt="img" /> |             <img src={project} alt="img" /> | ||||||
|                         <p>Проекты </p> |             <p>Проекты </p> | ||||||
|                     </Link> |           </Link> | ||||||
|                     <Link |           <Link | ||||||
|                         to='/profile/tracker' |             to="/profile/tracker" | ||||||
|                         className='tab' |             className="tab" | ||||||
|                         onClick={() => dispatch(setToggleTab(2))} |             onClick={() => dispatch(setToggleTab(2))} | ||||||
|                     > |           > | ||||||
|                         <img src={tasks} alt="img" /> |             <img src={tasks} alt="img" /> | ||||||
|                         <p>Все мои задачи</p> |             <p>Все мои задачи</p> | ||||||
|                     </Link> |           </Link> | ||||||
|                     <Link |           <Link | ||||||
|                         to='/profile/tracker' |             to="/profile/tracker" | ||||||
|                         className='tab' |             className="tab" | ||||||
|                         onClick={() => dispatch(setToggleTab(3))} |             onClick={() => dispatch(setToggleTab(3))} | ||||||
|                     > |           > | ||||||
|                         <img src={archive} alt="img" /> |             <img src={archive} alt="img" /> | ||||||
|                         <p>Архив</p> |             <p>Архив</p> | ||||||
|                     </Link> |           </Link> | ||||||
|                 </div> |         </div> | ||||||
|                 <div className="tracker__tabs__content"> |         <div className="tracker__tabs__content"> | ||||||
|                     <div |           <div className="tracker__tabs__content__tasks tasks active__content"> | ||||||
|                         className="tracker__tabs__content__tasks tasks active__content" |             <div className="tasks__head"> | ||||||
|                     > |               <div className="tasks__head__wrapper"> | ||||||
|                         <div className="tasks__head"> |                 <h4>Проект : {projectBoard.name}</h4> | ||||||
|                             <div className="tasks__head__wrapper"> |  | ||||||
|                                 <h4>Проект : {projectBoard.name}</h4> |  | ||||||
|  |  | ||||||
|                                 <ModalAdd |                 <ModalAdd | ||||||
|                                     active={modalCreateColl} |                   active={modalAdd} | ||||||
|                                     setActive={setModalCreateColl} |                   setActive={setModalAdd} | ||||||
|                                 > |                   selectedTab={selectedTab} | ||||||
|                                     <div className="title-project"> |                 ></ModalAdd> | ||||||
|                                         <h4>Введите название колонки</h4> |  | ||||||
|                                         <div className="input-container"> |  | ||||||
|                                             <input |  | ||||||
|                                                 className="name-project" |  | ||||||
|                                                 value={valueColl} |  | ||||||
|                                                 onChange={(e) => setValueColl(e.target.value)} |  | ||||||
|                                             ></input> |  | ||||||
|                                         </div> |  | ||||||
|                                     </div> |  | ||||||
|                                     <button className="button-add" onClick={createTab}> |  | ||||||
|                                         Создать |  | ||||||
|                                     </button> |  | ||||||
|                                 </ModalAdd> |  | ||||||
|  |  | ||||||
|                                 <ModalAdd active={modalAddWorker} setActive={setModalAddWorker}> |                 <div className="tasks__head__add"> | ||||||
|                                     <div className="title-project"> |                   <span | ||||||
|                                         <h4>Добавьте участника</h4> |                     onClick={() => { | ||||||
|                                         <p className="title-project__decs"> |                       dispatch(modalToggle("createColumn")); | ||||||
|                                             Введите имя или e-mail{" "} |                       setModalAdd(true); | ||||||
|                                         </p> |                     }} | ||||||
|                                         <div className="input-container"> |                   > | ||||||
|                                             <input |  | ||||||
|                                                 className="name-project" |  | ||||||
|                                                 value={valueTiket} |  | ||||||
|                                                 onChange={(e) => setValueTiket(e.target.value)} |  | ||||||
|                                             ></input> |  | ||||||
|                                         </div> |  | ||||||
|                                     </div> |  | ||||||
|                                     <button |  | ||||||
|                                         className="button-add" |  | ||||||
|                                         onClick={(e) => e.preventDefault()} |  | ||||||
|                                     > |  | ||||||
|                                         Добавить |  | ||||||
|                                     </button> |  | ||||||
|                                 </ModalAdd> |  | ||||||
|  |  | ||||||
|                                 <div className="tasks__head__add"> |  | ||||||
|                                     <span onClick={() => setModalCreateColl(true)}>+</span> |  | ||||||
|                                     <p>добавить колонку</p> |  | ||||||
|                                 </div> |  | ||||||
|                                 <div className="tasks__head__persons"> |  | ||||||
|                                     <img src={avatarTest} alt="avatar" /> |  | ||||||
|                                     <img src={avatarTest} alt="avatar" /> |  | ||||||
|                                     <span className="countPersons">+9</span> |  | ||||||
|                                     <span className="addPerson" onClick={setModalAddWorker}> |  | ||||||
|                     + |                     + | ||||||
|                   </span> |                   </span> | ||||||
|                                     <p>добавить участника</p> |                   <p>добавить колонку</p> | ||||||
|                                 </div> |  | ||||||
|                                 <div className="tasks__head__select"> |  | ||||||
|                                     <span>Участвую</span> |  | ||||||
|                                     <img src={selectArrow} alt="arrow" /> |  | ||||||
|                                 </div> |  | ||||||
|                                 <div className="tasks__head__select"> |  | ||||||
|                                     <span>Мои</span> |  | ||||||
|                                     <img src={selectArrow} alt="arrow" /> |  | ||||||
|                                 </div> |  | ||||||
|                                 <Link |  | ||||||
|                                     to='/profile/tracker' |  | ||||||
|                                     className="tasks__head__back" |  | ||||||
|                                 > |  | ||||||
|                                     <p>Вернуться на проекты</p> |  | ||||||
|                                     <img src={arrow} alt="arrow" /> |  | ||||||
|                                 </Link> |  | ||||||
|                             </div> |  | ||||||
|                         </div> |  | ||||||
|  |  | ||||||
|                         <ModalTicket |  | ||||||
|                             active={modalActiveTicket} |  | ||||||
|                             setActive={setModalActiveTicket} |  | ||||||
|                             task={selectedTicket} |  | ||||||
|                             projectId={projectBoard.id} |  | ||||||
|                             projectName = {projectBoard.name} |  | ||||||
|                         /> |  | ||||||
|  |  | ||||||
|                         <ModalAdd active={modalCreateTiket} setActive={setModalCreateTiket}> |  | ||||||
|                             <div className="title-project"> |  | ||||||
|                                 <h4>Введите название и описание задачи</h4> |  | ||||||
|                                 <div className="input-container"> |  | ||||||
|                                     <input |  | ||||||
|                                         className="name-project" |  | ||||||
|                                         value={valueTiket} |  | ||||||
|                                         onChange={(e) => setValueTiket(e.target.value)} |  | ||||||
|                                         placeholder='Название задачи' |  | ||||||
|                                     ></input> |  | ||||||
|                                 </div> |  | ||||||
|                                 <div className="input-container"> |  | ||||||
|                                     <input |  | ||||||
|                                         className="name-project" |  | ||||||
|                                         value={descriptionTicket} |  | ||||||
|                                         onChange={(e) => setDescriptionTicket(e.target.value)} |  | ||||||
|                                         placeholder='Описание задачи' |  | ||||||
|                                     ></input> |  | ||||||
|                                 </div> |  | ||||||
|                             </div> |  | ||||||
|                             <button className="button-add" onClick={createTiket}> |  | ||||||
|                                 Создать |  | ||||||
|                             </button> |  | ||||||
|                         </ModalAdd> |  | ||||||
|  |  | ||||||
|                         <div className="tasks__container"> |  | ||||||
|                             {Boolean(projectBoard?.columns) && Boolean(projectBoard.columns.length) && projectBoard.columns.map((column) => { |  | ||||||
|                                 return ( |  | ||||||
|                                     <div |  | ||||||
|                                         key={column.id} |  | ||||||
|                                         onDragOver={(e) => dragOverHandler(e)} |  | ||||||
|                                         onDragEnter={(e) => dragEnterHandler(column.id)} |  | ||||||
|                                         onDrop={(e) => dragDropHandler(e, column.id)} |  | ||||||
|                                         className={`tasks__board ${ |  | ||||||
|                                             column.tasks.length >= 3 ? "tasks__board__more" : "" |  | ||||||
|                                         } ${ |  | ||||||
|                                             wrapperHover[column.id] ? "tasks__board__hover" : "" |  | ||||||
|                                         }`} |  | ||||||
|                                     > |  | ||||||
|                                         <div className="board__head"> |  | ||||||
|                                             {/*<span className={wrapperIndex === 3 ? "done" : ""}>*/} |  | ||||||
|                                             <span> |  | ||||||
|                                                 {column.title} |  | ||||||
|                                             </span> |  | ||||||
|                                             <div> |  | ||||||
|                                                 <span |  | ||||||
|                                                     className="add" |  | ||||||
|                                                     onClick={() => selectedTabTask(column.id)} |  | ||||||
|                                                 > |  | ||||||
|                                                   + |  | ||||||
|                                                 </span> |  | ||||||
|                                                 <span onClick={() => { |  | ||||||
|                                                     setOpenColumnSelect(prevState => ({...prevState, [column.id]: true})) |  | ||||||
|                                                 }} className="more">...</span> |  | ||||||
|                                             </div> |  | ||||||
|                                         </div> |  | ||||||
|                                         {openColumnSelect[column.id] && |  | ||||||
|                                             <div className='column__select'> |  | ||||||
|                                                 <div className='column__select__item' onClick={() => { |  | ||||||
|                                                     setOpenColumnSelect(prevState => ({...prevState, [column.id]: false})) |  | ||||||
|                                                 }}> |  | ||||||
|                                                     <img src={edit} alt='edit' /> |  | ||||||
|                                                     <span>Изменить</span> |  | ||||||
|                                                 </div> |  | ||||||
|                                                 <div className='column__select__item' onClick={() => deleteColumn(column.id)}> |  | ||||||
|                                                     <img src={del} alt='delete' /> |  | ||||||
|                                                     <span>Удалить</span> |  | ||||||
|                                                 </div> |  | ||||||
|                                             </div> |  | ||||||
|                                         } |  | ||||||
|                                         {column.tasks.map((task, index) => { |  | ||||||
|                                             if (index > 2) { |  | ||||||
|                                                 if (!column.open) { |  | ||||||
|                                                     return; |  | ||||||
|                                                 } |  | ||||||
|                                             } |  | ||||||
|                                             return ( |  | ||||||
|                                                 <div |  | ||||||
|                                                     key={task.id} |  | ||||||
|                                                     className="tasks__board__item" |  | ||||||
|                                                     draggable={true} |  | ||||||
|                                                     onDragStart={(e) => |  | ||||||
|                                                         dragStartHandler(e, task, column.id) |  | ||||||
|                                                     } |  | ||||||
|                                                     onDragEnd={(e) => dragEndHandler(e)} |  | ||||||
|                                                     onClick={(e) => openTicket(e, task)} |  | ||||||
|                                                 > |  | ||||||
|                                                     <div className="tasks__board__item__title"> |  | ||||||
|                                                         <p>{task.title}</p> |  | ||||||
|                                                     </div> |  | ||||||
|                                                     <p className="tasks__board__item__description"> |  | ||||||
|                                                         {task.description} |  | ||||||
|                                                     </p> |  | ||||||
|                                                     <div className="tasks__board__item__info"> |  | ||||||
|                                                         <div className="tasks__board__item__info__more"> |  | ||||||
|                                                             <img src={commentsBoard} alt="commentsImg" /> |  | ||||||
|                                                             <span>{task.comments} коментариев</span> |  | ||||||
|                                                         </div> |  | ||||||
|                                                         <div className="tasks__board__item__info__more"> |  | ||||||
|                                                             <img src={filesBoard} alt="filesImg" /> |  | ||||||
|                                                             <span>{task.files} файлов</span> |  | ||||||
|                                                         </div> |  | ||||||
|                                                         {/*<div className="tasks__board__item__info__avatars">*/} |  | ||||||
|                                                         {/*  <img src={task.avatarCreated} alt="avatar" />*/} |  | ||||||
|                                                         {/*  <img src={task.avatarDo} alt="avatar" />*/} |  | ||||||
|                                                         {/*</div>*/} |  | ||||||
|                                                     </div> |  | ||||||
|                                                 </div> |  | ||||||
|                                             ); |  | ||||||
|                                         })} |  | ||||||
|                                         {column.tasks.length > 3 && ( |  | ||||||
|                                             <span |  | ||||||
|                                                 className={ |  | ||||||
|                                                     column.open |  | ||||||
|                                                         ? "lessItems openItems" |  | ||||||
|                                                         : "moreItems openItems" |  | ||||||
|                                                 } |  | ||||||
|                                                 // onClick={() => toggleMoreTasks(column.id)} |  | ||||||
|                                             > |  | ||||||
|                                                 {column.open ? "-" : "+"} |  | ||||||
|                                             </span> |  | ||||||
|                                         )} |  | ||||||
|                                     </div> |  | ||||||
|                                 ); |  | ||||||
|                             })} |  | ||||||
|                         </div> |  | ||||||
|                     </div> |  | ||||||
|                 </div> |                 </div> | ||||||
|  |                 <div className="tasks__head__persons"> | ||||||
|  |                   <img src={avatarTest} alt="avatar" /> | ||||||
|  |                   <img src={avatarTest} alt="avatar" /> | ||||||
|  |                   <span className="countPersons">+9</span> | ||||||
|  |                   <span | ||||||
|  |                     className="addPerson" | ||||||
|  |                     onClick={() => { | ||||||
|  |                       dispatch(modalToggle("addWorker")); | ||||||
|  |                       setModalAdd(true); | ||||||
|  |                     }} | ||||||
|  |                   > | ||||||
|  |                     + | ||||||
|  |                   </span> | ||||||
|  |                   <p>добавить участника</p> | ||||||
|  |                 </div> | ||||||
|  |                 <div className="tasks__head__select"> | ||||||
|  |                   <span>Участвую</span> | ||||||
|  |                   <img src={selectArrow} alt="arrow" /> | ||||||
|  |                 </div> | ||||||
|  |                 <div className="tasks__head__select"> | ||||||
|  |                   <span>Мои</span> | ||||||
|  |                   <img src={selectArrow} alt="arrow" /> | ||||||
|  |                 </div> | ||||||
|  |                 <Link to="/profile/tracker" className="tasks__head__back"> | ||||||
|  |                   <p>Вернуться на проекты</p> | ||||||
|  |                   <img src={arrow} alt="arrow" /> | ||||||
|  |                 </Link> | ||||||
|  |               </div> | ||||||
|             </div> |             </div> | ||||||
|             <Footer /> |  | ||||||
|  |             <ModalTicket | ||||||
|  |               active={modalActiveTicket} | ||||||
|  |               setActive={setModalActiveTicket} | ||||||
|  |               task={selectedTicket} | ||||||
|  |               projectId={projectBoard.id} | ||||||
|  |               projectName={projectBoard.name} | ||||||
|  |             /> | ||||||
|  |  | ||||||
|  |             <div className="tasks__container"> | ||||||
|  |               {Boolean(projectBoard?.columns) && | ||||||
|  |                 Boolean(projectBoard.columns.length) && | ||||||
|  |                 projectBoard.columns.map((column) => { | ||||||
|  |                   return ( | ||||||
|  |                     <div | ||||||
|  |                       key={column.id} | ||||||
|  |                       onDragOver={(e) => dragOverHandler(e)} | ||||||
|  |                       onDragEnter={(e) => dragEnterHandler(column.id)} | ||||||
|  |                       onDrop={(e) => dragDropHandler(e, column.id)} | ||||||
|  |                       className={`tasks__board ${ | ||||||
|  |                         column.tasks.length >= 3 ? "tasks__board__more" : "" | ||||||
|  |                       } ${ | ||||||
|  |                         wrapperHover[column.id] ? "tasks__board__hover" : "" | ||||||
|  |                       }`} | ||||||
|  |                     > | ||||||
|  |                       <div className="board__head"> | ||||||
|  |                         {/*<span className={wrapperIndex === 3 ? "done" : ""}>*/} | ||||||
|  |                         <span>{column.title}</span> | ||||||
|  |                         <div> | ||||||
|  |                           <span | ||||||
|  |                             className="add" | ||||||
|  |                             onClick={() => selectedTabTask(column.id)} | ||||||
|  |                           > | ||||||
|  |                             + | ||||||
|  |                           </span> | ||||||
|  |                           <span | ||||||
|  |                             onClick={() => { | ||||||
|  |                               setOpenColumnSelect((prevState) => ({ | ||||||
|  |                                 ...prevState, | ||||||
|  |                                 [column.id]: true, | ||||||
|  |                               })); | ||||||
|  |                             }} | ||||||
|  |                             className="more" | ||||||
|  |                           > | ||||||
|  |                             ... | ||||||
|  |                           </span> | ||||||
|  |                         </div> | ||||||
|  |                       </div> | ||||||
|  |                       {openColumnSelect[column.id] && ( | ||||||
|  |                         <div className="column__select"> | ||||||
|  |                           <div | ||||||
|  |                             className="column__select__item" | ||||||
|  |                             onClick={() => { | ||||||
|  |                               setOpenColumnSelect((prevState) => ({ | ||||||
|  |                                 ...prevState, | ||||||
|  |                                 [column.id]: false, | ||||||
|  |                               })); | ||||||
|  |                               dispatch(modalToggle("editColumn")); | ||||||
|  |                               setModalAdd(true); | ||||||
|  |                             }} | ||||||
|  |                           > | ||||||
|  |                             <img src={edit} alt="edit" /> | ||||||
|  |                             <span>Изменить</span> | ||||||
|  |                           </div> | ||||||
|  |                           <div | ||||||
|  |                             className="column__select__item" | ||||||
|  |                             onClick={() => deleteColumn(column.id)} | ||||||
|  |                           > | ||||||
|  |                             <img src={del} alt="delete" /> | ||||||
|  |                             <span>Удалить</span> | ||||||
|  |                           </div> | ||||||
|  |                         </div> | ||||||
|  |                       )} | ||||||
|  |                       {column.tasks.map((task, index) => { | ||||||
|  |                         if (index > 2) { | ||||||
|  |                           if (!column.open) { | ||||||
|  |                             return; | ||||||
|  |                           } | ||||||
|  |                         } | ||||||
|  |                         return ( | ||||||
|  |                           <div | ||||||
|  |                             key={task.id} | ||||||
|  |                             className="tasks__board__item" | ||||||
|  |                             draggable={true} | ||||||
|  |                             onDragStart={(e) => | ||||||
|  |                               dragStartHandler(e, task, column.id) | ||||||
|  |                             } | ||||||
|  |                             onDragEnd={(e) => dragEndHandler(e)} | ||||||
|  |                             onClick={(e) => openTicket(e, task)} | ||||||
|  |                           > | ||||||
|  |                             <div className="tasks__board__item__title"> | ||||||
|  |                               <p>{task.title}</p> | ||||||
|  |                             </div> | ||||||
|  |                             <p className="tasks__board__item__description"> | ||||||
|  |                               {task.description} | ||||||
|  |                             </p> | ||||||
|  |                             <div className="tasks__board__item__info"> | ||||||
|  |                               <div className="tasks__board__item__info__more"> | ||||||
|  |                                 <img src={commentsBoard} alt="commentsImg" /> | ||||||
|  |                                 <span>{task.comments} коментариев</span> | ||||||
|  |                               </div> | ||||||
|  |                               <div className="tasks__board__item__info__more"> | ||||||
|  |                                 <img src={filesBoard} alt="filesImg" /> | ||||||
|  |                                 <span>{task.files} файлов</span> | ||||||
|  |                               </div> | ||||||
|  |                               {/*<div className="tasks__board__item__info__avatars">*/} | ||||||
|  |                               {/*  <img src={task.avatarCreated} alt="avatar" />*/} | ||||||
|  |                               {/*  <img src={task.avatarDo} alt="avatar" />*/} | ||||||
|  |                               {/*</div>*/} | ||||||
|  |                             </div> | ||||||
|  |                           </div> | ||||||
|  |                         ); | ||||||
|  |                       })} | ||||||
|  |                       {column.tasks.length > 3 && ( | ||||||
|  |                         <span | ||||||
|  |                           className={ | ||||||
|  |                             column.open | ||||||
|  |                               ? "lessItems openItems" | ||||||
|  |                               : "moreItems openItems" | ||||||
|  |                           } | ||||||
|  |                           // onClick={() => toggleMoreTasks(column.id)} | ||||||
|  |                         > | ||||||
|  |                           {column.open ? "-" : "+"} | ||||||
|  |                         </span> | ||||||
|  |                       )} | ||||||
|  |                     </div> | ||||||
|  |                   ); | ||||||
|  |                 })} | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|         </div> |         </div> | ||||||
|     ); |       </div> | ||||||
|  |       <Footer /> | ||||||
|  |     </div> | ||||||
|  |   ); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -1,16 +1,15 @@ | |||||||
| import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; | import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; | ||||||
| import {apiRequest} from "../api/request"; | import { apiRequest } from "../api/request"; | ||||||
|  |  | ||||||
| const initialState = { | const initialState = { | ||||||
|   projects: [], |   projects: [], | ||||||
|   projectBoard: {}, |   projectBoard: {}, | ||||||
|   toggleTab: 1 |   toggleTab: 1, | ||||||
|  |   modalType: "", | ||||||
| }; | }; | ||||||
|  |  | ||||||
| export const setProjectBoardFetch = createAsyncThunk( | export const setProjectBoardFetch = createAsyncThunk("userInfo", (id) => | ||||||
|     'userInfo', |   apiRequest(`/project/get-project?project_id=${id}&expand=columns`) | ||||||
|     (id) => |  | ||||||
|         apiRequest(`/project/get-project?project_id=${id}&expand=columns`) |  | ||||||
| ); | ); | ||||||
|  |  | ||||||
| export const projectsTrackerSlice = createSlice({ | export const projectsTrackerSlice = createSlice({ | ||||||
| @@ -18,47 +17,61 @@ export const projectsTrackerSlice = createSlice({ | |||||||
|   initialState, |   initialState, | ||||||
|   reducers: { |   reducers: { | ||||||
|     setAllProjects: (state, action) => { |     setAllProjects: (state, action) => { | ||||||
|       state.projects = action.payload |       state.projects = action.payload; | ||||||
|     }, |     }, | ||||||
|     setProject: (state, action) => { |     setProject: (state, action) => { | ||||||
|       state.projects.push(action.payload); |       state.projects.push(action.payload); | ||||||
|     }, |     }, | ||||||
|     setToggleTab: (state, action) => { |     setToggleTab: (state, action) => { | ||||||
|       state.toggleTab = action.payload |       state.toggleTab = action.payload; | ||||||
|     }, |     }, | ||||||
|     deleteProject: (state, action) => { |     deleteProject: (state, action) => { | ||||||
|       state.projects = state.projects.filter((project) => project.id !== action.payload.id) |       state.projects = state.projects.filter( | ||||||
|  |         (project) => project.id !== action.payload.id | ||||||
|  |       ); | ||||||
|     }, |     }, | ||||||
|     moveProjectTask: (state, action) => { |     moveProjectTask: (state, action) => { | ||||||
|       state.projectBoard.columns.forEach((column, index) => { |       state.projectBoard.columns.forEach((column, index) => { | ||||||
|         if (column.id === action.payload.columnId) { |         if (column.id === action.payload.columnId) { | ||||||
|           column.tasks.push(action.payload.startWrapperIndex.task) |           column.tasks.push(action.payload.startWrapperIndex.task); | ||||||
|           apiRequest(`/task/update-task`, { |           apiRequest(`/task/update-task`, { | ||||||
|             method: 'PUT', |             method: "PUT", | ||||||
|             data: { |             data: { | ||||||
|               task_id: action.payload.startWrapperIndex.task.id, |               task_id: action.payload.startWrapperIndex.task.id, | ||||||
|               column_id: column.id |               column_id: column.id, | ||||||
|             } |             }, | ||||||
|           }).then((res) => { |           }).then((res) => {}); | ||||||
|           }) |  | ||||||
|         } |         } | ||||||
|         if (column.id === action.payload.startWrapperIndex.index) { |         if (column.id === action.payload.startWrapperIndex.index) { | ||||||
|           state.projectBoard.columns[index].tasks = column.tasks.filter((task)=> task.id !== action.payload.startWrapperIndex.task.id); |           state.projectBoard.columns[index].tasks = column.tasks.filter( | ||||||
|  |             (task) => task.id !== action.payload.startWrapperIndex.task.id | ||||||
|  |           ); | ||||||
|         } |         } | ||||||
|       }) |       }); | ||||||
|     } |     }, | ||||||
|  |     modalToggle: (state, action) => { | ||||||
|  |       state.modalType = action.payload; | ||||||
|  |     }, | ||||||
|   }, |   }, | ||||||
|   extraReducers: { |   extraReducers: { | ||||||
|     [setProjectBoardFetch.fulfilled]: (state, action) => { |     [setProjectBoardFetch.fulfilled]: (state, action) => { | ||||||
|       state.projectBoard = action.payload |       state.projectBoard = action.payload; | ||||||
|     } |     }, | ||||||
|   } |   }, | ||||||
| }); | }); | ||||||
|  |  | ||||||
| export const { setProject, deleteProject, setAllProjects, moveProjectTask, setToggleTab } = projectsTrackerSlice.actions; | export const { | ||||||
|  |   setProject, | ||||||
|  |   deleteProject, | ||||||
|  |   setAllProjects, | ||||||
|  |   moveProjectTask, | ||||||
|  |   setToggleTab, | ||||||
|  |   modalToggle, | ||||||
|  | } = projectsTrackerSlice.actions; | ||||||
|  |  | ||||||
| export const getProjects = (state) => state.tracker.projects; | export const getProjects = (state) => state.tracker.projects; | ||||||
| export const getProjectBoard = (state) => state.tracker.projectBoard; | export const getProjectBoard = (state) => state.tracker.projectBoard; | ||||||
| export const getToggleTab = (state) => state.tracker.toggleTab | export const getToggleTab = (state) => state.tracker.toggleTab; | ||||||
|  | export const getValueModalType = (state) => state.tracker.modalType; | ||||||
|  |  | ||||||
| export default projectsTrackerSlice.reducer; | export default projectsTrackerSlice.reducer; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 NikoM1k
					NikoM1k