diff --git a/src/components/Modal/Tracker/ModalTicket/ModalTicket.jsx b/src/components/Modal/Tracker/ModalTicket/ModalTicket.jsx
index 1a6d3406..210445e3 100644
--- a/src/components/Modal/Tracker/ModalTicket/ModalTicket.jsx
+++ b/src/components/Modal/Tracker/ModalTicket/ModalTicket.jsx
@@ -11,6 +11,7 @@ import { getProfileInfo } from "@redux/outstaffingSlice";
import { setProjectBoardFetch } from "@redux/projectsTrackerSlice";
import {
+ backendImg,
caseOfNum,
getCorrectRequestDate,
getToken,
@@ -68,15 +69,16 @@ export const ModalTiсket = ({
const [executor, setExecutor] = useState(task.executor);
const [members, setMembers] = useState(task.taskUsers);
const [users, setUsers] = useState([]);
- const [selectedFile, setSelectedFile] = useState("");
const [timerStart, setTimerStart] = useState(false);
const [timerInfo, setTimerInfo] = useState({});
+ const [uploadedFile, setUploadedFile] = useState(null);
const [currentTimerCount, setCurrentTimerCount] = useState({
hours: 0,
minute: 0,
seconds: 0,
});
const [timerId, setTimerId] = useState(null);
+ const [taskFiles, setTaskFiles] = useState([]);
const [correctProjectUsers, setCorrectProjectUsers] = useState(projectUsers);
const [executorId, setExecutorId] = useState(task.executor_id);
const profileInfo = useSelector(getProfileInfo);
@@ -287,6 +289,14 @@ export const ModalTiсket = ({
}
);
+ apiRequest(`/file/get-by-entity?entity_type=2&entity_id=${task.id}`).then(
+ (res) => {
+ if (Array.isArray(res)) {
+ setTaskFiles(res);
+ }
+ }
+ );
+
if (
localStorage.getItem("role_status") !== "18" &&
Boolean(
@@ -308,31 +318,53 @@ export const ModalTiсket = ({
}
}, []);
- function handleChange(event) {
- setSelectedFile(event.target.files[0]);
- }
-
- async function handleUpload() {
+ async function handleUpload(event) {
const formData = new FormData();
- formData.append("uploadFile", selectedFile);
- const headers = {
- "Access-Control-Allow-Origin": "*",
- "Content-Type": "application/json",
- };
- const fullHeaders = { ...headers, ...getToken() };
+ formData.append("uploadFile", event.target.files[0]);
const res = await fetch("https://itguild.info/api/file/upload", {
method: "POST",
body: formData,
- headers: { ...fullHeaders },
+ headers: { ...getToken() },
});
- console.log(fullHeaders);
- console.log(res);
- // apiRequest('/file/upload', {
- // method: 'POST',
- // body: formData
- // }).then((res) => {
- // })
+ const data = await res.json();
+
+ setUploadedFile(data);
+ }
+
+ function deleteLoadedFile() {
+ setUploadedFile(null);
+ }
+
+ function attachFile() {
+ apiRequest("/file/attach", {
+ method: "POST",
+ data: {
+ file_id: uploadedFile[0].id,
+ entity_type: 2,
+ entity_id: task.id,
+ status: 1,
+ },
+ }).then((res) => {
+ setTaskFiles((prevValue) => [...prevValue, res]);
+ setUploadedFile(null);
+ });
+ }
+
+ function deleteFile(file) {
+ apiRequest("/file/detach", {
+ method: "DELETE",
+ data: {
+ file_id: file.id,
+ entity_type: 2,
+ entity_id: task.id,
+ status: 0,
+ },
+ }).then(() => {
+ setTaskFiles((prevValue) =>
+ prevValue.filter((item) => item.id !== file.id)
+ );
+ });
}
function startTimer() {
@@ -468,6 +500,45 @@ export const ModalTiсket = ({
)}
{/**/}
+ {Boolean(taskFiles.length) && (
+
+ {taskFiles.map((file) => {
+ return (
+
+
+
deleteFile(file)}
+ >
+
+
+
+ );
+ })}
+
+ )}
+ {uploadedFile && (
+
+ {uploadedFile.map((file) => {
+ return (
+
+
+
deleteLoadedFile(file)}
+ >
+
+
+
+ );
+ })}
+
+
+ )}
{/*
*/}
{/*
- Отправить
- {0}
- {caseOfNum(0, "files")}
+ {taskFiles.length ? taskFiles.length : 0}
+ {caseOfNum(taskFiles.length, "files")}
diff --git a/src/components/Modal/Tracker/ModalTicket/modalTicket.scss b/src/components/Modal/Tracker/ModalTicket/modalTicket.scss
index 7686f9a3..0dd29d67 100644
--- a/src/components/Modal/Tracker/ModalTicket/modalTicket.scss
+++ b/src/components/Modal/Tracker/ModalTicket/modalTicket.scss
@@ -315,6 +315,100 @@
}
}
+ .task__files {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ margin-top: 10px;
+
+ .taskFile {
+ position: relative;
+ .imgFile {
+ max-width: 180px;
+ object-fit: contain;
+ }
+
+ &:hover {
+ .deleteFile {
+ background: rgb(226, 226, 226, 0.6);
+ }
+ }
+
+ .deleteFile {
+ position: absolute;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 10;
+ width: 20px;
+ height: 20px;
+ top: 0;
+ right: 0;
+ transition: all 0.3s ease;
+ background: rgb(226, 226, 226, 0.1);
+
+ img {
+ width: 12px;
+ height: 12px;
+ }
+ }
+ }
+ }
+
+ .fileLoaded {
+ display: flex;
+ align-items: center;
+ margin: 10px 0 0;
+
+ .loadedFile {
+ position: relative;
+ img {
+ max-width: 100px;
+ object-fit: contain;
+ }
+ .deleteFile {
+ position: absolute;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 10;
+ width: 20px;
+ height: 20px;
+ top: 0;
+ right: 0;
+ transition: all 0.3s ease;
+ background: rgb(226, 226, 226, 0.1);
+
+ img {
+ width: 12px;
+ height: 12px;
+ }
+ }
+ &:hover {
+ .deleteFile {
+ background: rgb(226, 226, 226, 0.6);
+ }
+ }
+ }
+
+ button {
+ display: flex;
+ justify-content: center;
+ color: blue;
+ margin-left: 10px;
+ border: 0.5px solid #1458dd;
+ border-radius: 44px;
+ font-weight: 400;
+ font-size: 12px;
+ line-height: 32px;
+ max-width: 120px;
+ background: none;
+ width: 100%;
+ }
+ }
+
&__communication {
display: flex;
flex-direction: row;
diff --git a/src/components/Modal/Tracker/TicketFullScreen/TicketFullScreen.jsx b/src/components/Modal/Tracker/TicketFullScreen/TicketFullScreen.jsx
index 38e0af38..65631554 100644
--- a/src/components/Modal/Tracker/TicketFullScreen/TicketFullScreen.jsx
+++ b/src/components/Modal/Tracker/TicketFullScreen/TicketFullScreen.jsx
@@ -10,16 +10,20 @@ import {
deletePersonOnProject,
getBoarderLoader,
modalToggle,
- setProjectBoardFetch,
setToggleTab,
} from "@redux/projectsTrackerSlice";
-import { caseOfNum, getCorrectRequestDate, urlForLocal } from "@utils/helper";
+import {
+ backendImg,
+ caseOfNum,
+ getCorrectRequestDate,
+ getToken,
+ urlForLocal,
+} from "@utils/helper";
import { apiRequest } from "@api/request";
import { getCorrectDate } from "@components/Calendar/calendarHelper";
-import BaseButton from "@components/Common/BaseButton/BaseButton";
import { Footer } from "@components/Common/Footer/Footer";
import { Loader } from "@components/Common/Loader/Loader";
import TrackerModal from "@components/Modal/Tracker/TrackerModal/TrackerModal";
@@ -32,6 +36,7 @@ import arrow from "assets/icons/arrows/arrowCalendar.png";
import arrowStart from "assets/icons/arrows/arrowStart.png";
import calendarIcon from "assets/icons/calendar.svg";
import close from "assets/icons/close.png";
+import fileDelete from "assets/icons/closeProjectPersons.svg";
import del from "assets/icons/delete.svg";
import edit from "assets/icons/edit.svg";
import file from "assets/icons/fileModal.svg";
@@ -75,6 +80,8 @@ export const TicketFullScreen = () => {
const [deadLine, setDeadLine] = useState("");
const [datePickerOpen, setDatePickerOpen] = useState(false);
const [startDate, setStartDate] = useState(null);
+ const [uploadedFile, setUploadedFile] = useState(null);
+ const [taskFiles, setTaskFiles] = useState([]);
useEffect(() => {
apiRequest(`/task/get-task?task_id=${ticketId.id}`).then((taskInfo) => {
@@ -103,6 +110,13 @@ export const TicketFullScreen = () => {
}, []);
setComments(comments);
});
+ apiRequest(
+ `/file/get-by-entity?entity_type=2&entity_id=${taskInfo.id}`
+ ).then((res) => {
+ if (Array.isArray(res)) {
+ setTaskFiles(res);
+ }
+ });
apiRequest(
`/timer/get-by-entity?entity_type=2&entity_id=${taskInfo.id}`
).then((res) => {
@@ -387,6 +401,55 @@ export const TicketFullScreen = () => {
}).then(() => {});
}
+ async function handleUpload(event) {
+ const formData = new FormData();
+ formData.append("uploadFile", event.target.files[0]);
+ const res = await fetch("https://itguild.info/api/file/upload", {
+ method: "POST",
+ body: formData,
+ headers: { ...getToken() },
+ });
+
+ const data = await res.json();
+
+ setUploadedFile(data);
+ }
+
+ function attachFile() {
+ apiRequest("/file/attach", {
+ method: "POST",
+ data: {
+ file_id: uploadedFile[0].id,
+ entity_type: 2,
+ entity_id: taskInfo.id,
+ status: 1,
+ },
+ }).then((res) => {
+ setTaskFiles((prevValue) => [...prevValue, res]);
+ setUploadedFile(null);
+ });
+ }
+
+ function deleteLoadedFile() {
+ setUploadedFile(null);
+ }
+
+ function deleteFile(file) {
+ apiRequest("/file/detach", {
+ method: "DELETE",
+ data: {
+ file_id: file.id,
+ entity_type: 2,
+ entity_id: taskInfo.id,
+ status: 0,
+ },
+ }).then(() => {
+ setTaskFiles((prevValue) =>
+ prevValue.filter((item) => item.id !== file.id)
+ );
+ });
+ }
+
return (
@@ -590,6 +653,49 @@ export const TicketFullScreen = () => {
/>
)}
+ {Boolean(taskFiles.length) && (
+
+ {taskFiles.map((file) => {
+ return (
+
+
+
deleteFile(file)}
+ >
+
+
+
+ );
+ })}
+
+ )}
+ {uploadedFile && (
+
+ {uploadedFile.map((file) => {
+ return (
+
+
+
deleteLoadedFile(file)}
+ >
+
+
+
+ );
+ })}
+
+
+ )}
{/*
*/}
{/* {
{/* Добавить под задачу*/}
{/* */}
{/*
*/}
-
-
-
- Загрузить файл
-
- {0}
- {caseOfNum(0, "files")}
-
+
+
+
+
+
+
{taskFiles.length ? taskFiles.length : 0}
+ {caseOfNum(taskFiles.length, "files")}
+
export const urlForLocal = (url) =>
process.env.NODE_ENV === "development" ? `https://itguild.info${url}` : url;
+export const backendImg = (url) =>
+ process.env.NODE_ENV === "development"
+ ? `https://back.itguild.info${url}`
+ : url;
+
export function scrollToForm() {
window.scrollTo({
top: 850,