task priority

This commit is contained in:
Mikola 2023-11-21 16:40:58 +03:00
parent 67f3f3b437
commit 5b60001013
7 changed files with 372 additions and 45 deletions

View File

@ -75,6 +75,7 @@ export const ModalTiсket = ({
const [dropListOpen, setDropListOpen] = useState(false); const [dropListOpen, setDropListOpen] = useState(false);
const [dropListMembersOpen, setDropListMembersOpen] = useState(false); const [dropListMembersOpen, setDropListMembersOpen] = useState(false);
const [executor, setExecutor] = useState(task.executor); const [executor, setExecutor] = useState(task.executor);
const [taskPriority, setTaskPriority] = useState(task.execution_priority)
const [members, setMembers] = useState(task.taskUsers); const [members, setMembers] = useState(task.taskUsers);
const [taskTags, setTaskTags] = useState(task.mark); const [taskTags, setTaskTags] = useState(task.mark);
const [users, setUsers] = useState([]); const [users, setUsers] = useState([]);
@ -94,6 +95,7 @@ export const ModalTiсket = ({
const profileInfo = useSelector(getProfileInfo); const profileInfo = useSelector(getProfileInfo);
const [acceptModalOpen, setAcceptModalOpen] = useState(false); const [acceptModalOpen, setAcceptModalOpen] = useState(false);
const [selectTagsOpen, setSelectTagsOpen] = useState(false); const [selectTagsOpen, setSelectTagsOpen] = useState(false);
const [selectPriorityOpen, setSelectPriorityOpen] = useState(false)
const { showNotification } = useNotification(); const { showNotification } = useNotification();
const [commentSendDisable, setCommentSendDisable] = useState(false); const [commentSendDisable, setCommentSendDisable] = useState(false);
@ -115,6 +117,28 @@ export const ModalTiсket = ({
}); });
} }
const priority =
{
2: 'Высокий',
1: 'Средний',
0: 'Низкий'
}
const priorityTypes = [
{
name: 'Высокий',
key: 2
},
{
name: 'Средний',
key: 1
},
{
name: 'Низкий',
key: 0
},
]
function archiveTask() { function archiveTask() {
setAcceptModalOpen(true); setAcceptModalOpen(true);
} }
@ -262,6 +286,19 @@ export const ModalTiсket = ({
}); });
} }
function updateTaskPriority(key) {
setSelectPriorityOpen(false)
apiRequest("/task/update-task", {
method: "PUT",
data: {
task_id: task.id,
execution_priority: key
},
}).then(() => {
dispatch(setProjectBoardFetch(projectId));
});
}
function addMember(person) { function addMember(person) {
apiRequest("/task/add-user-to-task", { apiRequest("/task/add-user-to-task", {
method: "POST", method: "POST",
@ -969,6 +1006,30 @@ export const ModalTiсket = ({
)} )}
</div> </div>
</div> </div>
<div className='workers_box-priority'>
<div className='priority__name' onClick={() => setSelectPriorityOpen(!selectPriorityOpen)}>
<span>{typeof taskPriority === "number" ? priority[taskPriority] : 'Выберете приоритет'}</span>
<img
className={selectPriorityOpen ? "open" : ""}
src={arrowDown}
alt="arrow"
/>
</div>
{selectPriorityOpen &&
<div className='priority__dropDown'>
{priorityTypes.map((item) => {
return <div
className='priority__dropDown__item'
key={item.key}
onClick={() => {
setTaskPriority(item.key)
updateTaskPriority(item.key)
}}
>{item.name}</div>
})}
</div>
}
</div>
<div className="workers_box-bottom"> <div className="workers_box-bottom">
<div <div
className={editOpen ? "edit" : ""} className={editOpen ? "edit" : ""}

View File

@ -1091,6 +1091,64 @@
} }
} }
&-priority {
position: relative;
padding: 10px 40px 0 40px;
border-radius: 10px;
margin-bottom: 10px;
.priority {
&__name {
cursor: pointer;
width: 100%;
height: 42px;
border-radius: 8px;
background: #ddd;
padding: 8px 12px 9px 12px;
display: flex;
justify-content: space-between;
align-items: center;
span {
font-size: 14px;
color: black;
}
img {
transition: all 0.3s ease;
}
.open {
transform: rotate(180deg);
}
}
&__dropDown {
position: absolute;
padding: 5px;
background: #ebebeb;
width: 30%;
border-radius: 8px;
border: 1px solid #e4e4e4;
top: 105%;
display: flex;
flex-direction: column;
align-items: center;
font-size: 16px;
row-gap: 6px;
z-index: 10;
&__item {
cursor: pointer;
&:hover {
font-weight: 700;
}
}
}
}
}
&-bottom { &-bottom {
padding: 10px 110px 15px 56px; padding: 10px 110px 15px 56px;
font-weight: 400; font-weight: 400;

View File

@ -10,7 +10,7 @@ import { getProfileInfo } from "@redux/outstaffingSlice";
import { import {
deletePersonOnProject, deletePersonOnProject,
getBoarderLoader, getBoarderLoader,
modalToggle, modalToggle, setProjectBoardFetch,
setToggleTab, setToggleTab,
} from "@redux/projectsTrackerSlice"; } from "@redux/projectsTrackerSlice";
@ -89,19 +89,43 @@ export const TicketFullScreen = () => {
const [startDate, setStartDate] = useState(null); const [startDate, setStartDate] = useState(null);
const [uploadedFile, setUploadedFile] = useState(null); const [uploadedFile, setUploadedFile] = useState(null);
const [taskFiles, setTaskFiles] = useState([]); const [taskFiles, setTaskFiles] = useState([]);
const [taskPriority, setTaskPriority] = useState("")
const [acceptModalOpen, setAcceptModalOpen] = useState(false); const [acceptModalOpen, setAcceptModalOpen] = useState(false);
const [taskTags, setTaskTags] = useState([]); const [taskTags, setTaskTags] = useState([]);
const [selectTagsOpen, setSelectTagsOpen] = useState(false); const [selectTagsOpen, setSelectTagsOpen] = useState(false);
const [selectPriorityOpen, setSelectPriorityOpen] = useState(false)
const [correctProjectTags, setCorrectProjectTags] = useState([]); const [correctProjectTags, setCorrectProjectTags] = useState([]);
const { showNotification } = useNotification(); const { showNotification } = useNotification();
const [commentSendDisable, setCommentSendDisable] = useState(false); const [commentSendDisable, setCommentSendDisable] = useState(false);
const priority = {
2: 'Высокий',
1: 'Средний',
0: 'Низкий'
}
const priorityTypes = [
{
name: 'Высокий',
key: 2
},
{
name: 'Средний',
key: 1
},
{
name: 'Низкий',
key: 0
},
]
useEffect(() => { useEffect(() => {
initListeners(); initListeners();
apiRequest(`/task/get-task?task_id=${ticketId.id}&expand=mark`).then( apiRequest(`/task/get-task?task_id=${ticketId.id}&expand=mark`).then(
(taskInfo) => { (taskInfo) => {
setTaskInfo(taskInfo); setTaskInfo(taskInfo);
setDeadLine(taskInfo.dead_line); setDeadLine(taskInfo.dead_line);
setTaskPriority(taskInfo.execution_priority)
setStartDate( setStartDate(
taskInfo.dead_line ? new Date(taskInfo.dead_line) : new Date() taskInfo.dead_line ? new Date(taskInfo.dead_line) : new Date()
); );
@ -484,6 +508,18 @@ export const TicketFullScreen = () => {
setUploadedFile(null); setUploadedFile(null);
} }
function updateTaskPriority(key) {
setSelectPriorityOpen(false)
apiRequest("/task/update-task", {
method: "PUT",
data: {
task_id: taskInfo.id,
execution_priority: key
},
}).then(() => {
});
}
// function deleteFile(file) { // function deleteFile(file) {
// apiRequest("/file/detach", { // apiRequest("/file/detach", {
// method: "DELETE", // method: "DELETE",
@ -1103,65 +1139,91 @@ export const TicketFullScreen = () => {
</button> </button>
)} )}
</div> </div>
<div className="workers_box-tag">
<div className="workers_box-bottom">
<div className="tags"> <div className="tags">
<div className="tags__selected"> <div className="tags__selected">
{taskTags.map((tag) => { {taskTags.map((tag) => {
return ( return (
<div <div
className="tags__selected__item" className="tags__selected__item"
key={tag.id} key={tag.id}
style={{ background: tag.color }} style={{ background: tag.color }}
> >
<p>{tag.slug}</p> <p>{tag.slug}</p>
<img <img
src={close} src={close}
className="delete" className="delete"
alt="delete" alt="delete"
onClick={() => deleteTagFromTask(tag.id)} onClick={() => deleteTagFromTask(tag.id)}
/> />
</div> </div>
); );
})} })}
</div> </div>
<div <div
className="tags__select" className="tags__select"
onClick={() => setSelectTagsOpen(!selectTagsOpen)} onClick={() => setSelectTagsOpen(!selectTagsOpen)}
> >
<span>Выберете тег</span> <span>Выберете тег</span>
<img <img
className={selectTagsOpen ? "open" : ""} className={selectTagsOpen ? "open" : ""}
src={arrowDown} src={arrowDown}
alt="arrow" alt="arrow"
/> />
</div> </div>
{selectTagsOpen && ( {selectTagsOpen && (
<div className="tags__dropDown"> <div className="tags__dropDown">
<img <img
onClick={() => setSelectTagsOpen(false)} onClick={() => setSelectTagsOpen(false)}
className="tags__dropDown__close" className="tags__dropDown__close"
src={close} src={close}
alt="close" alt="close"
/> />
{correctProjectTags.map((tag) => { {correctProjectTags.map((tag) => {
return ( return (
<div <div
className="tagItem" className="tagItem"
key={tag.id} key={tag.id}
onClick={() => addTagToTask(tag.id)} onClick={() => addTagToTask(tag.id)}
> >
<p>{tag.slug}</p> <p>{tag.slug}</p>
<span style={{ background: tag.color }} /> <span style={{ background: tag.color }} />
</div> </div>
); );
})} })}
{!Boolean(correctProjectTags.length) && ( {!Boolean(correctProjectTags.length) && (
<p className="tags__dropDown__noItem">Нет тегов</p> <p className="tags__dropDown__noItem">Нет тегов</p>
)} )}
</div> </div>
)} )}
</div> </div>
</div>
<div className='workers_box-priority'>
<div className='priority__name' onClick={() => setSelectPriorityOpen(!selectPriorityOpen)}>
<span>{typeof taskPriority === "number" ? priority[taskPriority] : 'Выберете приоритет'}</span>
<img
className={selectPriorityOpen ? "open" : ""}
src={arrowDown}
alt="arrow"
/>
</div>
{selectPriorityOpen &&
<div className='priority__dropDown'>
{priorityTypes.map((item) => {
return <div
className='priority__dropDown__item'
key={item.key}
onClick={() => {
setTaskPriority(item.key)
updateTaskPriority(item.key)
}}
>{item.name}</div>
})}
</div>
}
</div>
<div className="workers_box-bottom">
<div <div
className={editOpen ? "edit" : ""} className={editOpen ? "edit" : ""}
onClick={() => { onClick={() => {

View File

@ -32,7 +32,6 @@ import { getCorrectDate } from "@components/Calendar/calendarHelper";
import BaseButton from "@components/Common/BaseButton/BaseButton"; import BaseButton from "@components/Common/BaseButton/BaseButton";
import ModalLayout from "@components/Common/ModalLayout/ModalLayout"; import ModalLayout from "@components/Common/ModalLayout/ModalLayout";
import arrowCreateTask from "assets/icons/arrows/arrowCreateTask.svg";
import arrowRight from "assets/icons/arrows/arrowRightCreateTask.svg"; import arrowRight from "assets/icons/arrows/arrowRightCreateTask.svg";
import arrowDown from "assets/icons/arrows/selectArrow.png"; import arrowDown from "assets/icons/arrows/selectArrow.png";
import close from "assets/icons/close.png"; import close from "assets/icons/close.png";
@ -82,6 +81,8 @@ export const TrackerModal = ({
const [correctProjectTags, setCorrectProjectTags] = useState([]); const [correctProjectTags, setCorrectProjectTags] = useState([]);
const [taskTags, setTaskTags] = useState([]); const [taskTags, setTaskTags] = useState([]);
const [selectTagsOpen, setSelectTagsOpen] = useState(false); const [selectTagsOpen, setSelectTagsOpen] = useState(false);
const [selectedPriority, setSelectedPriority] = useState(null)
const [selectPriority, setSelectPriority] = useState(false)
const [selectColumnPriorityOpen, setSelectColumnPriorityOpen] = const [selectColumnPriorityOpen, setSelectColumnPriorityOpen] =
useState(false); useState(false);
const { showNotification } = useNotification(); const { showNotification } = useNotification();
@ -89,6 +90,21 @@ export const TrackerModal = ({
const [datePickerOpen, setDatePickerOpen] = useState(false); const [datePickerOpen, setDatePickerOpen] = useState(false);
const [startDate, setStartDate] = useState(new Date()); const [startDate, setStartDate] = useState(new Date());
const priority = [
{
name: 'Высокий',
key: 2
},
{
name: 'Средний',
key: 1
},
{
name: 'Низкий',
key: 0
},
]
function createTab() { function createTab() {
if (!valueColumn) { if (!valueColumn) {
showNotification({ show: true, text: "Введите название", type: "error" }); showNotification({ show: true, text: "Введите название", type: "error" });
@ -130,6 +146,7 @@ export const TrackerModal = ({
status: 1, status: 1,
user_id: localStorage.getItem("id"), user_id: localStorage.getItem("id"),
column_id: selectedTab, column_id: selectedTab,
execution_priority: selectedPriority ? selectedPriority.key : '',
priority: priorityTask, priority: priorityTask,
dead_line: deadLineDate ? getCorrectRequestDate(deadLineDate) : "", dead_line: deadLineDate ? getCorrectRequestDate(deadLineDate) : "",
}, },
@ -166,6 +183,7 @@ export const TrackerModal = ({
setValueTiket(""); setValueTiket("");
setDescriptionTicket(""); setDescriptionTicket("");
setSelectedExecutorTask("Выберите исполнителя задачи"); setSelectedExecutorTask("Выберите исполнителя задачи");
setSelectedPriority(null)
}); });
} else { } else {
setActive(false); setActive(false);
@ -587,6 +605,34 @@ export const TrackerModal = ({
</div> </div>
)} )}
</div> </div>
<div className='select__priority'>
<div className='select__priority__name'
onClick={() => setSelectPriority(!selectPriority)}
>
{selectedPriority ? `Приоритет: ${selectedPriority.name}` : 'Выберети приоритет'}
<img
className={
selectPriority ? "arrow arrow--open" : "arrow"
}
src={arrowDown}
alt="arrow"
/>
</div>
{selectPriority &&
<div className='select__priority__dropDown'>
{priority.map((item) => {
return <div
className='dropdown__item'
key={item.key}
onClick={() => {
setSelectPriority(false)
setSelectedPriority(item)
}}
>{item.name}</div>
})}
</div>
}
</div>
<div <div
onClick={() => onClick={() =>
setSelectExecutorTaskOpen(!selectExecutorTaskOpen) setSelectExecutorTaskOpen(!selectExecutorTaskOpen)

View File

@ -520,6 +520,57 @@
} }
} }
.select__priority {
position: relative;
&__name {
color: #000;
width: 393px;
height: 47px;
font-size: 15px;
font-weight: 400;
line-height: normal;
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
padding: 9.5px 12px;
border-radius: 8px;
height: 47px;
border: 1px solid #e4e4e4;
margin-bottom: 10px;
}
&__dropDown {
position: absolute;
border-radius: 8px;
padding: 9.5px 12px;
display: flex;
flex-direction: column;
row-gap: 5px;
width: 100%;
background: #f1f1f1;
z-index: 101;
.dropdown__item {
font-size: 16px;
cursor: pointer;
&:hover {
font-weight: 700;
}
}
}
img {
transition: all 0.3s ease;
}
.arrow--open {
transform: rotate(180deg);
}
}
.select__executor { .select__executor {
background: #f1f1f1; background: #f1f1f1;
width: 393px; width: 393px;

View File

@ -90,6 +90,19 @@ export const ProjectTracker = () => {
const loader = useSelector(getBoarderLoader); const loader = useSelector(getBoarderLoader);
const { showNotification } = useNotification(); const { showNotification } = useNotification();
const priority =
{
2: 'Высокий',
1: 'Средний',
0: 'Низкий'
}
const priorityClass = {
2: 'high',
1: 'middle',
0: 'low'
}
useEffect(() => { useEffect(() => {
dispatch(activeLoader()); dispatch(activeLoader());
dispatch(setProjectBoardFetch(projectId.id)); dispatch(setProjectBoardFetch(projectId.id));
@ -998,6 +1011,12 @@ export const ProjectTracker = () => {
})} })}
</div> </div>
)} )}
{typeof task.execution_priority === "number" &&
<div className='tasks__board__item__priority'>
<p>Приоритет:</p>
<span className={priorityClass[task.execution_priority]}>{priority[task.execution_priority]}</span>
</div>
}
{task.dead_line && ( {task.dead_line && (
<div className="tasks__board__item__deadLine"> <div className="tasks__board__item__deadLine">
<p>Срок исполнения:</p> <p>Срок исполнения:</p>

View File

@ -1124,6 +1124,36 @@
} }
} }
&__priority {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
p {
font-weight: 500;
font-size: 14px;
}
span {
font-weight: 500;
font-size: 14px;
}
.high {
color: red;
}
.middle {
color: #cece00;
}
.low {
color: green;
}
}
&__deadLine { &__deadLine {
display: flex; display: flex;
align-items: center; align-items: center;