Commit 6ab13d0f authored by Ermolaev Timur's avatar Ermolaev Timur

Merge branch 'development' of…

Merge branch 'development' of ssh://git.attractor-school.com:30022/apollo64/crm-team-one into task-78-fix/fix_logic_calendar_tasks
parents 923dc0c1 a09aa306
......@@ -24,32 +24,39 @@ export const auth = async(req: Request,res: Response, next:NextFunction):Promise
export const authAuthorOrExecutorOfTask = async(req: Request,res: Response, next:NextFunction):Promise<void | express.Response<Response>>=>{
const token = req.get('Authorization');
const {taskId} = req.body
if(!token) return res.status(401).send({Message:'token not exists'})
req.body={...req.body,executorStatus:false}
req.body={...req.body,authorStatus:false}
const executor = await dataSource
.createQueryBuilder()
.select("user")
.from(User, "user")
.leftJoinAndSelect("user.tasks", "task")
.where("user.token = :token", { token: token })
.getOne();
console.log('executor', executor)
if (executor) {
req.body={...req.body,executorStatus:true}
}
const author = await dataSource
.createQueryBuilder()
.select("user")
.from(User, "user")
.leftJoinAndSelect("user.createdTasks", "task")
.where("user.token = :token", { token: token })
.getOne();
console.log('author', author)
if (author) {
const task = await dataSource
.getRepository(Task)
.findOne({
relations:{
executor:true,
author:true,
},
where:[
{
id:taskId,
executor:{
token:token
}
},
{
id:taskId,
author:{
token:token
}
},
]})
if (!task) return res.status(404).send({message:'task with possible user involved is not found'})
if (task?.author?.token === token ) {
req.body={...req.body,authorStatus:true}
} else if(task?.executor?.token === token) {
req.body={...req.body,executorStatus:true}
} else {
}
if(!author && !executor)return res.status(401).send({Message:'user is not authorized'})
next()
};
......
......@@ -7,7 +7,8 @@ import {
ManyToOne,
OneToOne,
JoinTable,
OneToMany
OneToMany,
JoinColumn
} from 'typeorm';
import {User} from './User';
import {Project} from './Project';
......@@ -28,9 +29,9 @@ import { DateTimeTask } from './DateTimeTask';
priority: priorityType | null;
archive:boolean,
author: User;
executor:User;
project:Project|null;
dateTimeTasks:DateTimeTask[]|null;
executor:User;
}
@Entity({ name: 'Task' })
......@@ -73,8 +74,7 @@ import { DateTimeTask } from './DateTimeTask';
@ManyToOne(() => User, (user: { tasks: Task[]; }) => user.tasks,{eager : true})
author!: User;
@ManyToOne(() =>User, (user: { tasks: Task[]}) => user.tasks,{eager : true,nullable: true, onUpdate:'CASCADE'})
@JoinTable()
@ManyToOne(() =>User, (user: { tasks: Task[]}) => user.tasks,{nullable: true,cascade: true, onUpdate:'CASCADE', eager : true,})
executor!: User;
@ManyToOne(()=>Project,(project:{tasks: Task[]}) => project.tasks,{eager : true,nullable: true,onUpdate:'CASCADE'})
......
......@@ -25,7 +25,7 @@ router.get('/', async(req:Request, res:Response):Promise<Response> => {
/**create new task */
router.post('/', auth, async(req:Request, res:Response):Promise<Response>=>{
const {user,title,description,project,executor, dateTimeDeadLine,priority, dateTimeStart, dateTimeDue} = req.body;
const {user,title,description,project,executor,dateTimeStart,dateTimeDue, dateTimeDeadLine,priority} = req.body;
const newTask = new Task();
newTask.title = title;
newTask.description = description;
......@@ -34,12 +34,12 @@ router.post('/', auth, async(req:Request, res:Response):Promise<Response>=>{
newTask.author= user;
newTask.executor= executor;
newTask.priority = priority;
await newTask.save();
await newTask.save();
const newDateTimeTask = new DateTimeTask();
newDateTimeTask.dateTimeStart = dateTimeStart
newDateTimeTask.dateTimeDue = dateTimeDue
newDateTimeTask.task = newTask
await newDateTimeTask.save()
newDateTimeTask.dateTimeStart = dateTimeStart
newDateTimeTask.dateTimeDue = dateTimeDue
newDateTimeTask.task = newTask
await newDateTimeTask.save()
return res.send({newTask});
})
......@@ -158,7 +158,7 @@ router.delete('/:taskId',async (req: Request, res: Response):Promise<Response>=>
/**change of task by task id */
router.put('/',authAuthorOrExecutorOfTask,async(req:Request, res:Response)=> {
const {authorStatus,executorStatus,taskId,title,description,note, archive,project,dateTimeTaskId,start,due,executor,accomplish,dateTimeDeadLine, dateTimeFactDeadLine,priority} = req.body;
const {authorStatus,executorStatus,taskId,title,description,note, archive,project,dateTimeTaskId,dateTimeStart,dateTimeDue,executor,accomplish,dateTimeDeadLine, dateTimeFactDeadLine,priority} = req.body;
const task = await taskFinderById(taskId)
if (!task) return res.status(404).send({Message:'task not found'})
let dateTimeTask = null;
......@@ -173,6 +173,12 @@ router.put('/',authAuthorOrExecutorOfTask,async(req:Request, res:Response)=> {
dateTimeTask = dateTimeTaskData
}
if (dateTimeTask!==null) {
dateTimeTask.dateTimeStart = dateTimeStart
dateTimeTask.dateTimeDue = dateTimeDue
await dateTimeTask.save()
}
if (authorStatus){
task.title = title
task.description= description
......@@ -182,13 +188,9 @@ router.put('/',authAuthorOrExecutorOfTask,async(req:Request, res:Response)=> {
task.executor=executor
task.priority= priority
}
if(executorStatus && dateTimeTask!==null){
dateTimeTask.dateTimeStart = start
dateTimeTask.dateTimeDue = due
await dateTimeTask.save()
if(executorStatus){
task.note = note
task.dateTimeFactDeadLine= dateTimeFactDeadLine
}
task.accomplish= accomplish
await task.save()
......
......@@ -51,14 +51,6 @@ const App = () => {
<FullProject/>
</ProtectedRoute>
}/>
<Route path={"/projects/add"} element={
<ProtectedRoute
isAllowed={user}
redirectUrl={"/sign-in"}
>
<NewProject/>
</ProtectedRoute>
}/>
<Route path={"/"} element={
<ProtectedRoute
isAllowed={user}
......
......@@ -10,7 +10,7 @@ const WorkerMenu = () => {
const [anchorEl, setAnchorEl] = useState(null);
const open = Boolean(anchorEl);
const user = useSelector(state => state.users.user)
console.log(user)
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
......
.modal{
width: 200px;
height: 200px;
background-color: rgb(180, 243, 243);
display: flex;
margin:10% 20%;
padding: 30px;
word-break: break-all;
transition-duration:0.5s;
flex-direction: column;
padding: 10px;
align-items: center;
position: absolute;
top: 200px;
left: 200px;
width: 300px;
height: 300px;
background-color: white;
border: 2px solid #000;
box-shadow: 24px;
border-radius:5px
}
.modalBox{
display: flex;
......
......@@ -2,64 +2,95 @@ import { Modal, IconButton } from "@mui/material";
import "./TaskModal.css";
import { Done } from "@mui/icons-material";
import Input from "@mui/material/Input";
import TextField from "@mui/material/Input";
const TaskModal = ({handleClose,open,task,onChange,user }) => {
return (
<Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
className={"modal"}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
BackdropProps={{ style: { backgroundColor: 'rgba(255,255,255, 0)' } }}
closeAfterTransition
onClose={handleClose}
open={open}
>
{task?.isEditMode && task.author.id===user.id ? (
<div className="modalBox">
<div className="modal">
<Input
label="название"
color="secondary"
value={task.title}
name="title"
onChange={(e) => onChange(e, task)}
style={{
width: "auto",
fontSize: "12px",
color: "white",
fontWeight: "600",
height: "40px",
fontWeight: "600",
width:"280px",
margin:"10px",
padding:"5px",
border: '2px solid #D3D3D3',
borderRadius:"5px"
}}
/>
<Input
<TextField
label="описание"
value={task.description}
name="description"
onChange={(e) => onChange(e, task)}
style={{ width: "auto", fontSize: "12px", color: "white" }}
/>
<IconButton aria-label="done" onClick={handleClose}>
multiline={true}
sx={{
fontWeight: "400",
width:"280px",
margin:"10px",
padding:"5px",
border: '2px solid #D3D3D3',
borderRadius:"5px",
height:"300px",
whiteSpace:"normal"
}}
/>
<IconButton aria-label="done" onClick={handleClose}
sx={{margingBottom:"5px",marginTop:"auto"}}>
<Done />
</IconButton>
</div>
) : (
<div className="modalBox">
<div className="modal">
{task && task.title && (
<div
style={{
width: "200px",
height: "200px",
color: "white",
fontWeight: "600",
height: "40px",
fontWeight: "600",
width:"280px",
margin:"10px",
padding:"5px",
border: '2px solid #D3D3D3',
borderRadius:"5px"
}}
>
{task.title}
</div>
)}
{task && task.description && (
<div style={{ width: "200px", height: "200px", color: "white" }}>
<div
style={{margin:"10px",
border: '2px solid #D3D3D3',
borderRadius:"5px",
width:"280px",
height: "200px",
margin:"10px",
padding:"5px",
}}>
{task.description}
</div>
)}
<IconButton
sx={{ marginLeft: 0, color: "white" }}
aria-label="close"
onClick={handleClose}
sx={{margingBottom:"5px",marginTop:"auto"}}
>
X
</IconButton>
......
import {Button, Grid} from "@mui/material";
import {Box, Button, Grid, Modal} from "@mui/material";
import {useState} from "react";
import { useSelector } from "react-redux";
import FormElement from "../UI/Form/FormElement/FormElement";
import {Typography} from "@mui/material";
const style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 400,
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
};
const ProjectForm = ({onSubmit}) => {
const users = useSelector(state => state.users)
console.log(users)
const [open, setOpen] = useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
const [state, setState] = useState({
title: "",
color: ""
title: ""
});
const submitFormHandler = (e) => {
e.preventDefault();
let project = {title: state.title, color: state.color}
let project = {title: state.title}
console.log(project);
onSubmit(project);
};
const inputChangeHandler = (e) => {
......@@ -26,31 +42,44 @@ const ProjectForm = ({onSubmit}) => {
});
};
return <form onSubmit={submitFormHandler}>
return (
<div >
<Button onClick={handleOpen} >Add project</Button>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
onSubmit={submitFormHandler}
>
<Box sx={style}>
<form >
<Grid container direction="column" spacing={2}>
<Typography variant="h4">New project</Typography>
<FormElement
onChange={inputChangeHandler}
name={"title"}
label={"Title"}
state={state}
/>
<FormElement
onChange={inputChangeHandler}
name={"color"}
label={"Color"}
state={state}
/>
<Grid item>
<Button
type="submit"
color="primary"
variant="contained"
>
Create
</Button>
</Grid>
</Grid>
</form>
</Box>
</Modal>
</div>
);
};
export default ProjectForm;
\ No newline at end of file
......@@ -34,7 +34,7 @@ const FullProject = () => {
</strong>
<strong>
<br></br>
Админ проекта: {project?.project?.members}
{/* Админ проекта: {project?.project?.members} */}
</strong>
<strong>
<br></br>
......
......@@ -388,10 +388,7 @@ console.log(tasks)
.format("hh:mm A"),
user:user
}}>
{/* <span>"время завершения"+ {moment(task.dateTimeDue)
.utc()
.format("hh:mm A")}</span> */}
</CustomTableCell>
</CustomTableCell>
</>
)}
......@@ -475,7 +472,8 @@ console.log(tasks)
)}
</Tooltip>
</TableCell>
<TableCell>
{task.author.id===user.id ?
(<TableCell>
<Tooltip title="Удалить">
<IconButton
onClick={(id) => {
......@@ -485,7 +483,8 @@ console.log(tasks)
<DeleteIcon />
</IconButton>
</Tooltip>
</TableCell>
</TableCell>):null}
</TableRow>
);
})}
......
import {useNavigate} from "react-router-dom";
import {useDispatch, useSelector} from "react-redux";
import {Typography} from "@mui/material";
import { useEffect } from "react";
import ProjectForm from "../../components/ProjectForm/ProjectForm";
import { createProject, fetchProjects } from "../../store/actions/projectsActions";
......@@ -9,8 +9,12 @@ const NewProject = () => {
const dispatch = useDispatch();
const projects = useSelector(state => state.projects.projects);
const navigate = useNavigate();
let lastProject = projects.projects[projects.projects.length - 1];
const onSubmit = async (projectData) => {
await dispatch(createProject(projectData, navigate));
console.log(projectData)
console.log(lastProject)
};
useEffect(()=> {
......@@ -19,7 +23,6 @@ const NewProject = () => {
return (
<>
<Typography variant="h2">New project</Typography>
<ProjectForm projects={projects} onSubmit={onSubmit} />
</>
);
......
......@@ -6,6 +6,7 @@ import Loader from "../../components/UI/Loader/Loader";
import HasAccess from "../../components/UI/HasAccess/HasAccess";
import { fetchProjects } from "../../store/actions/projectsActions";
import ProjectsList from "../../components/ProjectsList/ProjectsList";
import NewProject from "../NewProject/NewProject";
const Projects = () => {
const dispatch = useDispatch();
......@@ -34,9 +35,7 @@ const Projects = () => {
</Grid>
<HasAccess roles={["superuser", "admin", "user"]} >
<Grid item>
<Button component={Link} to="/projects/add">
Add project
</Button>
<NewProject/>
</Grid>
</HasAccess>
</Grid>
......
......@@ -46,9 +46,10 @@ export const fetchProject = (id) => {
export const createProject = (projectData, navigate) => {
return async (dispatch) => {
try {
await axios.post("/projects", projectData);
const response = await axios.post("/projects", projectData);
dispatch(createProjectSuccess());
navigate("/");
console.log(response.data)
navigate("/projects/" + response.data.project.id)
dispatch(showNotification("Проект успешно создан"))
} catch (e) {
console.log(e);
......
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