Commit fd84e490 authored by Ermolaev Timur's avatar Ermolaev Timur

#141 реализовал драг энд дроп

parent c3e7626b
......@@ -173,6 +173,7 @@ router.delete('/remove-user/:userId', authAdminProject,async (req: Request, res:
router.put('/change-project-role/:userId',authAdminProject, async (req: Request, res: Response):Promise<Response|void> =>{
const {userId}= req.params
const {projectId, newRoleProject} =req.body
const member = await dataSource
.createQueryBuilder()
.select("member")
......@@ -191,6 +192,7 @@ router.put('/change-project-role/:userId',authAdminProject, async (req: Request
return res.send({message:"failed to change role"})
}
return res.send({message:"User's new role ", newRoleProject})
})
export default router;
......@@ -2,6 +2,7 @@ import { Box, Typography } from "@mui/material";
import moment from "moment";
import { memo } from "react";
import PersonAddIcon from '@mui/icons-material/PersonAdd';
import ArrowIncrementButton from "../../UI/ArrowIncrementButton/ArrowIncrementButton";
const style = {
display: 'flex',
......@@ -16,7 +17,7 @@ const styleText = {
}
const ProjectInfo = ({ project, handleOpen, currentRoleInProject }) => {
const ProjectInfo = ({ project, handleOpen, currentRoleInProject,onClickTasksHandler }) => {
return (
<Box sx={style} justifyContent={'space-between'}>
<Typography variant="h2">Проект - {project?.title} </Typography>
......@@ -33,7 +34,7 @@ const ProjectInfo = ({ project, handleOpen, currentRoleInProject }) => {
Роль в проекте: {currentRoleInProject}
</Typography>
<Typography variant="body1" sx={styleText}>
Задачи:
Задачи: <ArrowIncrementButton onClick={()=>{onClickTasksHandler()}}/>
</Typography>
{currentRoleInProject === 'admin' ?
<Typography variant="body1" sx={styleText}>
......
......@@ -5,7 +5,7 @@ import { memo } from "react";
const ColumnTitle = ({ text }) => {
return <>
<Typography variant="h4" textAlign={'center'} sx={{ marginBottom: '20px' }}>
<Typography variant="h4" textAlign={'center'} sx={{ height: '10%' }}>
{text}
</Typography>
</>
......
import { Box } from "@mui/material";
import { memo } from "react";
import { memo} from "react";
import ColumnTitle from "./ColumnTitle/ColumnTitle";
import UsersList from "./UsersList/UserList";
......@@ -13,9 +13,13 @@ const styleColumn = {
}
const ProjectUsersColumn = ({ role, members, deleteMemberHandler, currentRoleInProject }) => {
const ProjectUsersColumn = ({ role, members, deleteMemberHandler, currentRoleInProject, dragMemberToNewRole, setCurrentMember }) => {
return (
<Box sx={styleColumn}>
<Box
sx={styleColumn}
>
<ColumnTitle text={role.text} />
<UsersList
......@@ -23,6 +27,8 @@ const ProjectUsersColumn = ({ role, members, deleteMemberHandler, currentRoleInP
members={members}
deleteMemberHandler={deleteMemberHandler}
currentRoleInProject={currentRoleInProject}
dragMemberToNewRole={dragMemberToNewRole}
setCurrentMember={setCurrentMember}
>
</UsersList>
</Box>
......
......@@ -13,10 +13,40 @@ const style = {
alignItems: 'center'
}
const ProjectMembersItem = ({ user, deleteMemberHandler, currentRoleInProject }) => {
const ProjectMembersItem = ({ user, deleteMemberHandler, currentRoleInProject, dragMemberToNewRole, setCurrentMember, role }) => {
const userId = useSelector(state => state.users.user.id);
const dragStartHandler = (e) => {
setCurrentMember(user)
}
const dragEndHandler = (e) => {
setCurrentMember(null)
}
const dragOverHandler = (e) => {
e.preventDefault();
}
const dropHandler = (e) => {
e.preventDefault();
dragMemberToNewRole(role)
}
const dragLeaveHandler = (e) => {
e.preventDefault();
}
return <>
<Grid sx={style}>
<Grid sx={style}
draggable={user.id !== userId ? true : false}
onDragStart={(e) => { dragStartHandler(e) }}
onDragEnd={(e) => { dragEndHandler(e) }}
onDrop={(e) => { dropHandler(e) }}
onDragOver={(e) => { dragOverHandler(e) }}
onDragLeave={(e) => { dragLeaveHandler(e) }}
>
{user?.displayName}
{currentRoleInProject === 'admin' && user.id !== userId ?
<DeleteIcon
......
import { Box } from "@mui/material";
import { memo } from "react";
import { memo, useCallback } from "react";
import UserItem from "./UserItem/UserItem";
const styleList = {
......@@ -7,11 +7,35 @@ const styleList = {
gap: '10px',
flexDirection: 'column',
alignItems: 'center',
height: '90%',
}
const UsersList = ({ role, members, deleteMemberHandler, currentRoleInProject }) => {
const UsersList = ({ role, members, deleteMemberHandler, currentRoleInProject, dragMemberToNewRole, setCurrentMember }) => {
const dropHandler = (e) => {
e.preventDefault();
e.target.style.background = null
setCurrentMember(null)
dragMemberToNewRole(role)
}
const dragOverHandler = useCallback((e) => {
e.preventDefault();
e.target.style.background = '#d6d2d2'
}, [])
const dragLeaveHandler = useCallback((e) => {
e.preventDefault();
e.target.style.background = null
}, [])
return (
<Box sx={styleList}>
<Box
sx={styleList}
onDrop={(e) => { dropHandler(e) }}
onDragOver={(e) => { dragOverHandler(e) }}
onDragLeave={(e) => { dragLeaveHandler(e) }}
>
{members.map((member) => {
if (member.roleProject === role.value) {
return (
......@@ -19,7 +43,10 @@ const UsersList = ({ role, members, deleteMemberHandler, currentRoleInProject })
key={member.id}
user={member?.user}
deleteMemberHandler={() => { deleteMemberHandler(member?.user?.id) }}
role={role.value}
currentRoleInProject={currentRoleInProject}
dragMemberToNewRole={dragMemberToNewRole}
setCurrentMember={setCurrentMember}
/>
)
} else {
......
......@@ -13,7 +13,7 @@ const style = {
}
const ProjectUsersColumnsWrapper = ({ members, deleteMemberHandler, currentRoleInProject }) => {
const ProjectUsersColumnsWrapper = ({ members, deleteMemberHandler, currentRoleInProject, dragMemberToNewRole, setCurrentMember}) => {
return (
<Box sx={style} justifyContent={'space-between'}>
{projectRoles.map((role, i) => {
......@@ -24,6 +24,8 @@ const ProjectUsersColumnsWrapper = ({ members, deleteMemberHandler, currentRoleI
members={members}
deleteMemberHandler={deleteMemberHandler}
currentRoleInProject={currentRoleInProject}
dragMemberToNewRole={dragMemberToNewRole}
setCurrentMember={setCurrentMember}
/>
)
})}
......
import { Grid } from "@mui/material";
import { useParams } from "react-router-dom";
import { useNavigate, useParams } from "react-router-dom";
import { useSelector, useDispatch } from "react-redux";
import { useCallback, useEffect, useMemo, useState } from "react";
import { createMember, deleteMember, fetchProject } from "../../store/actions/projectsActions";
import { fetchUsers, fetchUsersAllFields } from "../../store/actions/usersActions";
import { changeMemberRole, createMember, deleteMember, fetchProject } from "../../store/actions/projectsActions";
import { fetchUsers } from "../../store/actions/usersActions";
import ProjectUsersColumnsWrapper from "../../components/ProjectComponents/ProjectUsersColumnsWrapper/ProjectUsersColumnsWrapper";
import ProjectInfo from "../../components/ProjectComponents/ProjectInfo/ProjectInfo";
import DefaultModal from "../../components/UI/DefaultModal/DefaultModal"
......@@ -16,10 +16,12 @@ const FullProject = () => {
const { project } = useSelector(state => state.projects);
const [modal, setModal] = useState(false)
const [newMember, setNewMember] = useState(null)
const [currentMember, setCurrentMember] = useState(null)
const { user, users } = useSelector(state => state.users);
const dispatch = useDispatch();
const params = useParams()
const navigate = useNavigate()
useEffect(() => {
dispatch(fetchProject(params.id))
......@@ -30,10 +32,10 @@ const FullProject = () => {
return project?.project?.members || []
}, [project])
const currentRoleInProject = useMemo(()=>{
const currentRoleInProject = useMemo(() => {
return members.find((member) => member.user.id === user.id)?.roleProject
}, [members, user.id])
const onChangeRoleHandler = useCallback((e, value) => {
setNewMember((prevState) => { return { ...prevState, roleProject: value?.value } });
}, []);
......@@ -51,16 +53,26 @@ const FullProject = () => {
setNewMember(null)
}, [])
const createNewMemberHandler = useCallback(()=>{
dispatch(createMember({...newMember, projectId: project?.project?.id}))
const createNewMemberHandler = useCallback(() => {
dispatch(createMember({ ...newMember, projectId: project?.project?.id }))
setModal(false)
setNewMember(null)
}, [dispatch, newMember, project?.project?.id])
const deleteMemberHandler = useCallback((id)=>{
const dragMemberToNewRole = useCallback((role) => {
if (currentMember?.id) {
dispatch(changeMemberRole(currentMember?.id, { newRoleProject: role?.value, projectId: project?.project?.id }))
}
}, [currentMember, dispatch, project?.project?.id])
const deleteMemberHandler = useCallback((id) => {
dispatch(deleteMember(id, project?.project?.id))
}, [dispatch, project?.project?.id])
const onClickTasksHandler = useCallback((id) => {
navigate('/workers-tasks')
}, [navigate])
return <>
<Grid>
......@@ -68,12 +80,15 @@ const FullProject = () => {
project={project.project}
handleOpen={handleOpen}
currentRoleInProject={currentRoleInProject}
onClickTasksHandler={onClickTasksHandler}
/>
<ProjectUsersColumnsWrapper
members={members}
deleteMemberHandler={deleteMemberHandler}
currentRoleInProject={currentRoleInProject}
dragMemberToNewRole={dragMemberToNewRole}
setCurrentMember={setCurrentMember}
/>
<DefaultModal
......
......@@ -15,4 +15,8 @@ export const FETCH_ALL_USER_PROJECTS_SUCCESS = "FETCH_ALL_USER_PROJECTS_SUCCESS"
export const DELETE_PROJECT_REQUEST = "DELETE_PROJECT_REQUEST";
export const DELETE_PROJECT_SUCCESS = "DELETE_PROJECT_SUCCESS";
export const DELETE_PROJECT_FAILURE = "DELETE_PROJECT_FAILURE";
\ No newline at end of file
export const DELETE_PROJECT_FAILURE = "DELETE_PROJECT_FAILURE";
export const CHANGE_MEMBER_ROLE_REQUEST = "CHANGE_MEMBER_ROLE_REQUEST";
export const CHANGE_MEMBER_ROLE_SUCCESS = "CHANGE_MEMBER_ROLE_SUCCESS";
export const CHANGE_MEMBER_ROLE_FAILURE = "CHANGE_MEMBER_ROLE_FAILURE";
\ No newline at end of file
import axios from "../../axiosPlanner";
import { CREATE_MEMBER_SUCCESS, CREATE_PROJECT_SUCCESS, 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 { CHANGE_MEMBER_ROLE_FAILURE, CHANGE_MEMBER_ROLE_REQUEST, CHANGE_MEMBER_ROLE_SUCCESS, CREATE_MEMBER_SUCCESS, CREATE_PROJECT_SUCCESS, 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 { showNotification } from "./commonActions";
const fetchProjectsRequest = () => {
......@@ -141,3 +141,29 @@ export const fetchAllUserProjects = () => {
}
}
const changeMemberRoleFailure = (error) => {
return { type: CHANGE_MEMBER_ROLE_FAILURE, error }
};
const changeMemberRoleRequest = () => {
return { type: CHANGE_MEMBER_ROLE_REQUEST }
};
const changeMemberRoleSuccess = () => {
return { type: CHANGE_MEMBER_ROLE_SUCCESS }
};
export const changeMemberRole = (userId, data) => {
return async (dispatch) => {
dispatch(changeMemberRoleSuccess());
try {
const response = await axios.put(`/projects/change-project-role/${userId}`, data);
console.log(response.data)
dispatch(changeMemberRoleRequest());
await dispatch(fetchProject(data?.projectId))
} catch (e) {
dispatch(changeMemberRoleFailure(e));
}
}
}
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 { CHANGE_MEMBER_ROLE_FAILURE, CHANGE_MEMBER_ROLE_REQUEST, CHANGE_MEMBER_ROLE_SUCCESS, 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 = {
allUserProjectsForModalTask: [],
......@@ -32,10 +32,16 @@ const projectsReducer = (state = initialState, action) => {
case DELETE_PROJECT_FAILURE:
return { ...state, loading: false, error: action.error };
case FETCH_ALL_USER_PROJECTS_SUCCESS:
const newArr = action.projects.map((project)=>{
return {value: project.id, text: project.title}
const newArr = action.projects.map((project) => {
return { value: project.id, text: project.title }
})
return { ...state, loading: false, allUserProjects: action.projects, allUserProjectsForModalTask: newArr}
return { ...state, loading: false, allUserProjects: action.projects, allUserProjectsForModalTask: newArr }
case CHANGE_MEMBER_ROLE_SUCCESS:
return { ...state, loading: false };
case CHANGE_MEMBER_ROLE_REQUEST:
return { ...state, loading: true };
case CHANGE_MEMBER_ROLE_FAILURE:
return { ...state, loading: false, error: action.error };
default:
return state;
}
......
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