Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
planner-team-one
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
21
Issues
21
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Евгений Положенцев
planner-team-one
Commits
fec54d89
Commit
fec54d89
authored
Dec 07, 2022
by
Ibadullina Inabat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
реализовано добавление участника в проект
parent
5d1dedbf
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
270 additions
and
52 deletions
+270
-52
projects.ts
planner-api/src/routers/projects.ts
+2
-1
MemberForm.js
planner-front/src/components/MemberForm/MemberForm.js
+137
-0
ProjectForm.js
planner-front/src/components/ProjectForm/ProjectForm.js
+3
-3
ProjectItem.js
planner-front/src/components/ProjectItem/ProjectItem.js
+3
-3
ProjectMembersItem.js
...t/src/components/ProjectMembersItem/ProjectMembersItem.js
+37
-23
ProjectMembersList.js
...t/src/components/ProjectMembersList/ProjectMembersList.js
+9
-7
ProjectsList.js
planner-front/src/components/ProjectsList/ProjectsList.js
+2
-1
FormElement.js
...r-front/src/components/UI/Form/FormElement/FormElement.js
+2
-1
FullProject.js
planner-front/src/containers/FullProject/FullProject.js
+10
-5
NewMember.js
planner-front/src/containers/NewMember/NewMember.js
+32
-0
NewProject.js
planner-front/src/containers/NewProject/NewProject.js
+0
-1
Projects.js
planner-front/src/containers/Projects/Projects.js
+3
-2
projectsActionTypes.js
planner-front/src/store/actionTypes/projectsActionTypes.js
+3
-0
projectsActions.js
planner-front/src/store/actions/projectsActions.js
+27
-5
No files found.
planner-api/src/routers/projects.ts
View file @
fec54d89
...
...
@@ -121,6 +121,7 @@ router.get('/user/:userId', async (req : Request, res : Response): Promise<Respo
router
.
post
(
'/add-user/'
,
async
(
req
:
Request
,
res
:
Response
):
Promise
<
Response
>=>
{
const
{
userId
,
projectId
,
roleProject
}
=
req
.
body
;
console
.
log
(
"req body"
+
req
.
body
)
const
newMember
:
Member
=
new
Member
();
try
{
newMember
.
user
=
userId
;
...
...
planner-front/src/components/MemberForm/MemberForm.js
0 → 100644
View file @
fec54d89
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"
;
import
TextField
from
'@mui/material/TextField'
;
import
Stack
from
'@mui/material/Stack'
;
import
Autocomplete
from
'@mui/material/Autocomplete'
;
import
{
useParams
}
from
"react-router-dom"
;
import
PersonAddIcon
from
'@mui/icons-material/PersonAdd'
;
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
MemberForm
=
({
onSubmit
})
=>
{
const
users
=
useSelector
(
state
=>
state
.
users
.
users
)
const
[
role
,
setRole
]
=
useState
([{
role
:
"user"
},
{
role
:
"admin"
},
{
role
:
"watcher"
}])
const
params
=
useParams
()
console
.
log
(
users
)
const
[
open
,
setOpen
]
=
useState
(
false
);
const
handleOpen
=
()
=>
setOpen
(
true
);
const
handleClose
=
()
=>
setOpen
(
false
);
const
[
state
,
setState
]
=
useState
({
displayName
:
""
,
roleProject
:
""
,
userId
:
""
,
projectId
:
""
});
const
submitFormHandler
=
(
e
)
=>
{
e
.
preventDefault
();
let
idOfUser
=
users
?.
map
((
user
)
=>
(
user
.
displayName
===
state
.
displayName
)
?
user
.
id
:
null
)
let
idOfUser1
=
users
?.
map
((
user
)
=>
{
console
.
log
(
user
)
return
null
})
console
.
log
(
idOfUser1
)
console
.
log
(
idOfUser
)
console
.
log
(
"state of submit "
+
state
);
let
members
=
{
roleProject
:
state
.
roleProject
,
projectId
:
params
.
id
,
userId
:
idOfUser
}
console
.
log
(
members
);
onSubmit
(
members
);
};
// const onChange = (e) => {
// const value = e.target.value;
// const name = e.target.name;
// const newState= { ...state, [name]: value };
// console.log("newState " + newState)
// console.log("e.target " + e.target)
// console.log("e " + e)
// setState(newState);
// };
const
memberChangeHandler
=
(
e
,
value
)
=>
{
setState
(()
=>
{
return
{
...
state
,
member
:
value
,
userId
:
state
.
userId
}
});
console
.
log
(
"memberChangeHandler"
+
value
)
}
const
roleChangeHandler
=
(
e
,
value
)
=>
{
setState
(()
=>
{
return
{
...
state
,
roleProject
:
value
}
});
console
.
log
(
value
)
}
return
(
<
div
>
<
PersonAddIcon
onClick
=
{
handleOpen
}
style
=
{{
marginLeft
:
"30px"
,
marginTop
:
"-3px"
}}
>
Добавить
участника
<
/PersonAddIcon
>
<
Modal
open
=
{
open
}
onClose
=
{
handleClose
}
aria
-
labelledby
=
"modal-modal-title"
aria
-
describedby
=
"modal-modal-description"
>
<
Box
sx
=
{
style
}
>
<
form
onSubmit
=
{
submitFormHandler
}
>
<
Grid
container
direction
=
"column"
spacing
=
{
2
}
>
<
Typography
variant
=
"h5"
style
=
{{
margin
:
"5px"
,
textAlign
:
"center"
}}
>
Новый
участник
<
/Typography
>
<
Autocomplete
id
=
"free-solo-demo"
freeSolo
options
=
{
users
?.
map
((
user
)
=>
user
.
displayName
)}
onChange
=
{
memberChangeHandler
}
name
=
{
"userId"
}
value
=
{
state
.
userId
}
renderInput
=
{(
params
)
=>
<
TextField
style
=
{{
margin
:
"5px"
}}
label
=
{
"Участник"
}
state
=
{
state
}
{...
params
}
/>
}
/>
<
Autocomplete
id
=
"free-solo-demo"
freeSolo
options
=
{
role
?.
map
((
role
)
=>
role
.
role
)}
value
=
{
state
.
roleProject
}
onChange
=
{
roleChangeHandler
}
renderInput
=
{(
params
)
=>
<
TextField
style
=
{{
margin
:
"5px"
}}
name
=
{
"roleProject"
}
label
=
{
"Роль в проекте"
}
state
=
{
state
}
{...
params
}
/>
}
/>
<
Grid
item
>
<
Button
type
=
"submit"
color
=
"primary"
variant
=
"contained"
>
Create
<
/Button
>
<
/Grid
>
<
/Grid
>
<
/form
>
<
/Box
>
<
/Modal
>
<
/div
>
);
};
export
default
MemberForm
;
\ No newline at end of file
planner-front/src/components/ProjectForm/ProjectForm.js
View file @
fec54d89
...
...
@@ -45,7 +45,7 @@ const ProjectForm = ({onSubmit}) => {
return
(
<
div
>
<
Button
onClick
=
{
handleOpen
}
>
Add
project
<
/Button
>
<
Button
onClick
=
{
handleOpen
}
>
Добавить
проект
<
/Button
>
<
Modal
open
=
{
open
}
onClose
=
{
handleClose
}
...
...
@@ -56,7 +56,7 @@ const ProjectForm = ({onSubmit}) => {
<
Box
sx
=
{
style
}
>
<
form
>
<
Grid
container
direction
=
"column"
spacing
=
{
2
}
>
<
Typography
variant
=
"h4"
>
New
project
<
/Typography
>
<
Typography
variant
=
"h4"
>
Новый
проект
<
/Typography
>
<
FormElement
onChange
=
{
inputChangeHandler
}
name
=
{
"title"
}
...
...
@@ -70,7 +70,7 @@ const ProjectForm = ({onSubmit}) => {
variant
=
"contained"
>
Create
Создать
<
/Button
>
<
/Grid
>
<
/Grid
>
...
...
planner-front/src/components/ProjectItem/ProjectItem.js
View file @
fec54d89
...
...
@@ -7,12 +7,12 @@ import { useDispatch, useSelector } from "react-redux";
const
ProjectItem
=
({
title
,
tasks
,
id
})
=>
{
const
user
=
useSelector
(
state
=>
state
.
users
.
user
);
const
dispatch
=
useDispatch
();
console
.
log
(
tasks
)
console
.
log
(
user
)
return
<>
<
Grid
item
xs
=
{
12
}
sm
=
{
12
}
md
=
{
6
}
lg
=
{
4
}
>
<
Card
>
<
CardContent
>
<
CardContent
>
<
strong
>
<
br
><
/br
>
Название
проекта
:
{
title
}
...
...
planner-front/src/components/ProjectMembersItem/ProjectMembersItem.js
View file @
fec54d89
import
{
Card
,
CardActions
,
CardContent
,
Grid
,
IconButton
}
from
"@mui/material"
;
import
{
Card
,
CardActions
,
CardContent
,
Grid
,
IconButton
,
Tooltip
}
from
"@mui/material"
;
import
{
Link
}
from
"react-router-dom"
;
import
ArrowForwardIcon
from
"@mui/icons-material/ArrowForward"
;
import
{
useDispatch
,
useSelector
}
from
"react-redux"
;
import
DeleteIcon
from
"@mui/icons-material/Delete"
;
const
ProjectMembersItem
=
({
displayName
,
id
})
=>
{
const
ProjectMembersItem
=
({
displayName
,
roleProject
,
id
,
roleProjectOfAuthor
})
=>
{
console
.
log
(
displayName
)
const
dispatch
=
useDispatch
();
const
user
=
useSelector
(
state
=>
state
.
users
)
console
.
log
(
user
)
const
{
projects
,
project
}
=
useSelector
(
state
=>
state
.
projects
);
return
<>
...
...
@@ -18,11 +21,22 @@ const ProjectMembersItem = ({ displayName, id }) => {
<
/strong
>
<
strong
>
<
br
><
/br
>
роль
:
{
project
?.
project
?.
members
[
0
]?.
roleProject
}
роль
:
{
roleProject
}
<
/strong
>
<
strong
>
<
br
><
/br
>
<
button
>
delete
<
/button
>
{
roleProjectOfAuthor
===
"admin"
?
(
<
strong
>
<
Tooltip
title
=
"Удалить"
>
<
IconButton
onClick
=
{(
id
)
=>
{
// deleteHandle(task.id);
}}
>
<
DeleteIcon
style
=
{{
marginTop
:
"-5px"
}}
/
>
<
/IconButton
>
<
/Tooltip
>
<
/strong>
)
: null
}
<
/strong
>
<
/CardContent
>
<
/Card
>
...
...
planner-front/src/components/ProjectMembersList/ProjectMembersList.js
View file @
fec54d89
import
{
Grid
}
from
"@mui/material"
;
import
ProjectMembersItem
from
"../ProjectMembersItem/ProjectMembersItem"
;
const
ProjectMembersList
=
({
users
})
=>
{
console
.
log
(
us
ers
)
const
ProjectMembersList
=
({
members
,
roleProjectOfAuthor
})
=>
{
console
.
log
(
"members "
,
memb
ers
)
return
(
<
Grid
item
container
direction
=
"
row
"
spacing
=
{
1
}
>
{
users
?.
map
(
us
er
=>
{
<
Grid
item
container
direction
=
"
column
"
spacing
=
{
1
}
>
{
members
?.
map
(
memb
er
=>
{
return
<
ProjectMembersItem
displayName
=
{
user
.
displayName
}
id
=
{
user
.
id
}
key
=
{
user
.
id
}
displayName
=
{
member
?.
user
?.
displayName
}
roleProject
=
{
member
?.
roleProject
}
id
=
{
member
.
id
}
key
=
{
member
.
id
}
roleProjectOfAuthor
=
{
roleProjectOfAuthor
}
/
>
})}
<
/Grid
>
...
...
planner-front/src/components/ProjectsList/ProjectsList.js
View file @
fec54d89
...
...
@@ -2,8 +2,9 @@ import {Grid} from "@mui/material";
import
ProjectItem
from
"../ProjectItem/ProjectItem"
;
const
ProjectsList
=
({
projects
})
=>
{
console
.
log
(
projects
)
return
(
<
Grid
item
container
direction
=
"
row
"
spacing
=
{
1
}
>
<
Grid
item
container
direction
=
"
column
"
spacing
=
{
1
}
>
{
projects
?.
map
(
project
=>
{
return
<
ProjectItem
tasks
=
{
project
.
tasks
}
...
...
planner-front/src/components/UI/Form/FormElement/FormElement.js
View file @
fec54d89
import
{
Grid
,
TextField
,
MenuItem
}
from
"@mui/material"
;
import
PropTypes
from
"prop-types"
;
const
FormElement
=
({
name
,
label
,
state
,
error
,
onChange
,
select
,
options
,
type
=
"'text"
})
=>
{
const
FormElement
=
({
name
,
label
,
state
,
error
,
onChange
,
select
,
options
,
type
=
"'text"
,
users
})
=>
{
let
inputChildren
=
null
if
(
select
)
{
...
...
@@ -19,6 +19,7 @@ const FormElement = ({ name, label, state, error, onChange, select, options, typ
type
=
{
type
}
variant
=
"outlined"
value
=
{
state
?.[
name
]}
users
=
{
users
}
onChange
=
{
onChange
}
error
=
{
!!
error
}
helperText
=
{
error
}
...
...
planner-front/src/containers/FullProject/FullProject.js
View file @
fec54d89
...
...
@@ -6,6 +6,7 @@ import { fetchProject } from "../../store/actions/projectsActions";
import
ProjectTasksBody
from
"../../components/ProjectTasks/ProjectTasksBody"
;
import
{
fetchUsers
}
from
"../../store/actions/usersActions"
;
import
ProjectMembersList
from
"../../components/ProjectMembersList/ProjectMembersList"
;
import
NewMember
from
"../NewMember/NewMember"
;
const
FullProject
=
()
=>
{
...
...
@@ -28,7 +29,7 @@ const FullProject = () => {
useEffect
(()
=>
{
dispatch
(
fetchProject
(
params
.
id
))
},
[
params
.
id
,
dispatch
]);
console
.
log
(
project
);
console
.
log
(
"project "
,
project
);
return
<>
<
Grid
item
xs
=
{
12
}
sm
=
{
12
}
md
=
{
6
}
lg
=
{
4
}
>
...
...
@@ -53,9 +54,13 @@ const FullProject = () => {
<
/strong
>
<
strong
>
<
br
><
/br
>
<
div
style
=
{{
display
:
'flex'
,
direction
:
'column'
}}
>
Участники
проекта
:
<
NewMember
members
=
{
project
?.
project
?.
members
}
/
>
<
ProjectMembersList
users
=
{
users
}
project
=
{
project
}
/
>
<
/div
>
<
ProjectMembersList
users
=
{
users
}
project
=
{
project
}
members
=
{
project
?.
project
?.
members
}
roleProjectOfAuthor
=
{
project
?.
project
?.
members
[
0
]?.
roleProject
}
/
>
<
/strong
>
<
strong
>
<
br
><
/br
>
...
...
planner-front/src/containers/NewMember/NewMember.js
0 → 100644
View file @
fec54d89
import
{
useNavigate
}
from
"react-router-dom"
;
import
{
useDispatch
,
useSelector
}
from
"react-redux"
;
import
{
useEffect
}
from
"react"
;
import
ProjectForm
from
"../../components/ProjectForm/ProjectForm"
;
import
{
createMember
,
createProject
,
fetchMembers
,
fetchProjects
}
from
"../../store/actions/projectsActions"
;
import
MemberForm
from
"../../components/MemberForm/MemberForm"
;
const
NewMember
=
({
members
})
=>
{
const
dispatch
=
useDispatch
();
const
projects
=
useSelector
(
state
=>
state
.
projects
.
projects
);
const
navigate
=
useNavigate
();
const
onSubmit
=
async
(
memberData
)
=>
{
await
dispatch
(
createMember
(
memberData
,
navigate
));
// navigate("/projects/" + memberData.id)
console
.
log
(
"memberData "
,
memberData
)
};
// useEffect(()=> {
// dispatch(fetchMembers());
// }, [dispatch])
return
(
<>
<
MemberForm
members
=
{
members
}
onSubmit
=
{
onSubmit
}
/
>
<
/
>
);
};
export
default
NewMember
;
\ No newline at end of file
planner-front/src/containers/NewProject/NewProject.js
View file @
fec54d89
...
...
@@ -13,7 +13,6 @@ const NewProject = () => {
const
onSubmit
=
async
(
projectData
)
=>
{
await
dispatch
(
createProject
(
projectData
,
navigate
));
console
.
log
(
projectData
)
};
useEffect
(()
=>
{
...
...
planner-front/src/containers/Projects/Projects.js
View file @
fec54d89
...
...
@@ -12,6 +12,7 @@ const Projects = () => {
const
dispatch
=
useDispatch
();
const
{
projects
,
loading
}
=
useSelector
(
state
=>
state
.
projects
.
projects
);
const
{
users
}
=
useSelector
(
state
=>
state
.
users
);
const
members
=
useSelector
(
state
=>
state
.
projects
.
projects
)
console
.
log
(
projects
)
console
.
log
(
users
)
...
...
@@ -32,7 +33,7 @@ const Projects = () => {
>
<
Grid
item
>
<
Typography
variant
=
"h4"
>
Projects
Проекты
<
/Typography
>
<
/Grid
>
<
HasAccess
roles
=
{[
"superuser"
,
"admin"
,
"user"
]}
>
...
...
@@ -42,7 +43,7 @@ const Projects = () => {
<
/HasAccess
>
<
/Grid
>
<
Loader
loading
=
{
loading
}
/
>
<
ProjectsList
projects
=
{
projects
}
/
>
<
ProjectsList
projects
=
{
projects
}
members
=
{
members
}
/
>
<
/Grid
>
<
/>
)
:
<
h1
>
Созданных
проектов
нет
<
/h1
>
...
...
planner-front/src/store/actionTypes/projectsActionTypes.js
View file @
fec54d89
export
const
FETCH_PROJECTS_REQUEST
=
"FETCH_PROJECTS_REQUEST"
;
export
const
FETCH_PROJECTS_SUCCESS
=
"FETCH_PROJECTS_SUCCESS"
;
export
const
FETCH_PROJECTS_ERROR
=
"FETCH_PROJECTS_ERROR"
;
export
const
FETCH_PROJECT_SUCCESS
=
"FETCH_PROJECT_SUCCESS"
;
export
const
CREATE_PROJECT_SUCCESS
=
"CREATE_PROJECT_SUCCESS"
;
export
const
CREATE_MEMBER_SUCCESS
=
"CREATE_MEMBER_SUCCESS"
;
\ No newline at end of file
planner-front/src/store/actions/projectsActions.js
View file @
fec54d89
import
axios
from
"../../axiosPlanner"
;
import
{
CREATE_
PROJECT
_SUCCESS
,
FETCH_PROJECTS_ERROR
,
FETCH_PROJECTS_REQUEST
,
FETCH_PROJECTS_SUCCESS
,
FETCH_PROJECT_SUCCESS
}
from
"../actionTypes/projectsActionTypes"
;
import
{
CREATE_
MEMBER_SUCCESS
,
CREATE_PROJECT_SUCCESS
,
FETCH_MEMBERS_ERROR
,
FETCH_MEMBERS_REQUEST
,
FETCH_MEMBERS
_SUCCESS
,
FETCH_PROJECTS_ERROR
,
FETCH_PROJECTS_REQUEST
,
FETCH_PROJECTS_SUCCESS
,
FETCH_PROJECT_SUCCESS
}
from
"../actionTypes/projectsActionTypes"
;
import
{
showNotification
}
from
"./commonActions"
;
const
fetchProjectsRequest
=
()
=>
{
...
...
@@ -8,17 +8,21 @@ const fetchProjectsRequest = () => {
const
fetchProjectsSuccess
=
(
projects
)
=>
{
return
{
type
:
FETCH_PROJECTS_SUCCESS
,
projects
};
};
const
fetchProjectSuccess
=
(
project
)
=>
{
return
{
type
:
FETCH_PROJECT_SUCCESS
,
project
};
};
const
fetchProjectsError
=
(
error
)
=>
{
return
{
type
:
FETCH_PROJECTS_ERROR
,
error
};
}
const
fetchProjectSuccess
=
(
project
)
=>
{
return
{
type
:
FETCH_PROJECT_SUCCESS
,
project
};
};
const
createProjectSuccess
=
()
=>
{
return
{
type
:
CREATE_PROJECT_SUCCESS
};
};
const
createMemberSuccess
=
(
member
)
=>
{
return
{
type
:
CREATE_MEMBER_SUCCESS
,
member
};
};
export
const
fetchProjects
=
()
=>
{
return
async
dispatch
=>
{
dispatch
(
fetchProjectsRequest
());
...
...
@@ -37,6 +41,7 @@ export const fetchProject = (id) => {
try
{
const
response
=
await
axios
.
get
(
"/projects/"
+
id
);
dispatch
(
fetchProjectSuccess
(
response
.
data
));
console
.
log
(
"fetch project "
+
response
.
data
)
}
catch
(
e
)
{
dispatch
(
fetchProjectsError
(
e
));
}
...
...
@@ -57,3 +62,20 @@ export const createProject = (projectData, navigate) => {
}
};
}
export
const
createMember
=
(
memberData
,
navigate
)
=>
{
return
async
(
dispatch
)
=>
{
try
{
console
.
log
(
memberData
)
const
response
=
await
axios
.
post
(
"/projects/add-user"
,
memberData
);
dispatch
(
createMemberSuccess
());
console
.
log
(
memberData
)
navigate
(
"/projects/"
)
dispatch
(
showNotification
(
"Участник успешно добавлен"
))
}
catch
(
e
)
{
console
.
log
(
e
);
dispatch
(
showNotification
(
"Не удалось добавить участника"
,
"error"
))
}
};
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment