diff --git a/src/components/ProjectTiket/ProjectTiket.js b/src/components/ProjectTiket/ProjectTiket.js index 33e9ed7b..9d11c406 100644 --- a/src/components/ProjectTiket/ProjectTiket.js +++ b/src/components/ProjectTiket/ProjectTiket.js @@ -6,10 +6,15 @@ import archiveSet from "../../images/archive.svg"; import del from "../../images/delete.svg"; import edit from "../../images/edit.svg"; +// import {apiRequest} from "../../api/request"; +import {useDispatch} from "react-redux"; +import { setProjectBoardFetch } from "../../redux/projectsTrackerSlice"; + import "./projectTiket.scss"; export const ProjectTiket = ({ project, index, setOpenProject }) => { const [modalSettings, setModalSettings] = useState(false); + const dispatch = useDispatch(); useEffect(() => { initListeners(); @@ -32,11 +37,14 @@ export const ProjectTiket = ({ project, index, setOpenProject }) => { return (
-

setOpenProject(true)}>{project.name}

+

{ + setOpenProject(true) + dispatch(setProjectBoardFetch(project.id)) + }}>{project.name}

Открытые задачи

- {project.count} - + + - + {/*{project.columns.length ? '+' : ''}*/} setModalSettings(true)}> ... diff --git a/src/components/UI/ModalAdd/modalAdd.scss b/src/components/UI/ModalAdd/modalAdd.scss index 71fc24db..8f60c092 100644 --- a/src/components/UI/ModalAdd/modalAdd.scss +++ b/src/components/UI/ModalAdd/modalAdd.scss @@ -20,7 +20,7 @@ padding: 60px 60px 30px 60px; display: flex; flex-direction: column; - align-items: flex-start; + align-items: center; justify-content: center; } @@ -34,14 +34,14 @@ height: 35px; background: #ffffff; border-radius: 8px; + margin-top: 12px; } h4 { font-weight: 500; - font-size: 22px; + font-size: 17px; line-height: 26px; color: #263238 !important; - margin-bottom: 22px !important; } &__decs { @@ -73,7 +73,7 @@ } .button-add { - margin: 20px 40% 0 0; + margin: 20px; width: 130px; height: 37px; background: #52b709; diff --git a/src/components/UI/ModalCreate/ModalCreate.js b/src/components/UI/ModalCreate/ModalCreate.js index 47ac2d03..8813a132 100644 --- a/src/components/UI/ModalCreate/ModalCreate.js +++ b/src/components/UI/ModalCreate/ModalCreate.js @@ -13,21 +13,15 @@ export const ModalCreate = ({ active, setActive, title }) => { if (inputValue === "") { return; } else { - let newItem = { - name: inputValue, - count: 0, - }; apiRequest('/project/create', { method: 'POST', data: { user_id: localStorage.getItem('id'), name: inputValue, status: 1, - // description: '', - // company_id: 3 } }).then((res) => { - dispatch(setProject(newItem)); + dispatch(setProject(res)); setActive(false); setInputValue(""); }) diff --git a/src/pages/Tracker/Tracker.js b/src/pages/Tracker/Tracker.js index fac2d70d..08bbb2c7 100644 --- a/src/pages/Tracker/Tracker.js +++ b/src/pages/Tracker/Tracker.js @@ -1,11 +1,11 @@ -import React, { useEffect, useState } from "react"; +import React, {useEffect, useRef, useState} from "react"; import { ProfileHeader } from "../../components/ProfileHeader/ProfileHeader"; import { ProfileBreadcrumbs } from "../../components/ProfileBreadcrumbs/ProfileBreadcrumbs"; import { Footer } from "../../components/Footer/Footer"; import { useDispatch, useSelector } from "react-redux"; -import { getProjects } from "../../redux/projectsTrackerSlice"; +import { setAllProjects, getProjects, getProjectBoard, moveProjectTask, setProjectBoardFetch } from "../../redux/projectsTrackerSlice"; import ModalTicket from "../../components/UI/ModalTicket/ModalTicket"; import ModalCreate from "../../components/UI/ModalCreate/ModalCreate"; @@ -26,10 +26,10 @@ import arrow from "../../images/arrowCalendar.png"; import {apiRequest} from "../../api/request"; import { Navigation } from "../../components/Navigation/Navigation"; - import "./tracker.scss"; export const Tracker = () => { + const dispatch = useDispatch(); const [toggleTab, setToggleTab] = useState(1); const [tabTaskMok, setTabTaskMok] = useState([ { @@ -369,18 +369,16 @@ export const Tracker = () => { const [modalCreateColl, setModalCreateColl] = useState(false); const [modalCreateTiket, setModalCreateTiket] = useState(false); const [valueTiket, setValueTiket] = useState(""); + const [descriptionTicket, setDescriptionTicket] = useState("") const [valueColl, setValueColl] = useState(""); // const [projectTasksOpen, setProjectTasksOpen] = useState(false); - const [selectedTab, setSelectedTab] = useState({ - name: "", - indexTab: 0, - task: [], - }); + const [selectedTab, setSelectedTab] = useState(0); const [startWrapperIndex, setStartWrapperIndex] = useState(null); + const startWrapperIndexTest = useRef({}) const [wrapperHover, setWrapperHover] = useState([ false, false, @@ -390,11 +388,12 @@ export const Tracker = () => { useEffect(() => { apiRequest(`/project/project-list?user_id=${localStorage.getItem('id')}&expand=columns`).then((el) => { - + dispatch(setAllProjects(el.projects)) }) }, []) const projects = useSelector(getProjects); + const projectBoard = useSelector(getProjectBoard); const toggleTabs = (index) => { if (projectTasksOpen) { @@ -403,10 +402,10 @@ export const Tracker = () => { setToggleTab(index); }; - function toggleMoreTasks(wrapperIndex) { + function toggleMoreTasks(columnId) { setTabTaskMok((prevArray) => prevArray.map((elem, index) => { - if (wrapperIndex === index) { + if (columnId === index) { return { ...elem, open: !elem.open }; } else { return elem; @@ -415,8 +414,9 @@ export const Tracker = () => { ); } - function dragStartHandler(e, task, wrapperIndex) { - setStartWrapperIndex({ task: task, index: wrapperIndex }); + function dragStartHandler(e, task, columnId) { + // setStartWrapperIndex({ task: task, index: columnId }); + startWrapperIndexTest.current = { task: task, index: columnId }; setTimeout(() => { e.target.classList.add("tasks__board__item__hide"); }, 0); @@ -435,13 +435,13 @@ export const Tracker = () => { e.preventDefault(); } - function dragEnterHandler(wrapperIndex) { - if (wrapperIndex === startWrapperIndex.index) { + function dragEnterHandler(columnId) { + if (columnId === startWrapperIndexTest.current.index) { return; } setWrapperHover((prevArray) => prevArray.map((elem, index) => { - if (index === wrapperIndex) { + if (index === columnId) { return true; } else { return false; @@ -450,9 +450,9 @@ export const Tracker = () => { ); } - function dragDropHandler(e, wrapperIndex) { + function dragDropHandler(e, columnId) { e.preventDefault(); - if (startWrapperIndex.index === wrapperIndex) { + if (startWrapperIndexTest.current.index === columnId) { return; } setWrapperHover((prevArray) => @@ -460,22 +460,27 @@ export const Tracker = () => { return false; }) ); - setTabTaskMok((prevArray) => - prevArray.map((elem, index) => { - if (index === wrapperIndex) { - return { ...elem, tasks: [...elem.tasks, startWrapperIndex.task] }; - } else if (index === startWrapperIndex.index) { - return { - ...elem, - tasks: elem.tasks.filter((item) => { - return item.id !== startWrapperIndex.task.id; - }), - }; - } else { - return elem; - } - }) - ); + + if (columnId !== startWrapperIndexTest.current.index) { + dispatch(moveProjectTask({startWrapperIndex:startWrapperIndexTest.current, columnId})) + } + + // setTabTaskMok((prevArray) => + // prevArray.map((elem, index) => { + // if (index === columnId) { + // return { ...elem, tasks: [...elem.tasks, startWrapperIndex.task] }; + // } else if (index === startWrapperIndex.index) { + // return { + // ...elem, + // tasks: elem.tasks.filter((item) => { + // return item.id !== startWrapperIndex.task.id; + // }), + // }; + // } else { + // return elem; + // } + // }) + // ); } function filterArchiveTasks(e) { @@ -496,9 +501,8 @@ export const Tracker = () => { ); } - function selectedTabTask(e, wrapperIndex, name, tasks) { - let tab = { name: name, indexTab: wrapperIndex, task: tasks }; - setSelectedTab(tab); + function selectedTabTask(columnId) { + setSelectedTab(columnId); setModalCreateTiket(true); } @@ -508,39 +512,64 @@ export const Tracker = () => { } function createTiket() { - tabTaskMok.filter((item) => { - if (item.name == selectedTab.name) { - let idItem = 0; + if (!valueTiket || !descriptionTicket) { + return + } - item.tasks.forEach((item) => { - idItem = item.id; - }); - - let newTiket = { - task: valueTiket, - description: "Сверстать часть таблицы. Сверстать часть таблицы", - comments: 0, - files: 0, - avatarCreated: avatarTest, - avatarDo: avatarTest, - id: idItem + 1, - }; - - item.tasks.push(newTiket); + apiRequest('/task/create-task', { + method: 'POST', + data: { + project_id: projectBoard.id, + title: valueTiket, + description: descriptionTicket, + status: 1, + user_id: localStorage.getItem('id'), + column_id: selectedTab } - }); + }).then((res) => { + dispatch(setProjectBoardFetch(projectBoard.id)) + }) + setModalCreateTiket(false); setValueTiket(""); + setDescriptionTicket("") + // tabTaskMok.filter((item) => { + // if (item.name == selectedTab.name) { + // let idItem = 0; + // + // item.tasks.forEach((item) => { + // idItem = item.id; + // }); + // + // let newTiket = { + // task: valueTiket, + // description: descriptionTicket, + // comments: 0, + // files: 0, + // avatarCreated: avatarTest, + // avatarDo: avatarTest, + // id: idItem + 1, + // }; + // + // item.tasks.push(newTiket); + // } + // }); } function createTab() { - let newTab = { - name: valueColl, - open: false, - tasks: [], - }; + if (!valueColl) { + return + } - tabTaskMok.unshift(newTab); + apiRequest('/project-column/create-column', { + method: 'POST', + data: { + project_id: projectBoard.id, + title: valueColl + } + }).then((res) => { + dispatch(setProjectBoardFetch(projectBoard.id)) + }) setValueColl(""); setModalCreateColl(false); } @@ -653,7 +682,7 @@ export const Tracker = () => { >
-

Проект : Разработка трекера

+

Проект : {projectBoard.name}

{
-

Введите название карточки

+

Введите название и описание задачи

setValueTiket(e.target.value)} + placeholder='Название задачи' + > +
+
+ setDescriptionTicket(e.target.value)} + placeholder='Описание задачи' >
@@ -750,59 +788,53 @@ export const Tracker = () => {
- {tabTaskMok.map((section, wrapperIndex) => { + {Boolean(projectBoard?.columns) && Boolean(projectBoard.columns.length) && projectBoard.columns.map((column) => { return (
dragOverHandler(e)} - onDragEnter={(e) => dragEnterHandler(wrapperIndex)} - onDrop={(e) => dragDropHandler(e, wrapperIndex)} + onDragEnter={(e) => dragEnterHandler(column.id)} + onDrop={(e) => dragDropHandler(e, column.id)} className={`tasks__board ${ - section.tasks.length >= 3 ? "tasks__board__more" : "" + column.tasks.length >= 3 ? "tasks__board__more" : "" } ${ - wrapperHover[wrapperIndex] ? "tasks__board__hover" : "" + wrapperHover[column.id] ? "tasks__board__hover" : "" }`} >
- - {section.name} + {/**/} + + {column.title}
- selectedTabTask( - e, - wrapperIndex, - section.name, - section.tasks - ) - } + onClick={() => selectedTabTask(column.id)} > + ...
- {section.tasks.map((task, index) => { + {column.tasks.map((task, index) => { if (index > 2) { - if (!section.open) { + if (!column.open) { return; } } return (
- dragStartHandler(e, task, wrapperIndex) + dragStartHandler(e, task, column.id) } onDragEnd={(e) => dragEndHandler(e)} - onClick={(e) => openTicket(e, index)} + onClick={(e) => openTicket(e, task.id)} >
-

{task.task}

+

{task.title}

{task.description} @@ -816,24 +848,24 @@ export const Tracker = () => { filesImg {task.files} файлов

-
- avatar - avatar -
+ {/*
*/} + {/* avatar*/} + {/* avatar*/} + {/*
*/}
); })} - {section.tasks.length > 3 && ( + {column.tasks.length > 3 && ( toggleMoreTasks(wrapperIndex)} + onClick={() => toggleMoreTasks(column.id)} > - {section.open ? "-" : "+"} + {column.open ? "-" : "+"} )}
diff --git a/src/pages/Tracker/tracker.scss b/src/pages/Tracker/tracker.scss index 9aefe3cb..87226a4b 100644 --- a/src/pages/Tracker/tracker.scss +++ b/src/pages/Tracker/tracker.scss @@ -397,6 +397,9 @@ border-radius: 6px; background: #ffffff; cursor: pointer; + display: flex; + flex-direction: column; + justify-content: space-between; &__hide { opacity: 0; diff --git a/src/redux/projectsTrackerSlice.js b/src/redux/projectsTrackerSlice.js index c35991bf..62465064 100644 --- a/src/redux/projectsTrackerSlice.js +++ b/src/redux/projectsTrackerSlice.js @@ -1,34 +1,49 @@ -import { createSlice } from "@reduxjs/toolkit"; +import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; +import {apiRequest} from "../api/request"; +import {act} from "@testing-library/react"; const initialState = { - project: [ - { - name: "Разработка трекера", - count: 4, - }, - { - name: "Кинотеатр", - count: 4, - }, - { - name: "Проект страхование", - count: 4, - }, - ], + projects: [], + projectBoard: {} }; +export const setProjectBoardFetch = createAsyncThunk( + 'userInfo', + (id) => + apiRequest(`/project/get-project?project_id=${id}&expand=columns`) +); + export const projectsTrackerSlice = createSlice({ name: "projectsTracker", initialState, reducers: { - setProject: (state, action) => { - state.project.push(action.payload); + setAllProjects: (state, action) => { + state.projects = action.payload }, + setProject: (state, action) => { + state.projects.push(action.payload); + }, + moveProjectTask: (state, action) => { + state.projectBoard.columns.forEach((column) => { + if (column.id === action.payload.columnId) { + column.tasks.push(action.payload.startWrapperIndex.task) + } + if (column.id === action.payload.startWrapperIndex.index) { + column.tasks.splice(column.tasks.indexOf(action.payload.startWrapperIndex.task), 1) + } + }) + } }, + extraReducers: { + [setProjectBoardFetch.fulfilled]: (state, action) => { + state.projectBoard = action.payload + } + } }); -export const { setProject } = projectsTrackerSlice.actions; +export const { setProject, setAllProjects, moveProjectTask } = projectsTrackerSlice.actions; -export const getProjects = (state) => state.tracker.project; +export const getProjects = (state) => state.tracker.projects; +export const getProjectBoard = (state) => state.tracker.projectBoard; export default projectsTrackerSlice.reducer;