Pull from main page
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import TrackerModal from "../TrackerModal/TrackerModal";
|
||||
import { apiRequest } from "../../../api/request";
|
||||
@ -32,6 +32,8 @@ export const ModalTiсket = ({
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const [addSubtask, setAddSubtask] = useState(false);
|
||||
const [editOpen, setEditOpen] = useState(false);
|
||||
const [inputsValue, setInputsValue] = useState({title: task.title, description: task.description})
|
||||
|
||||
function deleteTask() {
|
||||
apiRequest("/task/update-task", {
|
||||
@ -46,6 +48,19 @@ export const ModalTiсket = ({
|
||||
});
|
||||
}
|
||||
|
||||
function editTask() {
|
||||
apiRequest("/task/update-task", {
|
||||
method: "PUT",
|
||||
data: {
|
||||
task_id: task.id,
|
||||
title: inputsValue.title,
|
||||
description: inputsValue.description
|
||||
},
|
||||
}).then((res) => {
|
||||
dispatch(setProjectBoardFetch(projectId));
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={active ? "modal-tiket active" : "modal-tiket"}
|
||||
@ -69,11 +84,14 @@ export const ModalTiсket = ({
|
||||
|
||||
<div className="content__task">
|
||||
<span>Задача</span>
|
||||
<h5>{task.title}</h5>
|
||||
{editOpen ? <input value={inputsValue.title} onChange={(e) => {
|
||||
setInputsValue((prevValue) => ({...prevValue, title: e.target.value}))
|
||||
}} /> :<h5>{inputsValue.title}</h5>}
|
||||
<div className="content__description">
|
||||
<p>{task.description}</p>
|
||||
{editOpen ? <input value={inputsValue.description} onChange={(e) => {
|
||||
setInputsValue((prevValue) => ({...prevValue, description: e.target.value}))
|
||||
}}/> :<p>{inputsValue.description}</p>}
|
||||
<img src={taskImg} className="image-task"></img>
|
||||
<p>{task.description}</p>
|
||||
</div>
|
||||
<div className="content__communication">
|
||||
<p className="tasks">
|
||||
@ -138,15 +156,22 @@ export const ModalTiсket = ({
|
||||
</div>
|
||||
|
||||
<div className="workers_box-bottom">
|
||||
<div>
|
||||
<div className={editOpen ? 'edit' : ''} onClick={() => {
|
||||
if(editOpen) {
|
||||
setEditOpen(!editOpen)
|
||||
editTask()
|
||||
} else {
|
||||
setEditOpen(!editOpen)
|
||||
}
|
||||
}}>
|
||||
<img src={edit}></img>
|
||||
<p>редактировать</p>
|
||||
<p>{editOpen ? 'сохранить' : 'редактировать'}</p>
|
||||
</div>
|
||||
<div>
|
||||
<img src={link}></img>
|
||||
<p>ссылка на проект</p>
|
||||
</div>
|
||||
<div>
|
||||
<div onClick={deleteTask}>
|
||||
<img src={archive}></img>
|
||||
<p>в архив</p>
|
||||
</div>
|
||||
|
@ -6,14 +6,13 @@
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transform: scale(0);
|
||||
}
|
||||
|
||||
.modal-tiket.active {
|
||||
transform: scale(1);
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.modal-tiket__content {
|
||||
@ -50,6 +49,16 @@
|
||||
&__task {
|
||||
margin-top: -5px;
|
||||
padding: 18px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
input {
|
||||
font-style: normal;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
max-width: 340px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
button {
|
||||
img {
|
||||
@ -64,10 +73,14 @@
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
color: #1a1919;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__description {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: 10px;
|
||||
p {
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
@ -77,7 +90,8 @@
|
||||
}
|
||||
|
||||
.image-task {
|
||||
margin: 0 0 20px 0;
|
||||
margin: 10px 0 20px 0;
|
||||
max-width: 330px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -313,11 +327,21 @@
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
padding-left: 10px;
|
||||
|
||||
p {
|
||||
margin: 0 0 0 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.edit {
|
||||
background: #52b709;
|
||||
border-radius: 50px;
|
||||
|
||||
p {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,10 @@ import { Footer } from "../../Footer/Footer";
|
||||
import { Link, useParams, useNavigate } from "react-router-dom";
|
||||
import TrackerModal from "../TrackerModal/TrackerModal";
|
||||
import { Navigation } from "../../Navigation/Navigation";
|
||||
import {Loader} from "../../Loader/Loader";
|
||||
|
||||
import { useDispatch } from "react-redux";
|
||||
import { modalToggle, setToggleTab } from "../../../redux/projectsTrackerSlice";
|
||||
import {modalToggle, setToggleTab} from "../../../redux/projectsTrackerSlice";
|
||||
import { apiRequest } from "../../../api/request";
|
||||
|
||||
import project from "../../../images/trackerProject.svg";
|
||||
@ -37,13 +38,18 @@ export const TicketFullScreen = ({}) => {
|
||||
const navigate = useNavigate();
|
||||
const [projectInfo, setProjectInfo] = useState({});
|
||||
const [taskInfo, setTaskInfo] = useState({});
|
||||
const [editOpen, setEditOpen] = useState(false);
|
||||
const [inputsValue, setInputsValue] = useState({})
|
||||
const [loader, setLoader] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
apiRequest(`/task/get-task?task_id=${ticketId.id}`).then((taskInfo) => {
|
||||
setTaskInfo(taskInfo);
|
||||
setInputsValue({title: taskInfo.title, description: taskInfo.description})
|
||||
apiRequest(`/project/get-project?project_id=${taskInfo.project_id}`).then(
|
||||
(project) => {
|
||||
setProjectInfo(project);
|
||||
setLoader(false)
|
||||
}
|
||||
);
|
||||
});
|
||||
@ -61,6 +67,18 @@ export const TicketFullScreen = ({}) => {
|
||||
});
|
||||
}
|
||||
|
||||
function editTask() {
|
||||
apiRequest("/task/update-task", {
|
||||
method: "PUT",
|
||||
data: {
|
||||
task_id: taskInfo.id,
|
||||
title: inputsValue.title,
|
||||
description: inputsValue.description
|
||||
},
|
||||
}).then((res) => {
|
||||
});
|
||||
}
|
||||
|
||||
const toggleTabs = (index) => {
|
||||
dispatch(setToggleTab(index));
|
||||
};
|
||||
@ -107,6 +125,8 @@ export const TicketFullScreen = ({}) => {
|
||||
<p>Архив</p>
|
||||
</Link>
|
||||
</div>
|
||||
{loader ? <Loader /> :
|
||||
<>
|
||||
<div className="tracker__tabs__content content-tabs">
|
||||
<div className="tasks__head">
|
||||
<div className="tasks__head__wrapper">
|
||||
@ -153,11 +173,14 @@ export const TicketFullScreen = ({}) => {
|
||||
<div className="content ticket-whith">
|
||||
<div className="content__task">
|
||||
<span>Задача</span>
|
||||
<h5>{taskInfo.title}</h5>
|
||||
{editOpen ? <input value={inputsValue.title} onChange={(e) => {
|
||||
setInputsValue((prevValue) => ({...prevValue, title: e.target.value}))
|
||||
}} /> :<h5>{inputsValue.title}</h5>}
|
||||
<div className="content__description">
|
||||
<p>{taskInfo.description}</p>
|
||||
{editOpen ? <input value={inputsValue.description} onChange={(e) => {
|
||||
setInputsValue((prevValue) => ({...prevValue, description: e.target.value}))
|
||||
}}/> :<p>{inputsValue.description}</p>}
|
||||
<img src={task} className="image-task"></img>
|
||||
<p>{taskInfo.description}</p>
|
||||
</div>
|
||||
<div className="content__communication">
|
||||
<p className="tasks">
|
||||
@ -229,9 +252,16 @@ export const TicketFullScreen = ({}) => {
|
||||
</div>
|
||||
|
||||
<div className="workers_box-bottom">
|
||||
<div>
|
||||
<div className={editOpen ? 'edit' : ''} onClick={() => {
|
||||
if(editOpen) {
|
||||
setEditOpen(!editOpen)
|
||||
editTask()
|
||||
} else {
|
||||
setEditOpen(!editOpen)
|
||||
}
|
||||
}}>
|
||||
<img src={edit}></img>
|
||||
<p>редактировать</p>
|
||||
<p>{editOpen ? 'сохранить' : 'редактировать'}</p>
|
||||
</div>
|
||||
<div>
|
||||
<img src={link}></img>
|
||||
@ -248,6 +278,8 @@ export const TicketFullScreen = ({}) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
<Footer />
|
||||
</section>
|
||||
|
@ -1,16 +1,22 @@
|
||||
import React, { useState } from "react";
|
||||
import React, {useEffect, useState} from "react";
|
||||
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { apiRequest } from "../../../api/request";
|
||||
import { urlForLocal } from '../../../helper'
|
||||
import {
|
||||
setColumnName,
|
||||
getProjectBoard,
|
||||
getValueModalType,
|
||||
setProject,
|
||||
setProjectBoardFetch,
|
||||
editProjectName,
|
||||
getColumnTitle,
|
||||
editColumnName,
|
||||
getColumnName,
|
||||
getColumnId
|
||||
} from "../../../redux/projectsTrackerSlice";
|
||||
|
||||
import arrowDown from "../../../images/selectArrow.png"
|
||||
|
||||
import "./trackerModal.scss";
|
||||
|
||||
export const TrackerModal = ({
|
||||
@ -20,22 +26,22 @@ export const TrackerModal = ({
|
||||
defautlInput,
|
||||
titleProject,
|
||||
projectId,
|
||||
titleColumn
|
||||
priorityTask
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const projectBoard = useSelector(getProjectBoard);
|
||||
const columnName = useSelector(getColumnName);
|
||||
const columnId = useSelector(getColumnId)
|
||||
|
||||
const modalType = useSelector(getValueModalType);
|
||||
|
||||
const [emailWorker, setEmailWorker] = useState("");
|
||||
const [projectName, setProjectName] = useState(defautlInput);
|
||||
const [editTitleColumn, setEditTitleColumn] = useState(titleColumn);
|
||||
|
||||
const [valueColumn, setValueColumn] = useState("");
|
||||
const [nameProject, setNameProject] = useState("");
|
||||
|
||||
const [valueTiket, setValueTiket] = useState("");
|
||||
const [descriptionTicket, setDescriptionTicket] = useState("");
|
||||
const [workers, setWorkers] = useState([])
|
||||
const [selectWorkersOpen, setSelectWorkersOpen] = useState(false)
|
||||
const [selectedWorker, setSelectedWorker] = useState(null)
|
||||
|
||||
function createTab() {
|
||||
if (!valueColumn) {
|
||||
@ -69,6 +75,7 @@ export const TrackerModal = ({
|
||||
status: 1,
|
||||
user_id: localStorage.getItem("id"),
|
||||
column_id: selectedTab,
|
||||
priority: priorityTask
|
||||
},
|
||||
}).then((res) => {
|
||||
dispatch(setProjectBoardFetch(projectBoard.id));
|
||||
@ -92,6 +99,19 @@ export const TrackerModal = ({
|
||||
});
|
||||
}
|
||||
|
||||
function changeColumnName() {
|
||||
apiRequest("/project-column/update-column", {
|
||||
method: "PUT",
|
||||
data: {
|
||||
column_id: columnId,
|
||||
title: columnName
|
||||
}
|
||||
}).then((res) => {
|
||||
setActive(false);
|
||||
dispatch(editColumnName({id: columnId, title: columnName}))
|
||||
})
|
||||
}
|
||||
|
||||
function createProject() {
|
||||
if (nameProject === "") {
|
||||
return;
|
||||
@ -112,6 +132,23 @@ export const TrackerModal = ({
|
||||
}
|
||||
}
|
||||
|
||||
function addUserToProject() {
|
||||
apiRequest("/project/add-user", {
|
||||
method: "POST",
|
||||
data: {
|
||||
user_id: selectedWorker.id,
|
||||
project_id: projectBoard.id
|
||||
}
|
||||
}).then((el) => {
|
||||
setActive(false);
|
||||
selectedWorker(null)
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
modalType === "addWorker" ? apiRequest('/project/my-employee').then((el) => setWorkers(el.managerEmployees)) : ''
|
||||
}, [modalType])
|
||||
|
||||
return (
|
||||
<div
|
||||
className={active ? "modal-add active" : "modal-add"}
|
||||
@ -122,21 +159,35 @@ export const TrackerModal = ({
|
||||
<div>
|
||||
<div className="title-project">
|
||||
<h4>Добавьте участника</h4>
|
||||
<p className="title-project__decs">Введите имя или e-mail </p>
|
||||
<div className="input-container">
|
||||
<input
|
||||
className="name-project"
|
||||
value={emailWorker}
|
||||
onChange={(e) => setEmailWorker(e.target.value)}
|
||||
/>
|
||||
{/*<div className="input-container">*/}
|
||||
{/* <input*/}
|
||||
{/* className="name-project"*/}
|
||||
{/* value={emailWorker}*/}
|
||||
{/* onChange={(e) => setEmailWorker(e.target.value)}*/}
|
||||
{/* />*/}
|
||||
{/*</div>*/}
|
||||
<div className={selectWorkersOpen ? 'select__worker open' : 'select__worker'} onClick={() => setSelectWorkersOpen(!selectWorkersOpen)}>
|
||||
<p>{selectedWorker ? selectedWorker.employee.fio : 'Выберите пользователя'}</p>
|
||||
<img className='arrow' src={arrowDown} alt='arrow' />
|
||||
{Boolean(selectWorkersOpen) &&
|
||||
<div className='select__worker__dropDown'>
|
||||
{workers.map((worker) => {
|
||||
if (worker === selectedWorker) {
|
||||
return
|
||||
}
|
||||
return <div className='worker' key={worker.id} onClick={() => setSelectedWorker(worker)}>
|
||||
<p>{worker.employee.fio}</p>
|
||||
<img src={urlForLocal(worker.employee.avatar)} alt='avatar'/>
|
||||
</div>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
className="button-add"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setActive(false);
|
||||
}}
|
||||
onClick={addUserToProject}
|
||||
>
|
||||
Добавить
|
||||
</button>
|
||||
@ -243,12 +294,12 @@ export const TrackerModal = ({
|
||||
<div className="input-container">
|
||||
<input
|
||||
className="name-project"
|
||||
value={editTitleColumn}
|
||||
onChange={(e) => setEditTitleColumn(e.target.value)}
|
||||
value={columnName}
|
||||
onChange={(e) => dispatch(setColumnName(e.target.value))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button className="button-add" onClick={(e) => e.preventDefault()}>
|
||||
<button className="button-add" onClick={changeColumnName}>
|
||||
Сохранить
|
||||
</button>
|
||||
</div>
|
||||
|
@ -61,6 +61,56 @@
|
||||
font-size: 15px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.select__worker {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 5px;
|
||||
background: white;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
||||
p {
|
||||
max-width: 150px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
img {
|
||||
transition: all 0.3s ease;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
&__dropDown {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
top: 35px;
|
||||
left: 0;
|
||||
background: white;
|
||||
border-radius: 5px;
|
||||
row-gap: 5px;
|
||||
|
||||
.worker {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.open {
|
||||
.arrow {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.name-project {
|
||||
|
Reference in New Issue
Block a user