Commit a9661e91 authored by Ermolaev Timur's avatar Ermolaev Timur

Merge branch 'task-129-feature/add_project_in_modal_task' into 'development'

Task 129 feature/add project in modal task

See merge request !102
parents 465fd444 88508f5d
...@@ -22,7 +22,7 @@ router.post("/make-copy",auth,authAuthorOrExecutorOfTask, async(req:Request, res ...@@ -22,7 +22,7 @@ router.post("/make-copy",auth,authAuthorOrExecutorOfTask, async(req:Request, res
/** change date time of copy of task in calendar view */ /** change date time of copy of task in calendar view */
router.put("/change-copy/:dateTimeTaskId",auth, authAuthorOrExecutorOfTask, async(req:Request, res: Response):Promise<Response>=>{ router.put("/change-copy/:dateTimeTaskId",auth, authAuthorOrExecutorOfTask, async(req:Request, res: Response):Promise<Response>=>{
const {dateTimeTaskId} = req.params const {dateTimeTaskId} = req.params
const {executorStatus,authorStatus, task, dateTimeStart, dateTimeDue, description, title, priority} = req.body const {executorStatus,authorStatus, task, dateTimeStart, dateTimeDue, description, title, priority, project} = req.body
if(authorStatus){ if(authorStatus){
task.title = title; task.title = title;
task.description = description; task.description = description;
...@@ -73,6 +73,7 @@ router.put("/change-copy/:dateTimeTaskId",auth, authAuthorOrExecutorOfTask, asyn ...@@ -73,6 +73,7 @@ router.put("/change-copy/:dateTimeTaskId",auth, authAuthorOrExecutorOfTask, asyn
task.title = title; task.title = title;
task.description = description; task.description = description;
task.priority = priority; task.priority = priority;
task.project = project
await task.save() await task.save()
return res.send({task}) return res.send({task})
}) })
......
import { Button, TextField } from "@mui/material"; import { Button, TextField } from "@mui/material";
import { memo } from "react"; import { memo } from "react";
import { useSelector } from "react-redux";
import { priorities } from "../../../constants"; import { priorities } from "../../../constants";
import CustomSelect from '../../UI/СustomSelect/СustomSelect' import CustomSelect from '../../UI/СustomSelect/СustomSelect'
import { isValidate } from "./Helpers"; import { isValidate } from "./Helpers";
function CalendarModalTaskContent({ title, onChangeCurrentTaskHandler, description, priority, sendNewTaskHandler, deleteTaskHandler, startHour, endHour, id }) { function CalendarModalTaskContent({ title, onChangeCurrentTaskHandler, description, priority, project, sendNewTaskHandler, deleteTaskHandler, startHour, endHour, id }) {
return (<> const { allUserProjectsForModalTask } = useSelector(state => state.projects)
<TextField
id="task-description-title" return (
value={title} <>
label="Название"
variant="outlined"
sx={{ marginBottom: '30px' }}
name='title'
onChange={(e) => { onChangeCurrentTaskHandler(e) }}
/>
<TextField
id="task-description"
multiline
rows={4}
value={description}
label="Описание"
variant="outlined"
sx={{ marginBottom: '30px' }}
name='description'
onChange={(e) => { onChangeCurrentTaskHandler(e) }}
/>
<CustomSelect
defaultValue={null}
value={priority}
name={'priority'}
variant={'outlined'}
onChange={(e) => { onChangeCurrentTaskHandler(e) }}
label={'Приоритет'}
id={'priority-type'}
items={priorities}
/>
<div style={{ display: 'flex', gap: '20px', margin: '20px 0' }}>
<TextField <TextField
id="task-startHour" id="task-description-title"
value={startHour} value={title}
label="От" label="Название"
variant="outlined" variant="outlined"
name='startHour' sx={{ marginBottom: '30px' }}
name='title'
onChange={(e) => { onChangeCurrentTaskHandler(e) }} onChange={(e) => { onChangeCurrentTaskHandler(e) }}
/> />
<TextField <TextField
id="task-endHour" id="task-description"
value={endHour} multiline
label="До" rows={4}
value={description}
label="Описание"
variant="outlined" variant="outlined"
name='endHour' sx={{ marginBottom: '30px' }}
name='description'
onChange={(e) => { onChangeCurrentTaskHandler(e) }} onChange={(e) => { onChangeCurrentTaskHandler(e) }}
/> />
</div> <div style={{ display: 'flex', gap: '20px', margin: '20px 0' }}>
<div style={{ display: 'flex', gap: '20px', margin: '10px 0' }}> <CustomSelect
<Button id='test_button_save_task' onClick={sendNewTaskHandler} disabled={!isValidate(title, startHour, endHour)}>Сохранить</Button> defaultValue={null}
<Button onClick={deleteTaskHandler} disabled={!id}>Удалить</Button> value={priority}
</div> name={'priority'}
</>); variant={'outlined'}
onChange={(e) => { onChangeCurrentTaskHandler(e) }}
label={'Приоритет'}
id={'priority-type'}
items={priorities}
/>
<CustomSelect
value={project}
name={'project'}
variant={'outlined'}
onChange={(e) => { onChangeCurrentTaskHandler(e) }}
label={'Проект'}
id={'project'}
items={allUserProjectsForModalTask}
/>
</div>
<div style={{ display: 'flex', gap: '20px', margin: '20px 0' }}>
<TextField
id="task-startHour"
value={startHour}
label="От"
variant="outlined"
name='startHour'
onChange={(e) => { onChangeCurrentTaskHandler(e) }}
/>
<TextField
id="task-endHour"
value={endHour}
label="До"
variant="outlined"
name='endHour'
onChange={(e) => { onChangeCurrentTaskHandler(e) }}
/>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', margin: '10px 0' }}>
<Button id='test_button_save_task' onClick={sendNewTaskHandler} disabled={!isValidate(title, project, startHour, endHour)}>Сохранить</Button>
<Button onClick={deleteTaskHandler} disabled={!id}>Удалить</Button>
</div>
</>);
} }
export default memo(CalendarModalTaskContent); export default memo(CalendarModalTaskContent);
\ No newline at end of file
export const isValidate = (title, startHour, endHour) => { export const isValidate = (title, project, startHour, endHour) => {
if (title) { if (title && project) {
const startHourInt = parseInt(startHour) const startHourInt = parseInt(startHour)
const endHourInt = parseInt(endHour) const endHourInt = parseInt(endHour)
if (startHourInt >= 8 && startHourInt <= 24) { if (startHourInt >= 8 && startHourInt <= 24) {
......
...@@ -26,16 +26,16 @@ export default function ModalTask({ modal, handleClose, children, week }) { ...@@ -26,16 +26,16 @@ export default function ModalTask({ modal, handleClose, children, week }) {
const getYCordinatesToModal = useCallback(() => { const getYCordinatesToModal = useCallback(() => {
if (week) { if (week) {
if (windowDimenion.winHeight > modal.yClickСordinates + 450) { if (windowDimenion.winHeight > modal.yClickСordinates + 470) {
return modal.yClickСordinates - modal.yDivClick return modal.yClickСordinates - modal.yDivClick
} else { } else {
return modal.yClickСordinates - 450 return modal.yClickСordinates - 470
} }
} else { } else {
if (windowDimenion.winHeight > modal.yClickСordinates + 450) { if (windowDimenion.winHeight > modal.yClickСordinates + 470) {
return modal.yClickСordinates - modal.yDiv - modal.yDivClick return modal.yClickСordinates - modal.yDiv - modal.yDivClick
} else { } else {
return modal.yClickСordinates - modal.yDiv - modal.yDivClick - ((modal.yClickСordinates + 450) - windowDimenion.winHeight) - 30 return modal.yClickСordinates - modal.yDiv - modal.yDivClick - ((modal.yClickСordinates + 470) - windowDimenion.winHeight) - 30
} }
} }
}, [windowDimenion.winHeight, modal]) }, [windowDimenion.winHeight, modal])
...@@ -55,7 +55,7 @@ export default function ModalTask({ modal, handleClose, children, week }) { ...@@ -55,7 +55,7 @@ export default function ModalTask({ modal, handleClose, children, week }) {
top: getYCordinatesToModal(), top: getYCordinatesToModal(),
left: getXCordinatesToModal(), left: getXCordinatesToModal(),
width: 270, width: 270,
height: 450, height: 470,
bgcolor: 'background.paper', bgcolor: 'background.paper',
border: '2px solid #000', border: '2px solid #000',
boxShadow: 24, boxShadow: 24,
......
...@@ -6,10 +6,11 @@ import CalendarStandartCell from "../../CalendarStandartCell/CalendarStandartCel ...@@ -6,10 +6,11 @@ import CalendarStandartCell from "../../CalendarStandartCell/CalendarStandartCel
import ModalTask from "../../ModalTask/ModalTask" import ModalTask from "../../ModalTask/ModalTask"
import MonthCalendarModalContent from "../../CalendarModalTaskContent/CalendarModalTaskContent"; import MonthCalendarModalContent from "../../CalendarModalTaskContent/CalendarModalTaskContent";
import CalendarRowDay from "./CalendarRowDay/CalendarRowDay"; import CalendarRowDay from "./CalendarRowDay/CalendarRowDay";
import { useSelector } from "react-redux";
function MonthCalendarBody({ month, year, tasks, createTaskInCellHandler, currentTask, setCurrentTask, hourFormat, setHourFormat, onChangeCurrentTaskHandler, sendNewTaskHandler, deleteTaskHandler, cellSizes, hoursInDay, daysInMonth, dragTaskHandler, createCopyTask, setCopyTask, copyTask }) { function MonthCalendarBody({ month, year, tasks, createTaskInCellHandler, currentTask, setCurrentTask, hourFormat, setHourFormat, onChangeCurrentTaskHandler, sendNewTaskHandler, deleteTaskHandler, cellSizes, hoursInDay, daysInMonth, dragTaskHandler, createCopyTask, setCopyTask, copyTask}) {
const [currentLine, setCurrentLine] = useState('') const [currentLine, setCurrentLine] = useState('')
const [modal, setModal] = useState({ open: false, y: 0, x: 0, }); const [modal, setModal] = useState({ open: false, y: 0, x: 0, });
const handleOpen = useCallback((e) => { const handleOpen = useCallback((e) => {
...@@ -89,6 +90,7 @@ function MonthCalendarBody({ month, year, tasks, createTaskInCellHandler, curren ...@@ -89,6 +90,7 @@ function MonthCalendarBody({ month, year, tasks, createTaskInCellHandler, curren
title={currentTask.title} title={currentTask.title}
description={currentTask.description} description={currentTask.description}
priority={currentTask.priority} priority={currentTask.priority}
project={currentTask.project}
id={currentTask.id} id={currentTask.id}
startHour={currentTask.infoForCell?.startHour} startHour={currentTask.infoForCell?.startHour}
endHour={currentTask.infoForCell?.endHour} endHour={currentTask.infoForCell?.endHour}
......
...@@ -2,7 +2,7 @@ import { Grid } from "@mui/material"; ...@@ -2,7 +2,7 @@ import { Grid } from "@mui/material";
import { Box } from "@mui/system"; import { Box } from "@mui/system";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import ModalTask from "../../ModalTask/ModalTask"; import ModalTask from "../../ModalTask/ModalTask";
import MonthCalendarModalContent from "../../CalendarModalTaskContent/CalendarModalTaskContent"; import CalendarModalTaskContent from "../../CalendarModalTaskContent/CalendarModalTaskContent";
import CalendarRow from "../../CalendarRow/CalendarRow"; import CalendarRow from "../../CalendarRow/CalendarRow";
import CalendarSmallCell from "../../CalendarSmallCell/CalendarSmallCell"; import CalendarSmallCell from "../../CalendarSmallCell/CalendarSmallCell";
import CalendarStandartCell from "../../CalendarStandartCell/CalendarStandartCell"; import CalendarStandartCell from "../../CalendarStandartCell/CalendarStandartCell";
...@@ -98,13 +98,14 @@ function WeekCalendarBody({ week, hoursInDay, hourFormat, setHourFormat, date, t ...@@ -98,13 +98,14 @@ function WeekCalendarBody({ week, hoursInDay, hourFormat, setHourFormat, date, t
handleClose={() => { handleClose() }} handleClose={() => { handleClose() }}
week={true} week={true}
> >
<MonthCalendarModalContent <CalendarModalTaskContent
title={currentTask.title} title={currentTask.title}
description={currentTask.description} description={currentTask.description}
priority={currentTask.priority} priority={currentTask.priority}
id={currentTask.id} id={currentTask.id}
startHour={currentTask.infoForCell?.startHour} startHour={currentTask.infoForCell?.startHour}
endHour={currentTask.infoForCell?.endHour} endHour={currentTask.infoForCell?.endHour}
project={currentTask.project}
onChangeCurrentTaskHandler={(e) => { onChangeCurrentTaskHandler(e) }} onChangeCurrentTaskHandler={(e) => { onChangeCurrentTaskHandler(e) }}
sendNewTaskHandler={() => { sendNewTaskHandler(); handleClose() }} sendNewTaskHandler={() => { sendNewTaskHandler(); handleClose() }}
deleteTaskHandler={() => { deleteTaskHandler(currentTask.id); handleClose() }} deleteTaskHandler={() => { deleteTaskHandler(currentTask.id); handleClose() }}
......
...@@ -5,7 +5,7 @@ function СustomSelect({ value, onChange, label, variant = 'standard', items, id ...@@ -5,7 +5,7 @@ function СustomSelect({ value, onChange, label, variant = 'standard', items, id
return ( return (
<> <>
<FormControl variant={variant} sx={{ m: 0, minWidth: 120 }}> <FormControl variant={variant} sx={{ m: 0, minWidth: 125 }}>
<InputLabel id={`${id}-select-label`}>{label}</InputLabel> <InputLabel id={`${id}-select-label`}>{label}</InputLabel>
<Select <Select
labelId={`${id}-select-label`} labelId={`${id}-select-label`}
......
...@@ -38,10 +38,12 @@ function MonthCalendar() { ...@@ -38,10 +38,12 @@ function MonthCalendar() {
setUserId(userCalendarId) setUserId(userCalendarId)
dispatch(fetchCalendarTasks(userCalendarId)) dispatch(fetchCalendarTasks(userCalendarId))
dispatch(fetchCurrentCalendarDisplayName(userCalendarId)) dispatch(fetchCurrentCalendarDisplayName(userCalendarId))
dispatch(fetchAllUserProjects())
} else { } else {
setUserId(user.id) setUserId(user.id)
dispatch(fetchCalendarTasks(user.id)) dispatch(fetchCalendarTasks(user.id))
dispatch(fetchCurrentCalendarDisplayName(user.id)) dispatch(fetchCurrentCalendarDisplayName(user.id))
dispatch(fetchAllUserProjects())
} }
}, [userCalendarId, dispatch, user.id]) }, [userCalendarId, dispatch, user.id])
...@@ -145,10 +147,11 @@ function MonthCalendar() { ...@@ -145,10 +147,11 @@ function MonthCalendar() {
startHour: hour, startHour: hour,
endHour: hourDue, endHour: hourDue,
startDay: dayNumber startDay: dayNumber
} },
project: allUserProjects[0].id
} }
setCurrentTask((newTask)) setCurrentTask((newTask))
}, [dateNow.month, dateNow.year, hourFormat]) }, [dateNow.month, dateNow.year, hourFormat, allUserProjects])
const dragTaskHandler = useCallback(async (dayNumber, hour) => { const dragTaskHandler = useCallback(async (dayNumber, hour) => {
const hourDiff = currentTask.infoForCell.endHour - currentTask.infoForCell.startHour const hourDiff = currentTask.infoForCell.endHour - currentTask.infoForCell.startHour
...@@ -294,6 +297,7 @@ function MonthCalendar() { ...@@ -294,6 +297,7 @@ function MonthCalendar() {
createCopyTask={createCopyTask} createCopyTask={createCopyTask}
copyTask={copyTask} copyTask={copyTask}
setCopyTask={setCopyTask} setCopyTask={setCopyTask}
allUserProjects={allUserProjects}
/> />
</> </>
......
...@@ -4,14 +4,17 @@ import { useDispatch, useSelector } from 'react-redux'; ...@@ -4,14 +4,17 @@ import { useDispatch, useSelector } from 'react-redux';
import WeekCalendarBody from '../../components/Calendars/WeekCalendar/WeekCalendarBody/WeekCalendarBody'; import WeekCalendarBody from '../../components/Calendars/WeekCalendar/WeekCalendarBody/WeekCalendarBody';
import WeekCalendarHeader from '../../components/Calendars/WeekCalendar/WeekCalendarHeader/WeekCalendarHeader'; import WeekCalendarHeader from '../../components/Calendars/WeekCalendar/WeekCalendarHeader/WeekCalendarHeader';
import { getWeekInfoString, getWeekFromCurrentDate, dateToISOLikeButLocal } from '../../helpers/CalendarHelpers'; import { getWeekInfoString, getWeekFromCurrentDate, dateToISOLikeButLocal } from '../../helpers/CalendarHelpers';
import { fetchAllUserProjects } from '../../store/actions/projectsActions';
import { addCalendarTask, addCopyCalendarTask, deleteCalendarTask, editCalendarTask, fetchCalendarTasks } from '../../store/actions/tasksActions'; import { addCalendarTask, addCopyCalendarTask, deleteCalendarTask, editCalendarTask, fetchCalendarTasks } from '../../store/actions/tasksActions';
function WeekCalendar() { function WeekCalendar() {
const dispatch = useDispatch(); const dispatch = useDispatch();
const { calendarTasks } = useSelector(state => state.tasks); const { calendarTasks } = useSelector(state => state.tasks);
const [copyTask, setCopyTask] = useState(null) const { allUserProjects } = useSelector(state => state.projects)
const user = useSelector(state => state.users?.user); const user = useSelector(state => state.users?.user);
const [copyTask, setCopyTask] = useState(null)
const [weekGoal, setWeekGoal] = useState('Наладить режим сна') const [weekGoal, setWeekGoal] = useState('Наладить режим сна')
const [weekPriorities, setWeekPriorities] = useState({ priorityOne: 'Один', priorityTwo: 'Два', priorityThree: 'Три' }) const [weekPriorities, setWeekPriorities] = useState({ priorityOne: 'Один', priorityTwo: 'Два', priorityThree: 'Три' })
const [dateNow, setDateNow] = useState({ year: '', month: '', currentDay: '' }) const [dateNow, setDateNow] = useState({ year: '', month: '', currentDay: '' })
...@@ -25,6 +28,7 @@ function WeekCalendar() { ...@@ -25,6 +28,7 @@ function WeekCalendar() {
const currentDay = moment().date() const currentDay = moment().date()
setDateNow({ year: year, month: month, currentDay: currentDay }) setDateNow({ year: year, month: month, currentDay: currentDay })
dispatch(fetchCalendarTasks(user.id)) dispatch(fetchCalendarTasks(user.id))
dispatch(fetchAllUserProjects())
setUserId(user.id) setUserId(user.id)
}, [dispatch, user.id]) }, [dispatch, user.id])
...@@ -122,10 +126,11 @@ function WeekCalendar() { ...@@ -122,10 +126,11 @@ function WeekCalendar() {
endHour: hourDue, endHour: hourDue,
startDay: dayNumber, startDay: dayNumber,
month: month month: month
} },
project: allUserProjects[0]?.id
} }
setCurrentTask((newTask)) setCurrentTask((newTask))
}, [dateNow.year, hourFormat]) }, [dateNow.year, hourFormat, allUserProjects])
const sendNewTaskHandler = useCallback(async () => { const sendNewTaskHandler = useCallback(async () => {
const timeEndHour = currentTask.infoForCell.endHour const timeEndHour = currentTask.infoForCell.endHour
......
import {DELETE_MEMBER_FAILURE, DELETE_MEMBER_REQUEST, DELETE_MEMBER_SUCCESS, DELETE_PROJECT_FAILURE, DELETE_PROJECT_REQUEST, DELETE_PROJECT_SUCCESS, FETCH_ALL_USER_PROJECTS_SUCCESS, FETCH_PROJECTS_ERROR, FETCH_PROJECTS_REQUEST, FETCH_PROJECTS_SUCCESS, FETCH_PROJECT_SUCCESS } from "../actionTypes/projectsActionTypes"; import { DELETE_MEMBER_FAILURE, DELETE_MEMBER_REQUEST, DELETE_MEMBER_SUCCESS, DELETE_PROJECT_FAILURE, DELETE_PROJECT_REQUEST, DELETE_PROJECT_SUCCESS, FETCH_ALL_USER_PROJECTS_SUCCESS, FETCH_PROJECTS_ERROR, FETCH_PROJECTS_REQUEST, FETCH_PROJECTS_SUCCESS, FETCH_PROJECT_SUCCESS } from "../actionTypes/projectsActionTypes";
const initialState = { const initialState = {
allUserProjects: [], allUserProjectsForModalTask: [],
projects: [], allUserProjects: [],
project: "", projects: [],
loading: false, project: "",
error: null loading: false,
}; error: null
};
const projectsReducer = (state = initialState, action) => {
switch (action.type) { const projectsReducer = (state = initialState, action) => {
case FETCH_PROJECTS_REQUEST: switch (action.type) {
return {...state, loading: true}; case FETCH_PROJECTS_REQUEST:
case FETCH_PROJECTS_SUCCESS: return { ...state, loading: true };
return {...state, loading: false, projects: action.projects}; case FETCH_PROJECTS_SUCCESS:
case FETCH_PROJECTS_ERROR: return { ...state, loading: false, projects: action.projects };
return {...state, loading: false, error: action.error}; case FETCH_PROJECTS_ERROR:
case FETCH_PROJECT_SUCCESS: return { ...state, loading: false, error: action.error };
return {...state, loading: false, project: action.project} case FETCH_PROJECT_SUCCESS:
case DELETE_MEMBER_SUCCESS: return { ...state, loading: false, project: action.project }
return {...state, loading: false}; case DELETE_MEMBER_SUCCESS:
case DELETE_MEMBER_REQUEST: return { ...state, loading: false };
return {...state, loading: true}; case DELETE_MEMBER_REQUEST:
case DELETE_MEMBER_FAILURE: return { ...state, loading: true };
return {...state, loading: false, error: action.error}; case DELETE_MEMBER_FAILURE:
case DELETE_PROJECT_SUCCESS: return { ...state, loading: false, error: action.error };
return {...state, loading: false}; case DELETE_PROJECT_SUCCESS:
case DELETE_PROJECT_REQUEST: return { ...state, loading: false };
return {...state, loading: true}; case DELETE_PROJECT_REQUEST:
case DELETE_PROJECT_FAILURE: return { ...state, loading: true };
return {...state, loading: false, error: action.error}; case DELETE_PROJECT_FAILURE:
case FETCH_ALL_USER_PROJECTS_SUCCESS: return { ...state, loading: false, error: action.error };
return {...state, loading: false, allUserProjects: action.projects} case FETCH_ALL_USER_PROJECTS_SUCCESS:
default: const newArr = action.projects.map((project)=>{
return state; return {value: project.id, text: project.title}
} })
}; return { ...state, loading: false, allUserProjects: action.projects, allUserProjectsForModalTask: newArr}
default:
export default projectsReducer; return state;
\ No newline at end of file }
};
export default projectsReducer;
\ No newline at end of file
...@@ -38,6 +38,7 @@ const tasksReduсer = (state = initialState, action) => { ...@@ -38,6 +38,7 @@ const tasksReduсer = (state = initialState, action) => {
for (let copy of task.dateTimeTasks) { for (let copy of task.dateTimeTasks) {
newTasksWithoutInfoForCell.push({ newTasksWithoutInfoForCell.push({
...copy, ...copy,
project: task?.project?.id,
mainTaskId: task.id, mainTaskId: task.id,
executor: task.executor, executor: task.executor,
author: task.author, author: task.author,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment