Compare commits
8 Commits
c972df0656
...
2889569238
Author | SHA1 | Date | |
---|---|---|---|
|
2889569238 | ||
|
0b02a71a1a | ||
d9781b6396 | |||
0df30c74c9 | |||
|
59d0f5eae6 | ||
|
57cc2bc1fa | ||
|
ce775e03ab | ||
3a0426ae6d |
@ -5,19 +5,25 @@ import "./modalLayout.scss";
|
|||||||
export const ModalLayout = ({
|
export const ModalLayout = ({
|
||||||
active,
|
active,
|
||||||
setActive,
|
setActive,
|
||||||
|
onClose,
|
||||||
children,
|
children,
|
||||||
styles,
|
styles,
|
||||||
type,
|
type,
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
|
const handleClose = (event) => {
|
||||||
|
if (event.target.className === "modal-layout active") {
|
||||||
|
setActive(false);
|
||||||
|
if (onClose) {
|
||||||
|
onClose(); // Вызов колбэк-функции при закрытии модального окна
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={active ? `modal-layout active` : "modal-layout"}
|
className={active ? `modal-layout active` : "modal-layout"}
|
||||||
onClick={(event) => {
|
onClick={handleClose}
|
||||||
if (event.target.className === "modal-layout active") {
|
|
||||||
setActive(false);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
row-gap: 5px;
|
row-gap: 5px;
|
||||||
&__input {
|
&__input {
|
||||||
margin: 0;
|
margin: 10px 0 10px 0;
|
||||||
min-width: 240px;
|
min-width: 240px;
|
||||||
height: 42px;
|
height: 42px;
|
||||||
|
|
||||||
@ -79,6 +79,9 @@
|
|||||||
max-width: 190px;
|
max-width: 190px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
.email-error-message {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 805px) {
|
@media (max-width: 805px) {
|
||||||
|
@ -6,7 +6,7 @@ import {
|
|||||||
modalToggle
|
modalToggle
|
||||||
} from "@redux/projectsTrackerSlice";
|
} from "@redux/projectsTrackerSlice";
|
||||||
|
|
||||||
import { caseOfNum, urlForLocal } from "@utils/helper";
|
import { caseOfNum, removeLast, urlForLocal } from "@utils/helper";
|
||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ const ListEmployees = ({
|
|||||||
}
|
}
|
||||||
alt="avatar"
|
alt="avatar"
|
||||||
/>
|
/>
|
||||||
<span>{person.user.fio}</span>
|
<span>{removeLast(person.user.fio)}</span>
|
||||||
<img
|
<img
|
||||||
className="delete"
|
className="delete"
|
||||||
src={close}
|
src={close}
|
||||||
|
@ -11,10 +11,10 @@ import { getProfileInfo } from "@redux/outstaffingSlice";
|
|||||||
import { setProjectBoardFetch } from "@redux/projectsTrackerSlice";
|
import { setProjectBoardFetch } from "@redux/projectsTrackerSlice";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
backendImg,
|
|
||||||
caseOfNum,
|
caseOfNum,
|
||||||
getCorrectRequestDate,
|
getCorrectRequestDate,
|
||||||
getToken,
|
getToken,
|
||||||
|
removeLast,
|
||||||
urlForLocal
|
urlForLocal
|
||||||
} from "@utils/helper";
|
} from "@utils/helper";
|
||||||
|
|
||||||
@ -99,6 +99,18 @@ export const ModalTiсket = ({
|
|||||||
const { showNotification } = useNotification();
|
const { showNotification } = useNotification();
|
||||||
const [commentSendDisable, setCommentSendDisable] = useState(false);
|
const [commentSendDisable, setCommentSendDisable] = useState(false);
|
||||||
|
|
||||||
|
const closeModal = () => {
|
||||||
|
setActive(false);
|
||||||
|
// Восстанавливаем скролл при закрытии модального окна
|
||||||
|
document.body.style.overflow = "auto";
|
||||||
|
};
|
||||||
|
|
||||||
|
const [isExpanded, setIsExpanded] = useState(false);
|
||||||
|
|
||||||
|
const toggleModalSize = () => {
|
||||||
|
setIsExpanded((prevState) => !prevState);
|
||||||
|
};
|
||||||
|
|
||||||
function deleteTask() {
|
function deleteTask() {
|
||||||
apiRequest("/task/update-task", {
|
apiRequest("/task/update-task", {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
@ -107,7 +119,7 @@ export const ModalTiсket = ({
|
|||||||
status: 0
|
status: 0
|
||||||
}
|
}
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
setActive(false);
|
closeModal();
|
||||||
dispatch(setProjectBoardFetch(projectId));
|
dispatch(setProjectBoardFetch(projectId));
|
||||||
showNotification({
|
showNotification({
|
||||||
show: true,
|
show: true,
|
||||||
@ -594,20 +606,20 @@ export const ModalTiсket = ({
|
|||||||
<div
|
<div
|
||||||
className={active ? "modal-ticket active" : "modal-ticket"}
|
className={active ? "modal-ticket active" : "modal-ticket"}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
if (e.target.className.includes("modal-ticket")) setActive(false);
|
if (e.target.className.includes("modal-ticket")) closeModal();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="modal-ticket__content">
|
<div className={`modal-ticket__content ${isExpanded ? "expanded" : ""}`}>
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<h3 className="title-project">
|
<h3 className="title-project">
|
||||||
<img src={category} className="title-project__category"></img>
|
<img src={category} className="title-project__category"></img>
|
||||||
{projectName}
|
{projectName}
|
||||||
<Link
|
<img
|
||||||
to={`/tracker/task/${task.id}`}
|
src={fullScreen}
|
||||||
|
alt="Full screen"
|
||||||
|
onClick={toggleModalSize}
|
||||||
className="title-project__full"
|
className="title-project__full"
|
||||||
>
|
/>
|
||||||
<img src={fullScreen}></img>
|
|
||||||
</Link>
|
|
||||||
</h3>
|
</h3>
|
||||||
<div className="content__task">
|
<div className="content__task">
|
||||||
{editOpen ? (
|
{editOpen ? (
|
||||||
@ -757,14 +769,14 @@ export const ModalTiсket = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="workers">
|
<div className="workers">
|
||||||
<div className="workers_box task__info">
|
<div className="workers_box task__info">
|
||||||
<span className="exit" onClick={() => setActive(false)}></span>
|
<span className="exit" onClick={() => closeModal()}></span>
|
||||||
<h5>Создатель: </h5>
|
<h5>Создатель: </h5>
|
||||||
<p className="workers__creator">{task.user?.fio}</p>
|
<p className="workers__creator">{removeLast(task.user?.fio)}</p>
|
||||||
{executor ? (
|
{executor ? (
|
||||||
<>
|
<>
|
||||||
<h5>Исполнитель: </h5>
|
<h5>Исполнитель: </h5>
|
||||||
<div className="executor">
|
<div className="executor">
|
||||||
<p>{executor.fio}</p>
|
<p>{removeLast(executor.fio)}</p>
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
executor?.avatar
|
executor?.avatar
|
||||||
@ -803,7 +815,7 @@ export const ModalTiсket = ({
|
|||||||
key={person.user_id}
|
key={person.user_id}
|
||||||
onClick={() => taskExecutor(person)}
|
onClick={() => taskExecutor(person)}
|
||||||
>
|
>
|
||||||
<span>{person.user.fio}</span>
|
<span>{removeLast(person.user.fio)}</span>
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
person.user?.avatar
|
person.user?.avatar
|
||||||
@ -826,7 +838,7 @@ export const ModalTiсket = ({
|
|||||||
{members.map((member) => {
|
{members.map((member) => {
|
||||||
return (
|
return (
|
||||||
<div className="worker" key={member.user_id}>
|
<div className="worker" key={member.user_id}>
|
||||||
<p>{member.fio}</p>
|
<p>{removeLast(member.fio)}</p>
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
member?.avatar
|
member?.avatar
|
||||||
@ -869,7 +881,7 @@ export const ModalTiсket = ({
|
|||||||
key={person.user_id}
|
key={person.user_id}
|
||||||
onClick={() => addMember(person)}
|
onClick={() => addMember(person)}
|
||||||
>
|
>
|
||||||
<span>{person.user.fio}</span>
|
<span>{removeLast(person.user.fio)}</span>
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
person.user?.avatar
|
person.user?.avatar
|
||||||
@ -895,7 +907,7 @@ export const ModalTiсket = ({
|
|||||||
className="dead-line__container"
|
className="dead-line__container"
|
||||||
onClick={() => setDatePickerOpen(!datePickerOpen)}
|
onClick={() => setDatePickerOpen(!datePickerOpen)}
|
||||||
>
|
>
|
||||||
<img src={calendarIcon} alt="calendar" />
|
<p>⌛</p>
|
||||||
<span>
|
<span>
|
||||||
{deadLine ? getCorrectDate(deadLine) : "Срок исполнения"}
|
{deadLine ? getCorrectDate(deadLine) : "Срок исполнения"}
|
||||||
</span>
|
</span>
|
||||||
|
@ -15,13 +15,20 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-ticket__content.expanded {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
max-height: none;
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
.modal-ticket__content {
|
.modal-ticket__content {
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
max-height: 700px;
|
max-height: 700px;
|
||||||
// overflow-y: auto;
|
max-width: 915px;
|
||||||
|
|
||||||
@media (max-width: 990px) {
|
@media (max-width: 990px) {
|
||||||
width: 96%;
|
width: 96%;
|
||||||
@ -52,7 +59,7 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 630px;
|
width: 68%;
|
||||||
margin: 26px 0 0 21px;
|
margin: 26px 0 0 21px;
|
||||||
|
|
||||||
.title-project {
|
.title-project {
|
||||||
@ -160,7 +167,6 @@
|
|||||||
|
|
||||||
.comments__list {
|
.comments__list {
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow-y: auto;
|
|
||||||
height: 190px;
|
height: 190px;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
@ -364,7 +370,6 @@
|
|||||||
column-gap: 25px;
|
column-gap: 25px;
|
||||||
row-gap: 20px;
|
row-gap: 20px;
|
||||||
margin-top: 33px;
|
margin-top: 33px;
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
.task-file {
|
.task-file {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -607,6 +612,7 @@
|
|||||||
.workers {
|
.workers {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-left: 1px solid #f1f1f1;
|
border-left: 1px solid #f1f1f1;
|
||||||
|
width: 32%;
|
||||||
|
|
||||||
.exit {
|
.exit {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -950,7 +950,7 @@ export const TicketFullScreen = () => {
|
|||||||
className="dead-line__container"
|
className="dead-line__container"
|
||||||
onClick={() => setDatePickerOpen(!datePickerOpen)}
|
onClick={() => setDatePickerOpen(!datePickerOpen)}
|
||||||
>
|
>
|
||||||
<img src={calendarIcon} alt="calendar" />
|
<p>⌛</p>
|
||||||
<span>
|
<span>
|
||||||
{deadLine
|
{deadLine
|
||||||
? getCorrectDate(deadLine)
|
? getCorrectDate(deadLine)
|
||||||
|
@ -23,7 +23,7 @@ import {
|
|||||||
} from "@redux/projectsTrackerSlice";
|
} from "@redux/projectsTrackerSlice";
|
||||||
|
|
||||||
import { getCorrectDate } from "@utils/calendarHelper";
|
import { getCorrectDate } from "@utils/calendarHelper";
|
||||||
import { getCorrectRequestDate, urlForLocal } from "@utils/helper";
|
import { getCorrectRequestDate, removeLast, urlForLocal } from "@utils/helper";
|
||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
@ -72,6 +72,7 @@ export const TrackerModal = ({
|
|||||||
const [selectWorkersOpen, setSelectWorkersOpen] = useState(false);
|
const [selectWorkersOpen, setSelectWorkersOpen] = useState(false);
|
||||||
const [selectedWorker, setSelectedWorker] = useState(null);
|
const [selectedWorker, setSelectedWorker] = useState(null);
|
||||||
const [emailWorker, setEmailWorker] = useState("");
|
const [emailWorker, setEmailWorker] = useState("");
|
||||||
|
const [emailError, setEmailError] = useState("");
|
||||||
const [selectColumnPriority, setSelectColumnPriority] = useState(
|
const [selectColumnPriority, setSelectColumnPriority] = useState(
|
||||||
"Выберите приоритет колонки"
|
"Выберите приоритет колонки"
|
||||||
);
|
);
|
||||||
@ -114,6 +115,19 @@ export const TrackerModal = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const existingColumn = projectBoard.columns.find(
|
||||||
|
(column) => column.title === valueColumn
|
||||||
|
);
|
||||||
|
|
||||||
|
if (existingColumn) {
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Колонка с таким названием уже существует",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
apiRequest("/project-column/create-column", {
|
apiRequest("/project-column/create-column", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -325,19 +339,6 @@ export const TrackerModal = ({
|
|||||||
setActive(false);
|
setActive(false);
|
||||||
setSelectedWorker("");
|
setSelectedWorker("");
|
||||||
setSelectWorkersOpen(false);
|
setSelectWorkersOpen(false);
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function inviteUserByEmail() {
|
|
||||||
apiRequest("/project/add-user-by-email", {
|
|
||||||
method: "POST",
|
|
||||||
data: {
|
|
||||||
email: emailWorker,
|
|
||||||
project_id: projectBoard.id
|
|
||||||
}
|
|
||||||
}).then((el) => {
|
|
||||||
setActive(false);
|
|
||||||
setEmailWorker("");
|
|
||||||
showNotification({
|
showNotification({
|
||||||
show: true,
|
show: true,
|
||||||
text: "Приглашение отправлено",
|
text: "Приглашение отправлено",
|
||||||
@ -346,6 +347,35 @@ export const TrackerModal = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const validateEmail = (email) => {
|
||||||
|
// Простая валидация адреса электронной почты
|
||||||
|
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||||
|
return emailPattern.test(email);
|
||||||
|
};
|
||||||
|
|
||||||
|
const inviteUserByEmail = () => {
|
||||||
|
if (validateEmail(emailWorker)) {
|
||||||
|
setEmailError("");
|
||||||
|
apiRequest("/project/add-user-by-email", {
|
||||||
|
method: "POST",
|
||||||
|
data: {
|
||||||
|
email: emailWorker,
|
||||||
|
project_id: projectBoard.id
|
||||||
|
}
|
||||||
|
}).then((el) => {
|
||||||
|
setActive(false);
|
||||||
|
setEmailWorker("");
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Приглашение отправлено",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setEmailError("Некорректный e-mail адрес");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
modalType === "add-worker"
|
modalType === "add-worker"
|
||||||
? apiRequest("/project/my-employee").then((el) => {
|
? apiRequest("/project/my-employee").then((el) => {
|
||||||
@ -426,8 +456,18 @@ export const TrackerModal = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleModalClose = () => {
|
||||||
|
setEmailError("");
|
||||||
|
setEmailWorker("");
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalLayout active={active} setActive={setActive} type={modalType}>
|
<ModalLayout
|
||||||
|
active={active}
|
||||||
|
setActive={setActive}
|
||||||
|
onClose={handleModalClose}
|
||||||
|
type={modalType}
|
||||||
|
>
|
||||||
{modalType === "add-worker" && (
|
{modalType === "add-worker" && (
|
||||||
<>
|
<>
|
||||||
<div className="select__person">
|
<div className="select__person">
|
||||||
@ -448,7 +488,7 @@ export const TrackerModal = ({
|
|||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
{selectedWorker
|
{selectedWorker
|
||||||
? selectedWorker.employee.fio
|
? removeLast(selectedWorker.employee.fio)
|
||||||
: "Выберите пользователя"}
|
: "Выберите пользователя"}
|
||||||
</p>
|
</p>
|
||||||
<img className="arrow" src={arrowDown} alt="arrow" />
|
<img className="arrow" src={arrowDown} alt="arrow" />
|
||||||
@ -467,7 +507,7 @@ export const TrackerModal = ({
|
|||||||
setSelectedWorker(worker);
|
setSelectedWorker(worker);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>{worker.employee.fio}</span>
|
<span>{removeLast(worker.employee.fio)}</span>
|
||||||
<img
|
<img
|
||||||
src={urlForLocal(worker.employee.avatar)}
|
src={urlForLocal(worker.employee.avatar)}
|
||||||
alt="avatar"
|
alt="avatar"
|
||||||
@ -498,6 +538,7 @@ export const TrackerModal = ({
|
|||||||
value={emailWorker}
|
value={emailWorker}
|
||||||
onChange={(e) => setEmailWorker(e.target.value)}
|
onChange={(e) => setEmailWorker(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
<div className="email-error-message">{emailError}</div>
|
||||||
</div>
|
</div>
|
||||||
<BaseButton
|
<BaseButton
|
||||||
styles={"button-add add-person-btn"}
|
styles={"button-add add-person-btn"}
|
||||||
@ -521,7 +562,6 @@ export const TrackerModal = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="create-task-body">
|
<div className="create-task-body">
|
||||||
<div className="create-task-body__left">
|
<div className="create-task-body__left">
|
||||||
<h4>Введите название и описание задачи</h4>
|
|
||||||
<div className="input-container">
|
<div className="input-container">
|
||||||
<input
|
<input
|
||||||
maxLength="100"
|
maxLength="100"
|
||||||
@ -699,7 +739,7 @@ export const TrackerModal = ({
|
|||||||
}
|
}
|
||||||
alt="avatar"
|
alt="avatar"
|
||||||
/>
|
/>
|
||||||
<span>{person.user.fio}</span>
|
<span>{removeLast(person.user.fio)}</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
@ -710,7 +750,7 @@ export const TrackerModal = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="create-task-body__right__dead-line">
|
<div className="create-task-body__right__dead-line">
|
||||||
<img src={calendarImg} alt="calendar" />
|
<p>⌛</p>
|
||||||
<p onClick={() => setDatePickerOpen(!datePickerOpen)}>
|
<p onClick={() => setDatePickerOpen(!datePickerOpen)}>
|
||||||
{deadLineDate
|
{deadLineDate
|
||||||
? getCorrectDate(deadLineDate)
|
? getCorrectDate(deadLineDate)
|
||||||
@ -734,7 +774,7 @@ export const TrackerModal = ({
|
|||||||
<Loader style={"green"} />
|
<Loader style={"green"} />
|
||||||
) : (
|
) : (
|
||||||
<BaseButton styles={"button-add"} onClick={createTicket}>
|
<BaseButton styles={"button-add"} onClick={createTicket}>
|
||||||
Создать
|
Создать задачу
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -864,7 +904,14 @@ export const TrackerModal = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<span className="exit" onClick={() => setActive(false)}></span>
|
<span
|
||||||
|
className="exit"
|
||||||
|
onClick={() => {
|
||||||
|
setActive(false);
|
||||||
|
setEmailError("");
|
||||||
|
setEmailWorker("");
|
||||||
|
}}
|
||||||
|
></span>
|
||||||
</ModalLayout>
|
</ModalLayout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -227,6 +227,7 @@
|
|||||||
min-width: 240px;
|
min-width: 240px;
|
||||||
height: 42px;
|
height: 42px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
margin: 10px 0 10px 0;
|
||||||
|
|
||||||
p {
|
p {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -262,7 +263,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 9.5px 12px;
|
padding: 9.5px 12px;
|
||||||
top: 48px;
|
top: 45px;
|
||||||
left: 0;
|
left: 0;
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
@ -337,7 +338,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.create-task-body {
|
.create-task-body {
|
||||||
padding: 15px 20px;
|
padding: 15px 30px;
|
||||||
display: flex;
|
display: flex;
|
||||||
column-gap: 20px;
|
column-gap: 20px;
|
||||||
|
|
||||||
@ -373,8 +374,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ck-editor__editable.ck-rounded-corners {
|
.ck-editor__editable.ck-rounded-corners {
|
||||||
min-height: 150px;
|
min-height: 180px;
|
||||||
max-height: 150px;
|
max-height: 180px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,6 +384,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
justify-content: end;
|
justify-content: end;
|
||||||
|
row-gap: 10px;
|
||||||
|
|
||||||
&__owner {
|
&__owner {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -714,6 +716,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button-add {
|
||||||
|
margin: 0 30px;
|
||||||
|
align-self: flex-end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.name-project {
|
.name-project {
|
||||||
|
@ -97,7 +97,7 @@ export const Navigation = () => {
|
|||||||
|
|
||||||
<div className="profile-header__personal-info">
|
<div className="profile-header__personal-info">
|
||||||
<h3 className="profile-header__personal-info-name">
|
<h3 className="profile-header__personal-info-name">
|
||||||
{profileInfo?.fio ? profileInfo?.fio : profileInfo?.username}
|
{profileInfo?.fio || profileInfo?.username}
|
||||||
</h3>
|
</h3>
|
||||||
<NavLink end to={"/profile"}>
|
<NavLink end to={"/profile"}>
|
||||||
<img
|
<img
|
||||||
|
@ -95,7 +95,7 @@ export const ProfileCalendar = () => {
|
|||||||
alt="avatar"
|
alt="avatar"
|
||||||
/>
|
/>
|
||||||
<p className="summary__name">
|
<p className="summary__name">
|
||||||
{profileInfo?.fio ? profileInfo?.fio : profileInfo?.username},{" "}
|
{profileInfo?.fio || profileInfo?.username},{" "}
|
||||||
{profileInfo.specification} разработчик
|
{profileInfo.specification} разработчик
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -110,6 +110,10 @@ export const ProfileHeader = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const closeMenu = () => {
|
||||||
|
setActive(false);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="profile-header">
|
<header className="profile-header">
|
||||||
<div className="auth-title">
|
<div className="auth-title">
|
||||||
@ -146,7 +150,7 @@ export const ProfileHeader = () => {
|
|||||||
<nav className="auth-body__navigation">
|
<nav className="auth-body__navigation">
|
||||||
<div className="profile-header__personal-info">
|
<div className="profile-header__personal-info">
|
||||||
<h3 className="profile-header__personal-info-name">
|
<h3 className="profile-header__personal-info-name">
|
||||||
{profileInfo?.fio ? profileInfo?.fio : profileInfo?.username}
|
{profileInfo?.fio || profileInfo?.username}
|
||||||
</h3>
|
</h3>
|
||||||
<NavLink end to={"/profile"}>
|
<NavLink end to={"/profile"}>
|
||||||
<img
|
<img
|
||||||
@ -179,6 +183,7 @@ export const ProfileHeader = () => {
|
|||||||
</button>
|
</button>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
{active && <div className="backdrop" onClick={closeMenu}></div>}
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
z-index: 9;
|
|
||||||
max-width: 1160px;
|
max-width: 1160px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
@ -36,6 +35,7 @@
|
|||||||
|
|
||||||
@media (max-width: 414px) {
|
@media (max-width: 414px) {
|
||||||
display: block;
|
display: block;
|
||||||
|
z-index: 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__line {
|
&__line {
|
||||||
@ -64,9 +64,19 @@
|
|||||||
background: white;
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.backdrop {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 7;
|
||||||
|
}
|
||||||
|
|
||||||
.auth-body {
|
.auth-body {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
z-index: 99;
|
z-index: 8;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
@ -99,7 +109,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
padding: 10px 0 0 0;
|
padding: 15px 0 0 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
a,
|
a,
|
||||||
@ -134,7 +144,7 @@
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
width: calc(100vw / 3);
|
width: calc(100vw / 2.5);
|
||||||
transition: width 0.3s;
|
transition: width 0.3s;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -188,6 +198,7 @@
|
|||||||
&__logout-burger {
|
&__logout-burger {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
|
padding: 15px 0 0 0;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
|
@ -103,12 +103,12 @@ export const Profile = () => {
|
|||||||
{user === "developer" ? (
|
{user === "developer" ? (
|
||||||
<span>
|
<span>
|
||||||
<p>Добрый день, </p>
|
<p>Добрый день, </p>
|
||||||
{profileInfo?.fio ? profileInfo?.fio : profileInfo?.username}
|
{profileInfo?.fio || profileInfo?.username}
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<span>
|
<span>
|
||||||
<p>Добрый день, </p>
|
<p>Добрый день, </p>
|
||||||
{profileInfo?.fio ? profileInfo?.fio : profileInfo?.username}
|
{profileInfo?.fio || profileInfo?.username}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</h2>
|
</h2>
|
||||||
@ -124,13 +124,11 @@ export const Profile = () => {
|
|||||||
<p className="summary__name">
|
<p className="summary__name">
|
||||||
{user === "developer" ? (
|
{user === "developer" ? (
|
||||||
<span>
|
<span>
|
||||||
{profileInfo?.fio ? profileInfo?.fio : profileInfo?.username},{" "}
|
{profileInfo?.fio || profileInfo?.username},{" "}
|
||||||
{profileInfo?.specification} разработчик
|
{profileInfo?.specification} разработчик
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<span>
|
<span>{profileInfo?.fio || profileInfo?.username}</span>
|
||||||
{profileInfo?.fio ? profileInfo?.fio : profileInfo?.username}
|
|
||||||
</span>
|
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -23,8 +23,7 @@ import {
|
|||||||
setToggleTab
|
setToggleTab
|
||||||
} from "@redux/projectsTrackerSlice";
|
} from "@redux/projectsTrackerSlice";
|
||||||
|
|
||||||
import { urlForLocal } from "@utils/helper";
|
import { removeLast, urlForLocal } from "@utils/helper";
|
||||||
import { caseOfNum } from "@utils/helper";
|
|
||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
@ -44,7 +43,6 @@ import TrackerSelectColumn from "@components/TrackerSelectColumn/TrackerSelectCo
|
|||||||
|
|
||||||
import arrow from "assets/icons/arrows/arrowCalendar.png";
|
import arrow from "assets/icons/arrows/arrowCalendar.png";
|
||||||
import arrowDown from "assets/icons/arrows/selectArrow.png";
|
import arrowDown from "assets/icons/arrows/selectArrow.png";
|
||||||
import calendarIcon from "assets/icons/calendar.svg";
|
|
||||||
import category from "assets/icons/category.svg";
|
import category from "assets/icons/category.svg";
|
||||||
import close from "assets/icons/close.png";
|
import close from "assets/icons/close.png";
|
||||||
import commentsBoard from "assets/icons/commentsBoard.svg";
|
import commentsBoard from "assets/icons/commentsBoard.svg";
|
||||||
@ -64,7 +62,6 @@ export const ProjectTracker = () => {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const projectId = useParams();
|
const projectId = useParams();
|
||||||
|
|
||||||
const currentDate = new Date().getFullYear();
|
|
||||||
const [openColumnSelect, setOpenColumnSelect] = useState({});
|
const [openColumnSelect, setOpenColumnSelect] = useState({});
|
||||||
const [selectedTab, setSelectedTab] = useState(0);
|
const [selectedTab, setSelectedTab] = useState(0);
|
||||||
const [priorityTask, setPriorityTask] = useState(0);
|
const [priorityTask, setPriorityTask] = useState(0);
|
||||||
@ -224,11 +221,9 @@ export const ProjectTracker = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function openTicket(e, task) {
|
function openTicket(e, task) {
|
||||||
if (window.innerWidth < 985) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setSelectedTicket(task);
|
setSelectedTicket(task);
|
||||||
setModalActiveTicket(true);
|
setModalActiveTicket(true);
|
||||||
|
document.body.style.overflow = "hidden";
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteColumn(column) {
|
function deleteColumn(column) {
|
||||||
@ -612,7 +607,7 @@ export const ProjectTracker = () => {
|
|||||||
key={user.user_id}
|
key={user.user_id}
|
||||||
onClick={() => executorFilter(user)}
|
onClick={() => executorFilter(user)}
|
||||||
>
|
>
|
||||||
<p>{user.user?.fio}</p>
|
<p>{removeLast(user.user?.fio)}</p>
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
user.user?.avatar
|
user.user?.avatar
|
||||||
@ -910,10 +905,7 @@ export const ProjectTracker = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<p
|
<p className="task__board__item__title">
|
||||||
className="task__board__item__title"
|
|
||||||
style={{ color: titleColor }}
|
|
||||||
>
|
|
||||||
{task.title}
|
{task.title}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -955,7 +947,7 @@ export const ProjectTracker = () => {
|
|||||||
{task.dead_line && (
|
{task.dead_line && (
|
||||||
<div className="tasks__board__item__dead-line">
|
<div className="tasks__board__item__dead-line">
|
||||||
<p>⌛</p>
|
<p>⌛</p>
|
||||||
<span>
|
<span style={{ color: titleColor }}>
|
||||||
{getCorrectDate(task.dead_line)}
|
{getCorrectDate(task.dead_line)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -973,7 +965,7 @@ export const ProjectTracker = () => {
|
|||||||
alt="avatar"
|
alt="avatar"
|
||||||
/>
|
/>
|
||||||
<span>
|
<span>
|
||||||
{task.executor?.fio ||
|
{removeLast(task.executor?.fio) ||
|
||||||
"Исполнитель не назначен"}
|
"Исполнитель не назначен"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,8 +40,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 483px) {
|
@media (max-width: 483px) {
|
||||||
max-width: 160px;
|
display: none;
|
||||||
left: -175px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,6 +61,20 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: -100px;
|
top: -100px;
|
||||||
right: 58px;
|
right: 58px;
|
||||||
|
|
||||||
|
@media (max-width: 1100px) {
|
||||||
|
max-width: 100px;
|
||||||
|
top: -50px;
|
||||||
|
right: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 800px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1100px) {
|
||||||
|
padding: 20px 25px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,12 +86,23 @@
|
|||||||
&__head {
|
&__head {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-bottom: 33px;
|
margin-bottom: 33px;
|
||||||
|
|
||||||
|
@media (max-width: 650px) {
|
||||||
|
flex-direction: column;
|
||||||
|
row-gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__suptitle {
|
&__suptitle {
|
||||||
color: #6f6f6f;
|
color: #6f6f6f;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin-right: 70px;
|
margin-right: 70px;
|
||||||
|
|
||||||
|
@media (max-width: 650px) {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__steps {
|
&__steps {
|
||||||
@ -102,12 +126,17 @@
|
|||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
|
|
||||||
|
@media (max-width: 650px) {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__answers {
|
&__answers {
|
||||||
margin-top: 45px;
|
margin-top: 45px;
|
||||||
display: flex;
|
display: flex;
|
||||||
column-gap: 20px;
|
flex-wrap: wrap;
|
||||||
|
gap: 20px;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
@ -120,8 +149,16 @@
|
|||||||
.active {
|
.active {
|
||||||
background: #1458dd;
|
background: #1458dd;
|
||||||
color: whitesmoke;
|
color: whitesmoke;
|
||||||
font-weight: 500;
|
border: 1px solid #1458dd;
|
||||||
border: none;
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1100px) {
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 450px) {
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,6 +189,7 @@
|
|||||||
row-gap: 19px;
|
row-gap: 19px;
|
||||||
column-gap: 21px;
|
column-gap: 21px;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__item {
|
&__item {
|
||||||
|
@ -107,7 +107,7 @@ export const Summary = () => {
|
|||||||
alt="avatar"
|
alt="avatar"
|
||||||
/>
|
/>
|
||||||
<p className="summary__name">
|
<p className="summary__name">
|
||||||
{profileInfo?.fio ? profileInfo?.fio : profileInfo?.username},{" "}
|
{profileInfo?.fio || profileInfo?.username},{" "}
|
||||||
{profileInfo.specification} разработчик
|
{profileInfo.specification} разработчик
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -91,3 +91,11 @@ export function copyProjectLink(projectId) {
|
|||||||
`https://itguild.info/tracker/project/${projectId}`
|
`https://itguild.info/tracker/project/${projectId}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function removeLast(string = " ") {
|
||||||
|
let arr = string.trim().split(" ");
|
||||||
|
if (arr.length > 2) {
|
||||||
|
return arr.slice(0, -1).join(" ");
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user