Commit 0fe75260 authored by Ermolaev Timur's avatar Ermolaev Timur

#103 Реализовал возможность перехода в чужой календарь и возвращения назад

parent 61d26665
......@@ -52,7 +52,6 @@ router.get('/user/:userId', async (req: Request, res: Response):Promise<Response
.find({
relations:{
executor:true,
author:true,
},
where:[
{
......@@ -60,11 +59,6 @@ router.get('/user/:userId', async (req: Request, res: Response):Promise<Response
id:userId
}
},
{
author:{
id:userId
}
},
]
})
return res.send({tasks})
......
import {Routes, Route, Outlet, Navigate, BrowserRouter} from "react-router-dom";
import {Container} from "@mui/material";
import {useSelector} from "react-redux";
import { Routes, Route, Outlet, Navigate, BrowserRouter } from "react-router-dom";
import { Container } from "@mui/material";
import { useSelector } from "react-redux";
import AppToolbar from "./components/UI/AppToolBar/AppToolBar";
import MyTasks from './containers/MyTasks/MyTasks';
import Login from './containers/Login/Login';
......@@ -12,116 +12,134 @@ import FullProject from "./containers/FullProject/FullProject";
import NewProject from "./containers/NewProject/NewProject";
import WeekCalendar from "./containers/WeekCalendar/WeekCalendar";
const ProtectedRoute = ({isAllowed, roles, redirectUrl, children}) => {
const ProtectedRoute = ({ isAllowed, roles, redirectUrl, children }) => {
const user = useSelector(state => state.users?.user);
if (!isAllowed && !roles?.includes(user?.role)) {
return <Navigate to={redirectUrl} />
return <Navigate to={redirectUrl} />
}
return children || <Outlet />;
};
const App = () => {
const user = useSelector(state => state.users?.user);
return (
const user = useSelector(state => state.users?.user);
return (
<BrowserRouter>
<Routes>
<Route element={
<>
<AppToolbar/>
<main>
<Container maxWidth={false} sx={{maxWidth:'2500px'}}>
<Outlet/>
</Container>
</main>
</>
}>
<Route path={"/projects"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<Projects/>
</ProtectedRoute>
}/>
<Route path={"/projects/:id"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<FullProject/>
</ProtectedRoute>
}/>
<Route path={"/"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<WeekCalendar/>
</ProtectedRoute>
}/>
<Route element={
<>
<AppToolbar />
<main>
<Container maxWidth={false} sx={{ maxWidth: '2500px' }}>
<Outlet />
</Container>
</main>
</>
}>
<Route path={"/projects"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<Projects />
</ProtectedRoute>
} />
<Route path={"/projects/:id"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<FullProject />
</ProtectedRoute>
} />
<Route path={"/"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<WeekCalendar />
</ProtectedRoute>
} />
<Route path={"/week"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<WeekCalendar />
</ProtectedRoute>
} />
<Route path={"/week/:id"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<WeekCalendar />
</ProtectedRoute>
} />
<Route path={"/week"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<WeekCalendar/>
</ProtectedRoute>
}/>
<Route path={"/month"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<MonthCalendar></MonthCalendar>
</ProtectedRoute>
} />
<Route path={"/month"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<MonthCalendar></MonthCalendar>
</ProtectedRoute>
}/>
<Route path={"/month/:id"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<MonthCalendar></MonthCalendar>
</ProtectedRoute>
} />
<Route path={"/my-tasks"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<MyTasks/>
</ProtectedRoute>
}/>
<Route path={"/my-tasks"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<MyTasks />
</ProtectedRoute>
} />
<Route path={"/profile/:id"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<h1>profile page</h1>
</ProtectedRoute>
}/>
<Route path={"/profile/:id"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<h1>profile page</h1>
</ProtectedRoute>
} />
<Route path={"/workers-tasks"} element={
<ProtectedRoute
roles={["superuser"]}
redirectUrl={"/"}
>
<h1>workers tasks page</h1>
</ProtectedRoute>
}/>
<Route path={"/workers-tasks"} element={
<ProtectedRoute
roles={["superuser"]}
redirectUrl={"/"}
>
<h1>workers tasks page</h1>
</ProtectedRoute>
} />
<Route path={"/sign-up"} element={
<ProtectedRoute
roles={["superuser"]}
redirectUrl={"/"}
>
<Register/>
</ProtectedRoute>
}/>
<Route path={"/sign-up"} element={
<ProtectedRoute
roles={["superuser"]}
redirectUrl={"/"}
>
<Register />
</ProtectedRoute>
} />
<Route path={"/sign-in"} element={<Login/>}/>
<Route path={"/forgottenpassword"} element={<ForgottenPassword/>}/>
<Route path='*' element={<h1>404</h1>}/>
</Route>
<Route path={"/sign-in"} element={<Login />} />
<Route path={"/forgottenpassword"} element={<ForgottenPassword />} />
<Route path='*' element={<h1>404</h1>} />
</Route>
</Routes>
</BrowserRouter>
)
)
};
export default App;
......
import { Autocomplete, TextField } from "@mui/material";
import { Autocomplete, Button, TextField } from "@mui/material";
import { memo } from "react";
function CalendarModalWorkerContent({ allUserProjects, onChangeProjectHandler, workerInfo }) {
console.log(workerInfo)
function CalendarModalWorkerContent({ allUserProjects, onChangeProjectHandler, onChangeWorkerHandler, workerInfo, workers, handleClose, onChangeCalendarUser}) {
return (<>
<Autocomplete
id="choose-project"
......@@ -11,30 +10,36 @@ function CalendarModalWorkerContent({ allUserProjects, onChangeProjectHandler, w
options={allUserProjects}
getOptionLabel={(item) => item.title || ""}
onChange={onChangeProjectHandler}
name={"userId"}
name={"project"}
value={workerInfo.project}
renderInput={(params) => <TextField
style={{ margin: "5px" }}
style={{ marginBottom: "15px" }}
label={"Проект"}
state={workerInfo.project}
{...params} />}
/>
{workerInfo.project ?
<Autocomplete
id="choose-worker"
freeSolo
options={allUserProjects}
getOptionLabel={(item) => item.title || ""}
onChange={(e, value)=>{ onChangeProjectHandler(e, value)}}
name={"userId"}
value={workerInfo.project}
renderInput={(params) => <TextField
style={{ margin: "5px" }}
label={"Проект"}
state={workerInfo.project}
{...params} />}
/>
<>
<Autocomplete
id="choose-worker"
freeSolo
options={workers}
getOptionLabel={(item) => item?.user?.displayName || ""}
onChange={(e, value) => { onChangeWorkerHandler(e, value) }}
name={"worker"}
value={workerInfo.worker}
renderInput={(params) => <TextField
label={"Участник"}
state={workerInfo.worker}
{...params} />}
/>
<div style={{ display: 'flex', justifyContent: 'space-between', margin: '10px 0' }}>
<Button onClick={()=>{onChangeCalendarUser()}} >Выбрать</Button>
<Button onClick={() => handleClose()}>Отмена</Button>
</div>
</>
: null}
</>);
}
......
......@@ -2,7 +2,7 @@ import { AppBar, Button, Toolbar, Typography } from '@mui/material';
import { Box } from '@mui/system';
import MonthAndYearInfo from './MonthAndYearInfo/MonthAndYearInfo';
function MonthCalendarHeader({ currentMonthString, decrementMonth, incrementMonth, year, handleOpen, currentCalendarDisplayName }) {
function MonthCalendarHeader({ currentMonthString, decrementMonth, incrementMonth, year, handleOpen, currentCalendarDisplayName, user, userId}) {
return (
<>
......@@ -27,7 +27,7 @@ function MonthCalendarHeader({ currentMonthString, decrementMonth, incrementMont
size="large"
sx={{ marginLeft: 'auto' }}
>
Выбрать сотрудника
{user.id === userId ? 'Выбрать сотрудника' : 'Вернуться назад'}
</Button>
</Toolbar>
</AppBar>
......
......@@ -13,7 +13,7 @@ const style = {
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
p: 2
};
export default function DefaultModal({ modal, handleClose, children }) {
......
import { useEffect, useCallback, useState, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useParams } from 'react-router-dom';
import { useNavigate, useParams } from 'react-router-dom';
import CalendarModalWorkerContent from '../../components/Calendars/CalendarModalWorkerContent/CalendarModalWorkerContent';
import MonthCalendarBody from '../../components/Calendars/MonthCalendar/MonthCalendarBody/MonthCalendarBody';
import MonthCalendarHeader from '../../components/Calendars/MonthCalendar/MonthCalendarHeader/MonthCalendarHeader';
import DefaultModal from '../../components/UI/DefaultModal/DefaultModal';
import { dateToISOLikeButLocal, getCurrentMonthString, getDaysInMonth } from '../../helpers/CalendarHelpers';
import { fetchAllUserProjects } from '../../store/actions/projectsActions';
import { fetchAllUserProjects, fetchProject } from '../../store/actions/projectsActions';
import { addCalendarTask, addCopyCalendarTask, deleteCalendarTask, editCalendarTask, fetchCalendarTasks } from '../../store/actions/tasksActions';
import { fetchCurrentCalendarDisplayName } from '../../store/actions/usersActions';
function MonthCalendar() {
const dispatch = useDispatch();
const navigate = useNavigate()
const { calendarTasks } = useSelector(state => state.tasks);
const { user, currentCalendarDisplayName } = useSelector(state => state.users);
const { allUserProjects } = useSelector(state => state.projects)
const { allUserProjects, project } = useSelector(state => state.projects)
const params = useParams()
const [hourFormat, setHourFormat] = useState(false);
const [dateNow, setDateNow] = useState({ month: '', year: '' })
const [workerInfo, setWorkerInfo] = useState({project: '', worker: ''});
const [workerInfo, setWorkerInfo] = useState({ project: '', worker: '' });
const [currentTask, setCurrentTask] = useState({ title: '', description: '', priority: null, infoForCell: { startHour: null, endHour: null } })
const [copyTask, setCopyTask] = useState(null)
const [cellSizes, setCellSizes] = useState({})
......@@ -42,6 +43,11 @@ function MonthCalendar() {
}
}, [dispatch])
useEffect(() => {
if (workerInfo.project) {
dispatch(fetchProject(workerInfo.project.id))
}
}, [workerInfo.project])
const hoursInDay = useMemo(() => {
let arr
......@@ -67,10 +73,11 @@ function MonthCalendar() {
}, [dateNow.month])
const onChangeProjectHandler = useCallback((e, value) => {
setWorkerInfo((prevState)=>{return {...prevState, project: value}});
setWorkerInfo((prevState) => { return { ...prevState, project: value } });
}, []);
const onChangeWorkerHandler = useCallback((e, value) => {
setWorkerInfo((prevState)=>{return {...prevState, worker: value}});
setWorkerInfo((prevState) => { return { ...prevState, worker: value } });
}, []);
const incrementMonth = useCallback(() => {
......@@ -182,7 +189,8 @@ function MonthCalendar() {
...currentTask,
dateTimeStart: start,
dateTimeDue: due,
executor: user,
executor: userId,
author: user.id,
dateTimeDeadLine: due,
}
delete newTask.infoForCell
......@@ -190,6 +198,7 @@ function MonthCalendar() {
await dispatch(addCalendarTask(newTask, userId))
}
}
console.log(userId)
const createCopyTask = async (dayNumber, hour) => {
const hourDiff = copyTask.infoForCell.endHour - copyTask.infoForCell.startHour
......@@ -219,10 +228,26 @@ function MonthCalendar() {
const handleClose = () => {
setModal(false)
setWorkerInfo({ project: '', worker: '' })
}
const handleOpen = async () => {
await dispatch(fetchAllUserProjects())
setModal(true)
if (user.id === userId) {
await dispatch(fetchAllUserProjects())
setModal(true)
} else {
navigate("/month")
setWorkerInfo({ project: '', worker: '' })
setUserId(user.id)
dispatch(fetchCalendarTasks(user.id))
dispatch(fetchCurrentCalendarDisplayName(user.id))
}
}
const onChangeCalendarUser = () => {
navigate(`/month/${workerInfo.worker.user.id}`)
setModal(false)
setUserId(workerInfo.worker.user.id)
dispatch(fetchCalendarTasks(workerInfo.worker.user.id))
dispatch(fetchCurrentCalendarDisplayName(workerInfo.worker.user.id))
}
return (
......@@ -234,8 +259,11 @@ function MonthCalendar() {
<CalendarModalWorkerContent
workerInfo={workerInfo}
allUserProjects={allUserProjects}
workers={project?.project?.members}
onChangeProjectHandler={onChangeProjectHandler}
onChangeWorkerHandler={onChangeWorkerHandler}
handleClose={handleClose}
onChangeCalendarUser={onChangeCalendarUser}
/>
</DefaultModal>
......@@ -246,6 +274,8 @@ function MonthCalendar() {
incrementMonth={incrementMonth}
handleOpen={handleOpen}
currentCalendarDisplayName={currentCalendarDisplayName}
user={user}
userId={userId}
/>
<MonthCalendarBody
month={dateNow.month}
......
......@@ -53,7 +53,7 @@ export const fetchProjects = () => {
dispatch(fetchProjectsRequest());
try {
const response = await axios.get("/projects");
dispatch(fetchProjectsSuccess(response.data));
dispatch(fetchProjectsSuccess(response.data));
} catch(e) {
dispatch(fetchProjectsError(e));
}
......
......@@ -141,8 +141,7 @@ export const editCalendarTask = (task, taskId, userId) => {
return async (dispatch) => {
dispatch(editTaskRequest());
try {
const response = await axios.put(`/copy-tasks/change-copy/${taskId}`, task);
console.log(response.data)
await axios.put(`/copy-tasks/change-copy/${taskId}`, task);
dispatch(editTaskSuccess())
dispatch(fetchCalendarTasks(userId))
} catch (error) {
......
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