fix task modal and column priority

This commit is contained in:
Николай Полтщук 2023-06-09 03:19:09 +03:00
parent 4e0a44e5a4
commit f4b55a5d79
9 changed files with 189 additions and 46 deletions

View File

@ -77,15 +77,19 @@ export const TrackerTaskComment = ({
</div> </div>
<div className='comments__list__item__date'> <div className='comments__list__item__date'>
<span>{getCorrectDate(comment.created_at)}</span> <span>{getCorrectDate(comment.created_at)}</span>
<div className={commentsEditOpen ? 'edit edit__open' : 'edit'} > {comment.user_id === Number(localStorage.getItem('id')) &&
<img src={edit} alt='edit' onClick={() => { <>
if (commentsEditOpen) { <div className={commentsEditOpen ? 'edit edit__open' : 'edit'} >
editComment() <img src={edit} alt='edit' onClick={() => {
} if (commentsEditOpen) {
setCommentsEditOpen(!commentsEditOpen) editComment()
}} /> }
</div> setCommentsEditOpen(!commentsEditOpen)
<img src={del} alt='delete' onClick={() => deleteComment()} /> }} />
</div>
<img src={del} alt='delete' onClick={() => deleteComment()} />
</>
}
</div> </div>
</div> </div>
{commentsEditOpen ? {commentsEditOpen ?

View File

@ -98,6 +98,7 @@ export const ModalTiсket = ({
function commentDelete(comment) { function commentDelete(comment) {
setComments((prevValue) => prevValue.filter((item) => item.id !== comment.id)) setComments((prevValue) => prevValue.filter((item) => item.id !== comment.id))
if (comment.subComments.length) { if (comment.subComments.length) {
// promiseAll
comment.subComments.forEach((subComment) => { comment.subComments.forEach((subComment) => {
apiRequest("/comment/update", { apiRequest("/comment/update", {
method: "PUT", method: "PUT",
@ -225,7 +226,7 @@ export const ModalTiсket = ({
}) })
apiRequest(`/timer/get-by-entity?entity_type=2&entity_id=${task.id}`).then((res) => { apiRequest(`/timer/get-by-entity?entity_type=2&entity_id=${task.id}`).then((res) => {
let timerSeconds = 0 let timerSeconds = 0
res.forEach((time) => { res.length && res.forEach((time) => {
timerSeconds += time.deltaSeconds timerSeconds += time.deltaSeconds
setCurrentTimerCount({ setCurrentTimerCount({
hours: Math.floor(timerSeconds / 60 / 60), hours: Math.floor(timerSeconds / 60 / 60),
@ -437,7 +438,7 @@ export const ModalTiсket = ({
Остановить Остановить
</button> </button>
: :
<button className="start" onClick={() => startTaskTimer()}> <button className={task.executor_id === Number(localStorage.getItem('id')) ? 'start' : 'start disable'} onClick={() => startTaskTimer()}>
Начать делать <img src={arrow}></img> Начать делать <img src={arrow}></img>
</button> </button>
} }

View File

@ -436,6 +436,11 @@
} }
} }
.disable {
opacity: 0.5;
pointer-events: none;
}
.stop { .stop {
font-size: 12px; font-size: 12px;
margin-top: 25px; margin-top: 25px;

View File

@ -16,7 +16,7 @@ import {
setProjectBoardFetch, setProjectBoardFetch,
setToggleTab, setToggleTab,
getProjectBoard, getProjectBoard,
getBoarderLoader getBoarderLoader, filteredParticipateTasks, filterCreatedByMe
} from "../../../redux/projectsTrackerSlice"; } from "../../../redux/projectsTrackerSlice";
import { apiRequest } from "../../../api/request"; import { apiRequest } from "../../../api/request";
@ -28,15 +28,15 @@ import arrow2 from "../../../images/arrowStart.png";
import plus from "../../../images/plus.svg"; import plus from "../../../images/plus.svg";
import tasks from "../../../images/trackerTasks.svg"; import tasks from "../../../images/trackerTasks.svg";
import archive from "../../../images/archiveTracker.svg"; import archive from "../../../images/archiveTracker.svg";
import selectArrow from "../../../images/select.svg";
import arrow from "../../../images/arrowCalendar.png"; import arrow from "../../../images/arrowCalendar.png";
import link from "../../../images/link.svg"; import link from "../../../images/link.svg";
import archive2 from "../../../images/archive.svg"; import archive2 from "../../../images/archive.svg";
import del from "../../../images/delete.svg"; import del from "../../../images/delete.svg";
import edit from "../../../images/edit.svg"; import edit from "../../../images/edit.svg";
import accept from "../../../images/accept.png";
import close from "../../../images/closeProjectPersons.svg";
import "./ticketFullScreen.scss"; import "./ticketFullScreen.scss";
import close from "../../../images/closeProjectPersons.svg";
import {getCorrectRequestDate, urlForLocal} from "../../../helper"; import {getCorrectRequestDate, urlForLocal} from "../../../helper";
export const TicketFullScreen = ({}) => { export const TicketFullScreen = ({}) => {
@ -295,14 +295,6 @@ export const TicketFullScreen = ({}) => {
</div> </div>
} }
</div> </div>
<div className="tasks__head__select">
<span>Учавствую</span>
<img src={selectArrow} alt="arrow" />
</div>
<div className="tasks__head__select">
<span>Мои</span>
<img src={selectArrow} alt="arrow" />
</div>
<Link to={`/profile/tracker`} className="link"> <Link to={`/profile/tracker`} className="link">
<div className="tasks__head__back"> <div className="tasks__head__back">
<p>Вернуться на проекты</p> <p>Вернуться на проекты</p>
@ -421,7 +413,7 @@ export const TicketFullScreen = ({}) => {
Остановить Остановить
</button> </button>
: :
<button className="start" onClick={() => startTaskTimer()}> <button className={taskInfo.executor_id === Number(localStorage.getItem('id')) ? 'start' : 'start disable'} onClick={() => startTaskTimer()}>
Начать делать <img src={arrow2}></img> Начать делать <img src={arrow2}></img>
</button> </button>
} }

View File

@ -5,6 +5,7 @@ import { apiRequest } from "../../../api/request";
import { urlForLocal } from '../../../helper' import { urlForLocal } from '../../../helper'
import { import {
setColumnName, setColumnName,
setColumnPriority,
getProjectBoard, getProjectBoard,
getValueModalType, getValueModalType,
setProject, setProject,
@ -13,7 +14,7 @@ import {
editColumnName, editColumnName,
getColumnName, getColumnName,
getColumnId, getColumnId,
addPersonToProject addPersonToProject, getColumnPriority
} from "../../../redux/projectsTrackerSlice"; } from "../../../redux/projectsTrackerSlice";
import arrowDown from "../../../images/selectArrow.png" import arrowDown from "../../../images/selectArrow.png"
@ -33,6 +34,7 @@ export const TrackerModal = ({
const projectBoard = useSelector(getProjectBoard); const projectBoard = useSelector(getProjectBoard);
const columnName = useSelector(getColumnName); const columnName = useSelector(getColumnName);
const columnId = useSelector(getColumnId) const columnId = useSelector(getColumnId)
const columnPriority = useSelector(getColumnPriority)
const modalType = useSelector(getValueModalType); const modalType = useSelector(getValueModalType);
const [projectName, setProjectName] = useState(defautlInput); const [projectName, setProjectName] = useState(defautlInput);
@ -53,6 +55,7 @@ export const TrackerModal = ({
method: "POST", method: "POST",
data: { data: {
project_id: projectBoard.id, project_id: projectBoard.id,
priority: projectBoard.columns.length ? projectBoard.columns.at(-1).priority + 1 : 1,
title: valueColumn, title: valueColumn,
}, },
}).then((res) => { }).then((res) => {
@ -100,7 +103,42 @@ export const TrackerModal = ({
}); });
} }
function changeColumnName() { function changeColumnParams() {
projectBoard.columns.forEach((column) => {
if (column.id === columnId && column.priority !== columnPriority) {
const priorityColumns = [{
column_id: column.id,
priority: Number(columnPriority)
}]
for (let i = column.priority; i < columnPriority; i++) {
const currentColumn = {
column_id: projectBoard.columns[i].id,
priority: i
}
priorityColumns.push(currentColumn)
}
for (let i = column.priority; i > columnPriority; i--) {
const currentColumn = {
column_id: projectBoard.columns[i - 2].id,
priority: i
}
priorityColumns.push(currentColumn)
}
apiRequest("/project-column/set-priority", {
method: "POST",
data: {
project_id: projectBoard.id,
data: JSON.stringify(priorityColumns)
}
}).then(() => {
dispatch(setProjectBoardFetch(projectBoard.id));
})
}
})
changeColumnTitle()
}
function changeColumnTitle() {
apiRequest("/project-column/update-column", { apiRequest("/project-column/update-column", {
method: "PUT", method: "PUT",
data: { data: {
@ -318,8 +356,19 @@ export const TrackerModal = ({
onChange={(e) => dispatch(setColumnName(e.target.value))} onChange={(e) => dispatch(setColumnName(e.target.value))}
/> />
</div> </div>
<h4>Приоритет колонки</h4>
<div className="input-container">
<input
className="name-project"
placeholder='Приоритет колонки'
type='number'
step='1'
value={columnPriority}
onChange={(e) => dispatch(setColumnPriority(e.target.value))}
/>
</div>
</div> </div>
<button className="button-add" onClick={changeColumnName}> <button className="button-add" onClick={changeColumnParams}>
Сохранить Сохранить
</button> </button>
</div> </div>

View File

@ -26,7 +26,7 @@
.title-project { .title-project {
display: flex; display: flex;
align-items: flex-start; align-items: center;
flex-direction: column; flex-direction: column;
.input-container { .input-container {
@ -34,7 +34,11 @@
height: 35px; height: 35px;
background: #ffffff; background: #ffffff;
border-radius: 8px; border-radius: 8px;
margin-top: 12px; margin: 12px 0;
input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
} }
h4 { h4 {
@ -123,7 +127,6 @@
} }
.button-add { .button-add {
margin: 20px;
width: 130px; width: 130px;
height: 37px; height: 37px;
background: #52b709; background: #52b709;
@ -136,6 +139,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin: 0 auto;
} }
} }

View File

@ -19,7 +19,10 @@ import {
activeLoader, activeLoader,
setColumnName, setColumnName,
setColumnId, setColumnId,
deletePersonOnProject setColumnPriority,
deletePersonOnProject,
filterCreatedByMe,
filteredParticipateTasks
} from "../../redux/projectsTrackerSlice"; } from "../../redux/projectsTrackerSlice";
import ModalTicket from "../../components/UI/ModalTicket/ModalTicket"; import ModalTicket from "../../components/UI/ModalTicket/ModalTicket";
@ -28,13 +31,13 @@ import TrackerModal from "../../components/UI/TrackerModal/TrackerModal";
import project from "../../images/trackerProject.svg"; import project from "../../images/trackerProject.svg";
import tasks from "../../images/trackerTasks.svg"; import tasks from "../../images/trackerTasks.svg";
import archive from "../../images/archiveTracker.svg"; import archive from "../../images/archiveTracker.svg";
import selectArrow from "../../images/select.svg";
import commentsBoard from "../../images/commentsBoard.svg"; import commentsBoard from "../../images/commentsBoard.svg";
import filesBoard from "../../images/filesBoard.svg"; import filesBoard from "../../images/filesBoard.svg";
import arrow from "../../images/arrowCalendar.png"; import arrow from "../../images/arrowCalendar.png";
import del from "../../images/delete.svg"; import del from "../../images/delete.svg";
import edit from "../../images/edit.svg"; import edit from "../../images/edit.svg";
import close from "../../images/closeProjectPersons.svg" import close from "../../images/closeProjectPersons.svg"
import accept from "../../images/accept.png";
export const ProjectTracker = () => { export const ProjectTracker = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -48,7 +51,8 @@ export const ProjectTracker = () => {
const [modalActiveTicket, setModalActiveTicket] = useState(false); const [modalActiveTicket, setModalActiveTicket] = useState(false);
const [selectedTicket, setSelectedTicket] = useState({}); const [selectedTicket, setSelectedTicket] = useState({});
const [personListOpen, setPersonListOpen] = useState(false) const [personListOpen, setPersonListOpen] = useState(false)
const [checkBoxParticipateTasks, setCheckBoxParticipateTasks] = useState(false)
const [checkBoxMyTasks, setCheckBoxMyTasks] = useState(false)
const startWrapperIndexTest = useRef({}); const startWrapperIndexTest = useRef({});
const projectBoard = useSelector(getProjectBoard); const projectBoard = useSelector(getProjectBoard);
const loader = useSelector(getBoarderLoader); const loader = useSelector(getBoarderLoader);
@ -142,16 +146,36 @@ export const ProjectTracker = () => {
setModalActiveTicket(true); setModalActiveTicket(true);
} }
function deleteColumn(id) { function deleteColumn(column) {
const priorityColumns = []
apiRequest("/project-column/update-column", { apiRequest("/project-column/update-column", {
method: "PUT", method: "PUT",
data: { data: {
column_id: id, column_id: column.id,
project_id: projectBoard.id, project_id: projectBoard.id,
status: 0, status: 0,
}, },
}).then((res) => { }).then((res) => {
dispatch(setProjectBoardFetch(projectBoard.id)); if (column.priority < projectBoard.columns.length) {
for (let i = column.priority; i < projectBoard.columns.length; i++) {
const currentColumn = {
column_id: projectBoard.columns[i].id,
priority: i
}
priorityColumns.push(currentColumn)
}
apiRequest("/project-column/set-priority", {
method: "POST",
data: {
project_id: projectBoard.id,
data: JSON.stringify(priorityColumns)
}
}).then(() => {
dispatch(setProjectBoardFetch(projectBoard.id));
})
} else {
dispatch(setProjectBoardFetch(projectBoard.id));
}
}); });
} }
@ -167,6 +191,28 @@ export const ProjectTracker = () => {
}); });
} }
function filterParticipateTasks() {
if (!checkBoxParticipateTasks) {
dispatch(filteredParticipateTasks(Number(localStorage.getItem('id'))))
} else {
dispatch(setProjectBoardFetch(projectId.id))
setCheckBoxParticipateTasks(false)
setCheckBoxMyTasks(false)
}
setCheckBoxParticipateTasks(!checkBoxParticipateTasks)
}
function filterMyTask() {
if (!checkBoxMyTasks) {
dispatch(filterCreatedByMe(Number(localStorage.getItem('id'))))
} else {
dispatch(setProjectBoardFetch(projectId.id))
setCheckBoxParticipateTasks(false)
setCheckBoxMyTasks(false)
}
setCheckBoxMyTasks(!checkBoxMyTasks)
}
return ( return (
<div className="tracker"> <div className="tracker">
<ProfileHeader /> <ProfileHeader />
@ -276,13 +322,21 @@ export const ProjectTracker = () => {
</div> </div>
} }
</div> </div>
<div className="tasks__head__select"> <div className="tasks__head__checkBox" onClick={filterParticipateTasks}>
<span>Участвую</span> <span>Участвую</span>
<img src={selectArrow} alt="arrow" /> <div className="tasks__head__checkBox__box">
{checkBoxParticipateTasks &&
<img src={accept} alt='accept' />
}
</div>
</div> </div>
<div className="tasks__head__select"> <div className="tasks__head__checkBox" onClick={filterMyTask}>
<span>Мои</span> <span>Мои</span>
<img src={selectArrow} alt="arrow" /> <div className="tasks__head__checkBox__box">
{checkBoxMyTasks &&
<img src={accept} alt='accept' />
}
</div>
</div> </div>
<Link to="/profile/tracker" className="tasks__head__back"> <Link to="/profile/tracker" className="tasks__head__back">
<p>Вернуться на проекты</p> <p>Вернуться на проекты</p>
@ -351,6 +405,7 @@ export const ProjectTracker = () => {
dispatch(modalToggle("editColumn")); dispatch(modalToggle("editColumn"));
dispatch(setColumnName(column.title)) dispatch(setColumnName(column.title))
dispatch(setColumnId(column.id)) dispatch(setColumnId(column.id))
dispatch(setColumnPriority(column.priority))
setModalAdd(true); setModalAdd(true);
}} }}
> >
@ -359,7 +414,7 @@ export const ProjectTracker = () => {
</div> </div>
<div <div
className="column__select__item" className="column__select__item"
onClick={() => deleteColumn(column.id)} onClick={() => deleteColumn(column)}
> >
<img src={del} alt="delete" /> <img src={del} alt="delete" />
<span>Удалить</span> <span>Удалить</span>

View File

@ -423,18 +423,33 @@
} }
} }
&__select { &__checkBox {
cursor: pointer; cursor: pointer;
display: flex;
align-items: center;
img {
margin-left: 18px;
}
span { span {
color: #252c32; color: #252c32;
font-weight: 400; font-weight: 400;
font-size: 14px; font-size: 14px;
line-height: 24px; line-height: 24px;
} }
&__box {
width: 20px;
height: 20px;
border-radius: 6px;
border: solid 1px gray;
margin-left: 5px;
display: flex;
justify-content: center;
align-items: center;
img {
width: 18px;
height: 18px;
}
}
} }
&__back { &__back {

View File

@ -8,7 +8,8 @@ const initialState = {
modalType: "", modalType: "",
boardLoader: false, boardLoader: false,
columnName: "", columnName: "",
columnId: 0 columnId: 0,
columnPriority: 0
}; };
export const setProjectBoardFetch = createAsyncThunk("userInfo", (id) => export const setProjectBoardFetch = createAsyncThunk("userInfo", (id) =>
@ -63,12 +64,25 @@ export const projectsTrackerSlice = createSlice({
} }
}); });
}, },
filterCreatedByMe: (state, action) => {
state.projectBoard.columns.forEach((column) => {
column.tasks = column.tasks.filter((task) => task.user_id === action.payload)
})
},
filteredParticipateTasks: (state, action) => {
state.projectBoard.columns.forEach((column) => {
column.tasks = column.tasks.filter((task) => task.taskUsers.some((person) => person.user_id === action.payload))
})
},
setColumnName: (state, action) => { setColumnName: (state, action) => {
state.columnName = action.payload state.columnName = action.payload
}, },
setColumnId: (state, action) => { setColumnId: (state, action) => {
state.columnId = action.payload state.columnId = action.payload
}, },
setColumnPriority: (state, action) => {
state.columnPriority = action.payload
},
editProjectName: (state, action) => { editProjectName: (state, action) => {
state.projects.forEach((project) => { state.projects.forEach((project) => {
if (project.id === action.payload.id) { if (project.id === action.payload.id) {
@ -107,8 +121,11 @@ export const {
editProjectName, editProjectName,
editColumnName, editColumnName,
setColumnId, setColumnId,
setColumnPriority,
deletePersonOnProject, deletePersonOnProject,
addPersonToProject addPersonToProject,
filterCreatedByMe,
filteredParticipateTasks
} = projectsTrackerSlice.actions; } = projectsTrackerSlice.actions;
export const getProjects = (state) => state.tracker.projects; export const getProjects = (state) => state.tracker.projects;
@ -118,5 +135,6 @@ export const getValueModalType = (state) => state.tracker.modalType;
export const getBoarderLoader = (state) => state.tracker.boardLoader; export const getBoarderLoader = (state) => state.tracker.boardLoader;
export const getColumnName = (state) => state.tracker.columnName; export const getColumnName = (state) => state.tracker.columnName;
export const getColumnId = (state) => state.tracker.columnId; export const getColumnId = (state) => state.tracker.columnId;
export const getColumnPriority = (state) => state.tracker.columnPriority
export default projectsTrackerSlice.reducer; export default projectsTrackerSlice.reducer;