diff --git a/src/assets/icons/calendar.svg b/src/assets/icons/calendar.svg
index e8aa0d3c..1cd84ac5 100644
--- a/src/assets/icons/calendar.svg
+++ b/src/assets/icons/calendar.svg
@@ -1 +1,4 @@
-
\ No newline at end of file
+
+
diff --git a/src/components/Calendar/calendarComponent.scss b/src/components/Calendar/calendarComponent.scss
index 4beb3afe..8f980833 100644
--- a/src/components/Calendar/calendarComponent.scss
+++ b/src/components/Calendar/calendarComponent.scss
@@ -160,12 +160,17 @@
a {
color: black;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: 500;
+ font-size: 12px;
}
img {
width: 16px;
height: 16px;
- margin: 0 10px 0 0;
+ margin: 0 5px 0 0;
@media (max-width: 968px) {
margin-right: 2px;
diff --git a/src/components/Modal/Tracker/ModalTicket/ModalTicket.jsx b/src/components/Modal/Tracker/ModalTicket/ModalTicket.jsx
index c1d86bfe..f2d14230 100644
--- a/src/components/Modal/Tracker/ModalTicket/ModalTicket.jsx
+++ b/src/components/Modal/Tracker/ModalTicket/ModalTicket.jsx
@@ -25,6 +25,7 @@ import file from "assets/icons/fileModal.svg";
import link from "assets/icons/link.svg";
import send from "assets/icons/send.svg";
import watch from "assets/icons/watch.svg";
+import avatarMok from "assets/images/avatarMok.png";
import "./modalTicket.scss";
@@ -69,7 +70,7 @@ export const ModalTiсket = ({
task_id: task.id,
status: 0,
},
- }).then((res) => {
+ }).then(() => {
setActive(false);
dispatch(setProjectBoardFetch(projectId));
});
@@ -334,9 +335,9 @@ export const ModalTiсket = ({
);
}, [members]);
- function copyProjectLink() {
+ function copyTicketLink() {
navigator.clipboard.writeText(
- `https://itguild.info/tracker/project/${projectId}`
+ `https://itguild.info/tracker/task/${task.id}`
);
}
@@ -469,7 +470,12 @@ export const ModalTiсket = ({
{executor ? (
diff --git a/src/components/Modal/Tracker/ModalTicket/modalTicket.scss b/src/components/Modal/Tracker/ModalTicket/modalTicket.scss
index ac7925b8..9a1e24ca 100644
--- a/src/components/Modal/Tracker/ModalTicket/modalTicket.scss
+++ b/src/components/Modal/Tracker/ModalTicket/modalTicket.scss
@@ -129,6 +129,10 @@
width: 100%;
position: relative;
+ .ck-editor {
+ margin: 10px 0;
+ }
+
&__subComment {
&:before {
content: "";
@@ -251,6 +255,11 @@
}
}
}
+ .comment__edit--open {
+ &:after {
+ display: none;
+ }
+ }
}
}
@@ -508,7 +517,6 @@
&__creator {
font-size: 14px;
- line-height: 32px;
font-weight: 500;
color: #2d4a17;
max-width: 200px;
diff --git a/src/components/Modal/Tracker/TicketFullScreen/TicketFullScreen.jsx b/src/components/Modal/Tracker/TicketFullScreen/TicketFullScreen.jsx
index 676a0ed0..a5e264f4 100644
--- a/src/components/Modal/Tracker/TicketFullScreen/TicketFullScreen.jsx
+++ b/src/components/Modal/Tracker/TicketFullScreen/TicketFullScreen.jsx
@@ -1,3 +1,5 @@
+import ClassicEditor from "@ckeditor/ckeditor5-build-classic";
+import { CKEditor } from "@ckeditor/ckeditor5-react";
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Link, useNavigate, useParams } from "react-router-dom";
@@ -5,7 +7,6 @@ import { Link, useNavigate, useParams } from "react-router-dom";
import {
deletePersonOnProject,
getBoarderLoader,
- getProjectBoard,
modalToggle,
setProjectBoardFetch,
setToggleTab,
@@ -27,17 +28,17 @@ import TrackerTaskComment from "@components/TrackerTaskComment/TrackerTaskCommen
import archive from "assets/icons/archive.svg";
import archive2 from "assets/icons/archive.svg";
import arrow from "assets/icons/arrows/arrowCalendar.png";
-import arrow2 from "assets/icons/arrows/arrowStart.png";
+import arrowStart from "assets/icons/arrows/arrowStart.png";
import close from "assets/icons/close.png";
import del from "assets/icons/delete.svg";
import edit from "assets/icons/edit.svg";
import file from "assets/icons/fileModal.svg";
import link from "assets/icons/link.svg";
-import plus from "assets/icons/plus.svg";
import send from "assets/icons/send.svg";
import project from "assets/icons/trackerProject.svg";
import tasks from "assets/icons/trackerTasks.svg";
import watch from "assets/icons/watch.svg";
+import avatarMok from "assets/images/avatarMok.png";
import "./ticketFullScreen.scss";
@@ -46,8 +47,8 @@ export const TicketFullScreen = () => {
const ticketId = useParams();
const dispatch = useDispatch();
const navigate = useNavigate();
- const projectBoard = useSelector(getProjectBoard);
const boardLoader = useSelector(getBoarderLoader);
+ const [projectInfo, setProjectInfo] = useState({});
const [taskInfo, setTaskInfo] = useState({});
const [editOpen, setEditOpen] = useState(false);
const [inputsValue, setInputsValue] = useState({});
@@ -56,6 +57,16 @@ export const TicketFullScreen = () => {
const [personListOpen, setPersonListOpen] = useState(false);
const [timerStart, setTimerStart] = useState(false);
const [timerInfo, setTimerInfo] = useState({});
+ const [currentTimerCount, setCurrentTimerCount] = useState({
+ hours: 0,
+ minute: 0,
+ seconds: 0,
+ });
+ const [timerId, setTimerId] = useState(null);
+ const [dropListOpen, setDropListOpen] = useState(false);
+ const [correctProjectUsers, setCorrectProjectUsers] = useState([]);
+ const [dropListMembersOpen, setDropListMembersOpen] = useState(false);
+ const [users, setUsers] = useState([]);
useEffect(() => {
apiRequest(`/task/get-task?task_id=${ticketId.id}`).then((taskInfo) => {
@@ -80,13 +91,34 @@ export const TicketFullScreen = () => {
}, []);
setComments(comments);
});
- taskInfo.timers.forEach((time) => {
- if (!time.stopped_at) {
- setTimerStart(true);
- setTimerInfo(time);
- }
+ apiRequest(
+ `/timer/get-by-entity?entity_type=2&entity_id=${taskInfo.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,
+ });
+ updateTimerHours = Math.floor(timerSeconds / 60 / 60);
+ updateTimerMinute = Math.floor((timerSeconds / 60) % 60);
+ updateTimerSec = timerSeconds % 60;
+ if (!time.stopped_at) {
+ setTimerStart(true);
+ startTimer();
+ setTimerInfo(time);
+ }
+ });
+ });
+ apiRequest(
+ `/project/get-project?project_id=${taskInfo.project_id}&expand=columns`
+ ).then((res) => {
+ setProjectInfo(res);
+ setCorrectProjectUsers(res.projectUsers);
});
- dispatch(setProjectBoardFetch(taskInfo.project_id));
setLoader(boardLoader);
});
}, []);
@@ -142,6 +174,7 @@ export const TicketFullScreen = () => {
}).then((res) => {
setTimerStart(true);
setTimerInfo(res);
+ startTimer();
});
}
@@ -152,14 +185,17 @@ export const TicketFullScreen = () => {
timer_id: timerInfo.id,
stopped_at: getCorrectRequestDate(new Date()),
},
- }).then(() => setTimerStart(false));
+ }).then(() => {
+ setTimerStart(false);
+ clearInterval(timerId);
+ });
}
function deletePerson(userId) {
apiRequest("/project/del-user", {
method: "DELETE",
data: {
- project_id: projectBoard.id,
+ project_id: projectInfo.id,
user_id: userId,
},
}).then(() => {
@@ -216,6 +252,119 @@ export const TicketFullScreen = () => {
);
}
+ function startTimer() {
+ setTimerId(
+ setInterval(() => {
+ run();
+ }, 1000)
+ );
+ }
+
+ useEffect(() => {
+ if (taskInfo.taskUsers && projectInfo.projectUsers) {
+ let ids = taskInfo.taskUsers.map((user) => user.user_id);
+ setUsers(
+ projectInfo.projectUsers.reduce((acc, cur) => {
+ if (!ids.includes(cur.user_id)) acc.push(cur);
+ return acc;
+ }, [])
+ );
+ }
+ }, [taskInfo.taskUsers, projectInfo]);
+
+ let updateTimerSec = currentTimerCount.seconds,
+ updateTimerMinute = currentTimerCount.minute,
+ updateTimerHours = currentTimerCount.hours;
+
+ function run() {
+ updateTimerSec++;
+ if (updateTimerSec > 60) {
+ updateTimerMinute++;
+ updateTimerSec = 0;
+ }
+ if (updateTimerMinute === 60) {
+ updateTimerMinute = 0;
+ updateTimerHours++;
+ }
+
+ return setCurrentTimerCount({
+ hours: updateTimerHours,
+ minute: updateTimerMinute,
+ seconds: updateTimerSec,
+ });
+ }
+
+ function correctTimerTime(time) {
+ if (time < 10) return `0${time}`;
+ if (time > 10) return time;
+ }
+
+ function deleteTaskExecutor() {
+ apiRequest("/task/update-task", {
+ method: "PUT",
+ data: {
+ task_id: taskInfo.id,
+ executor_id: 0,
+ },
+ }).then(() => {
+ setTaskInfo((prevState) => ({
+ ...prevState,
+ executor_id: null,
+ executor: null,
+ }));
+ });
+ }
+
+ function taskExecutor(person) {
+ apiRequest("/task/update-task", {
+ method: "PUT",
+ data: {
+ task_id: taskInfo.id,
+ executor_id: person.user_id,
+ },
+ }).then((res) => {
+ setDropListOpen(false);
+ setTaskInfo((prevState) => ({
+ ...prevState,
+ executor_id: res.executor_id,
+ executor: res.executor,
+ }));
+ });
+ }
+
+ function deleteMember(person) {
+ apiRequest("/task/del-user", {
+ method: "DELETE",
+ data: {
+ task_id: taskInfo.id,
+ user_id: person.user_id,
+ },
+ }).then(() => {
+ setTaskInfo((prevState) => ({
+ ...prevState,
+ taskUsers: taskInfo.taskUsers.filter(
+ (item) => item.user_id !== person.user_id
+ ),
+ }));
+ });
+ }
+
+ function addMember(person) {
+ apiRequest("/task/add-user-to-task", {
+ method: "POST",
+ data: {
+ task_id: taskInfo.id,
+ user_id: person.user_id,
+ },
+ }).then((res) => {
+ setDropListMembersOpen(false);
+ setTaskInfo((prevValue) => ({
+ ...prevValue,
+ taskUsers: [...prevValue.taskUsers, res],
+ }));
+ });
+ }
+
return (
@@ -265,7 +414,7 @@ export const TicketFullScreen = () => {
-
Проект : {projectBoard.name}
+
Проект : {projectInfo.name}
{
>
-
- {projectBoard.projectUsers?.length}
-
+ {projectInfo.projectUsers?.length > 3 && (
+
+1...
+ )}
+
+ {projectInfo.projectUsers?.length &&
+ projectInfo.projectUsers.slice(0, 3).map((person) => {
+ return (
+
+ );
+ })}
+
{
@@ -294,14 +459,14 @@ export const TicketFullScreen = () => {
onClick={() => setPersonListOpen(false)}
/>
- {projectBoard.projectUsers?.length}
+ {projectInfo.projectUsers?.length}
участник
- В проекте - “{projectBoard.name}”
+ В проекте - “{projectInfo.name}”
- {projectBoard.projectUsers?.map((person) => {
+ {projectInfo.projectUsers?.map((person) => {
return (
{
>
{person.user.fio}
@@ -365,32 +534,52 @@ export const TicketFullScreen = () => {
)}
{editOpen ? (
-
{
+
{
+ const data = editor.getData();
setInputsValue((prevValue) => ({
...prevValue,
- description: e.target.value,
+ description: data,
}));
}}
/>
) : (
- {inputsValue.description}
+
)}
-
- {
- dispatch(modalToggle("addSubtask"));
- setModalAddWorker(true);
- }}
- styles={"button-green-add"}
- >
-
- Добавить под задачу
-
-
+ {/*
*/}
+ {/* {*/}
+ {/* dispatch(modalToggle("addSubtask"));*/}
+ {/* setModalAddWorker(true);*/}
+ {/* }}*/}
+ {/* styles={"button-green-add"}*/}
+ {/* >*/}
+ {/* */}
+ {/* Добавить под задачу*/}
+ {/* */}
+ {/*
*/}
@@ -430,58 +619,159 @@ export const TicketFullScreen = () => {
-
+
- Создатель : {taskInfo.user?.fio}
+ Создатель :
+ {taskInfo.user?.fio}
-
- {Boolean(taskInfo.taskUsers?.length) &&
- taskInfo.taskUsers.map((worker, index) => {
- return (
-
-
-
{worker.name}
-
- );
- })}
-
+ {taskInfo.executor ? (
+
+
Исполнитель: {taskInfo.executor.fio}
+
+
deleteTaskExecutor()}
+ />
+
+ ) : (
+
+
+
Добавить исполнителя
+ {dropListOpen && (
+
+
setDropListOpen(false)}
+ />
+ {correctProjectUsers.map((person) => {
+ return (
+
taskExecutor(person)}
+ >
+
{person.user.fio}
+
+
+ );
+ })}
+
+ )}
+
+ )}
+ {Boolean(taskInfo.taskUsers.length) && (
+
+
Участники:
+
+ {taskInfo.taskUsers.map((member) => {
+ return (
+
+
{member.fio}
+
+
deleteMember(member)}
+ />
+
+ );
+ })}
+
+
+ )}
- {
- dispatch(modalToggle("addWorker"));
- setModalAddWorker(true);
- }}
- styles={"button-add-worker"}
+
- Добавить исполнителя
-
-
-
{
- dispatch(modalToggle("addWorker"));
- setModalAddWorker(true);
- }}
- styles={"button-add-worker"}
- >
- +
-
-
+
Добавить участников
+ {dropListMembersOpen && (
+
+
setDropListMembersOpen(false)}
+ />
+ {users.length ? (
+ users.map((person) => {
+ return (
+
addMember(person)}
+ >
+
{person.user.fio}
+
+
+ );
+ })
+ ) : (
+
Нет пользователей
+ )}
+
+ )}
-
+
Длительность :
-
{"0:00:00"}
+
+ {correctTimerTime(currentTimerCount.hours)}:
+ {correctTimerTime(currentTimerCount.minute)}:
+ {correctTimerTime(currentTimerCount.seconds)}
+
{timerStart ? (
-
)}
diff --git a/src/components/Modal/Tracker/TrackerModal/TrackerModal.jsx b/src/components/Modal/Tracker/TrackerModal/TrackerModal.jsx
index 99475330..8a9db262 100644
--- a/src/components/Modal/Tracker/TrackerModal/TrackerModal.jsx
+++ b/src/components/Modal/Tracker/TrackerModal/TrackerModal.jsx
@@ -1,3 +1,5 @@
+import ClassicEditor from "@ckeditor/ckeditor5-build-classic";
+import { CKEditor } from "@ckeditor/ckeditor5-react";
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
@@ -25,6 +27,7 @@ import BaseButton from "@components/Common/BaseButton/BaseButton";
import ModalLayout from "@components/Common/ModalLayout/ModalLayout";
import arrowDown from "assets/icons/arrows/selectArrow.png";
+import avatarMok from "assets/images/avatarMok.png";
import "./trackerModal.scss";
@@ -50,7 +53,7 @@ export const TrackerModal = ({
const [valueColumn, setValueColumn] = useState("");
const [nameProject, setNameProject] = useState("");
const [valueTiket, setValueTiket] = useState("");
- const [descriptionTicket, setDescriptionTicket] = useState("");
+ const [descriptionTicket, setDescriptionTicket] = useState("Описание задачи");
const [workers, setWorkers] = useState([]);
const [selectWorkersOpen, setSelectWorkersOpen] = useState(false);
const [selectedWorker, setSelectedWorker] = useState(null);
@@ -114,13 +117,13 @@ export const TrackerModal = ({
dispatch(setProjectBoardFetch(projectBoard.id));
setActive(false);
setValueTiket("");
- setDescriptionTicket("");
+ setDescriptionTicket("Описание задачи");
setSelectedExecutorTask("Выберите исполнителя задачи");
});
} else {
setActive(false);
setValueTiket("");
- setDescriptionTicket("");
+ setDescriptionTicket("Описание задачи");
dispatch(setProjectBoardFetch(projectBoard.id));
}
});
@@ -337,14 +340,27 @@ export const TrackerModal = ({
placeholder="Название задачи"
/>
-
- setDescriptionTicket(e.target.value)}
- placeholder="Описание задачи"
- />
-
+
{
+ const data = editor.getData();
+ setDescriptionTicket(data);
+ }}
+ />
setSelectExecutorTaskOpen(!selectExecutorTaskOpen)}
className={
@@ -381,7 +397,11 @@ export const TrackerModal = ({
{person.user.fio}
diff --git a/src/components/Modal/Tracker/TrackerModal/trackerModal.scss b/src/components/Modal/Tracker/TrackerModal/trackerModal.scss
index f8eb408d..5c28876f 100644
--- a/src/components/Modal/Tracker/TrackerModal/trackerModal.scss
+++ b/src/components/Modal/Tracker/TrackerModal/trackerModal.scss
@@ -31,6 +31,7 @@
align-items: center;
flex-direction: column;
margin: 0 0 15px 0;
+ row-gap: 5px;
.select-priority {
background-color: white;
@@ -78,7 +79,7 @@
}
.input-container {
- width: 287px;
+ width: 320px;
height: 35px;
background: #ffffff;
border-radius: 8px;
@@ -89,8 +90,12 @@
}
}
+ .ck-editor {
+ max-width: 320px;
+ }
+
.select__executor {
- width: 287px;
+ width: 320px;
background: white;
border-radius: 8px;
margin: 5px 0;
diff --git a/src/components/TrackerTaskComment/TrackerTaskComment.jsx b/src/components/TrackerTaskComment/TrackerTaskComment.jsx
index 30f487e4..b7227a88 100644
--- a/src/components/TrackerTaskComment/TrackerTaskComment.jsx
+++ b/src/components/TrackerTaskComment/TrackerTaskComment.jsx
@@ -1,3 +1,5 @@
+import ClassicEditor from "@ckeditor/ckeditor5-build-classic";
+import { CKEditor } from "@ckeditor/ckeditor5-react";
import React, { useState } from "react";
import { urlForLocal } from "@utils/helper";
@@ -76,6 +78,7 @@ export const TrackerTaskComment = ({
? "comments__list__item__main"
: "",
"comments__list__item",
+ commentsEditOpen ? "comment__edit--open" : "",
comment.parent_id ? "comments__list__item__subComment" : "",
].join(" ")}
>
@@ -106,17 +109,35 @@ export const TrackerTaskComment = ({
{commentsEditOpen ? (
- {
- setCommentsEditText(e.target.value);
+ {
+ const data = editor.getData();
+ setCommentsEditText(data);
}}
/>
) : (
- {commentsEditText}
+
)}
- {!comment.parent_id && (
+ {!comment.parent_id && !commentsEditOpen && (
<>
{subCommentsCreateOpen ? (
diff --git a/src/pages/ProjectTracker/ProjectTracker.js b/src/pages/ProjectTracker/ProjectTracker.js
index 8982f294..134ff358 100644
--- a/src/pages/ProjectTracker/ProjectTracker.js
+++ b/src/pages/ProjectTracker/ProjectTracker.js
@@ -322,29 +322,24 @@ export const ProjectTracker = () => {
добавить колонку
-
- {projectBoard.projectUsers?.length}
-
+ {projectBoard.projectUsers?.length > 3 && (
+
+1...
+ )}
{projectBoard.projectUsers?.length &&
- projectBoard.projectUsers
- .slice(
- 0,
- projectBoard.length > 3 ? 3 : projectBoard.length
- )
- .map((person) => {
- return (
-
- );
- })}
+ projectBoard.projectUsers.slice(0, 3).map((person) => {
+ return (
+
+ );
+ })}
{
>
{person.user.fio}
@@ -462,7 +461,13 @@ export const ProjectTracker = () => {
- selectedTabTask(column.id, column.tasks.length)
+ selectedTabTask(
+ column.id,
+ projectBoard?.columns
+ ? projectBoard?.columns[0].tasks.at(-1)
+ .priority + 1
+ : 1
+ )
}
>
+
diff --git a/src/pages/Tracker/tracker.scss b/src/pages/Tracker/tracker.scss
index 48764b45..1a38bead 100644
--- a/src/pages/Tracker/tracker.scss
+++ b/src/pages/Tracker/tracker.scss
@@ -295,7 +295,7 @@
color: #252c32;
border: 1px solid #dde2e4;
background: white;
- left: -5px;
+ left: -6px;
}
.addPerson {
@@ -329,9 +329,11 @@
&__close {
cursor: pointer;
position: absolute;
- right: 20px;
- top: 15px;
+ right: 25px;
+ top: 25px;
margin-left: auto;
+ width: 35px;
+ height: 35px;
}
&__count {
@@ -356,7 +358,7 @@
line-height: 22px;
color: #263238;
font-weight: 500;
- margin: 13px 0 32px;
+ margin: 13px 0 10px;
span {
width: auto;