Member management forms
This commit is contained in:
1 parent
a53a3a8cb5
commit
caba8bb338
15 files changed
+226
-98
No files matched your search
@@ -18,17 +18,23 @@ export const GET_ALL_TEAMS_QUERY = gql`
|
||||
createdAt
|
||||
profile {
|
||||
avatar
|
||||
banner
|
||||
description
|
||||
motto
|
||||
updatedAt
|
||||
}
|
||||
members {
|
||||
role
|
||||
email
|
||||
member {
|
||||
alias
|
||||
authId
|
||||
}
|
||||
status {
|
||||
id
|
||||
status
|
||||
reason
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,17 +16,23 @@ export const GET_TEAMS_BY_OWNER = gql`
|
||||
createdAt
|
||||
profile {
|
||||
avatar
|
||||
banner
|
||||
description
|
||||
motto
|
||||
updatedAt
|
||||
}
|
||||
members {
|
||||
role
|
||||
email
|
||||
member {
|
||||
alias
|
||||
authId
|
||||
}
|
||||
status {
|
||||
id
|
||||
status
|
||||
reason
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export const REMOVE_TEAM_MEMBER = gql`
|
||||
mutation removeTeamMember($teamId: String!, $memberId: String!) {
|
||||
removeTeamMember(teamId: $teamId, memberId: $memberId) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export default REMOVE_TEAM_MEMBER
|
||||
@@ -0,0 +1,12 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export const SET_TEAM_MEMBER_ROLE = gql`
|
||||
mutation setTeamMemberRole($teamId: String!, $memberId: String!, $role: String!) {
|
||||
setTeamMemberRole(teamId: $teamId, memberId: $memberId, role: $role) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export default SET_TEAM_MEMBER_ROLE
|
||||
@@ -15,17 +15,23 @@ export const TEAMS_FRAGMENT = gql`
|
||||
createdAt
|
||||
profile {
|
||||
avatar
|
||||
banner
|
||||
description
|
||||
motto
|
||||
updatedAt
|
||||
}
|
||||
members {
|
||||
role
|
||||
email
|
||||
member {
|
||||
alias
|
||||
authId
|
||||
}
|
||||
status {
|
||||
id
|
||||
status
|
||||
reason
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
@@ -28,17 +28,23 @@ const UPDATE_TEAM_PROFILE = gql`
|
||||
createdAt
|
||||
profile {
|
||||
avatar
|
||||
banner
|
||||
description
|
||||
motto
|
||||
updatedAt
|
||||
}
|
||||
members {
|
||||
role
|
||||
email
|
||||
member {
|
||||
alias
|
||||
authId
|
||||
}
|
||||
status {
|
||||
id
|
||||
status
|
||||
reason
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import DialogContent from '@material-ui/core/DialogContent'
|
||||
import DialogTitle from '@material-ui/core/DialogTitle'
|
||||
import Typography from '@material-ui/core/Typography'
|
||||
|
||||
import DELETE_TEAM from '../../../graphql/teams/DeleteTeamMutation'
|
||||
import REMOVE_TEAM_MEMBER from '../../../graphql/teams/RemoveTeamMemberMutation'
|
||||
import GET_TEAMS_BY_OWNER from '../../../graphql/teams/GetTeamsByOwnerQuery'
|
||||
|
||||
import { checkGraphQLError } from '../../../utils/graphql-errors'
|
||||
@@ -58,13 +58,8 @@ export class ManageMemberDelete extends Component {
|
||||
const { classes, teamId, authId } = this.props
|
||||
return (
|
||||
<Mutation
|
||||
mutation={DELETE_TEAM}
|
||||
refetchQueries={[
|
||||
{
|
||||
query: GET_TEAMS_BY_OWNER,
|
||||
variables: { authId }
|
||||
}
|
||||
]}
|
||||
mutation={REMOVE_TEAM_MEMBER}
|
||||
refetchQueries={[{ query: GET_TEAMS_BY_OWNER }]}
|
||||
>
|
||||
{(deleteTeam, { loading, error, data }) => {
|
||||
let errors
|
||||
@@ -86,7 +81,7 @@ export class ManageMemberDelete extends Component {
|
||||
})
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<React.Fragment>
|
||||
<Button
|
||||
size='small'
|
||||
color='primary'
|
||||
@@ -123,7 +118,8 @@ export class ManageMemberDelete extends Component {
|
||||
this.handleSubmit(
|
||||
e,
|
||||
deleteTeam,
|
||||
teamId
|
||||
teamId,
|
||||
authId
|
||||
)
|
||||
}}
|
||||
color='primary'
|
||||
@@ -133,16 +129,16 @@ export class ManageMemberDelete extends Component {
|
||||
</DialogActions>
|
||||
</div>
|
||||
</Dialog>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
}}
|
||||
</Mutation>
|
||||
)
|
||||
}
|
||||
|
||||
async handleSubmit (e, deleteTeam, teamId) {
|
||||
async handleSubmit (e, deleteTeam, teamId, memberId) {
|
||||
e.preventDefault()
|
||||
await deleteTeam({ variables: { teamId } })
|
||||
await deleteTeam({ variables: { teamId, memberId } })
|
||||
this.setState({ open: false })
|
||||
}
|
||||
}
|
||||
@@ -150,7 +146,7 @@ export class ManageMemberDelete extends Component {
|
||||
ManageMemberDelete.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
teamId: PropTypes.string.isRequired,
|
||||
authId: PropTypes.string.isRequired
|
||||
authId: PropTypes.string
|
||||
}
|
||||
|
||||
export default withStyles(styles)(ManageMemberDelete)
|
||||
@@ -10,8 +10,10 @@ import DialogActions from '@material-ui/core/DialogActions'
|
||||
import DialogContent from '@material-ui/core/DialogContent'
|
||||
import DialogTitle from '@material-ui/core/DialogTitle'
|
||||
import Typography from '@material-ui/core/Typography'
|
||||
import TextField from '@material-ui/core/TextField'
|
||||
import MenuItem from '@material-ui/core/MenuItem'
|
||||
|
||||
import DELETE_TEAM from '../../../graphql/teams/DeleteTeamMutation'
|
||||
import SET_TEAM_MEMBER_ROLE from '../../../graphql/teams/SetTeamMemberRoleMutation'
|
||||
import GET_TEAMS_BY_OWNER from '../../../graphql/teams/GetTeamsByOwnerQuery'
|
||||
|
||||
import { checkGraphQLError } from '../../../utils/graphql-errors'
|
||||
@@ -27,6 +29,11 @@ const styles = theme => ({
|
||||
}
|
||||
})
|
||||
|
||||
const roles = [
|
||||
{ role: 'Admin' },
|
||||
{ role: 'Member' }
|
||||
]
|
||||
|
||||
export class ManageMemberRole extends Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
@@ -37,7 +44,8 @@ export class ManageMemberRole extends Component {
|
||||
this.handleSubmit = this.handleSubmit.bind(this)
|
||||
|
||||
this.state = {
|
||||
open: false
|
||||
open: false,
|
||||
role: ''
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,15 +66,10 @@ export class ManageMemberRole extends Component {
|
||||
const { classes, teamId, authId } = this.props
|
||||
return (
|
||||
<Mutation
|
||||
mutation={DELETE_TEAM}
|
||||
refetchQueries={[
|
||||
{
|
||||
query: GET_TEAMS_BY_OWNER,
|
||||
variables: { authId }
|
||||
}
|
||||
]}
|
||||
mutation={SET_TEAM_MEMBER_ROLE}
|
||||
refetchQueries={[{ query: GET_TEAMS_BY_OWNER }]}
|
||||
>
|
||||
{(deleteTeam, { loading, error, data }) => {
|
||||
{(setTeamMemberRole, { loading, error, data }) => {
|
||||
let errors
|
||||
let loader
|
||||
if (loading) {
|
||||
@@ -86,7 +89,7 @@ export class ManageMemberRole extends Component {
|
||||
})
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<React.Fragment>
|
||||
<Button
|
||||
size='small'
|
||||
color='primary'
|
||||
@@ -108,6 +111,17 @@ export class ManageMemberRole extends Component {
|
||||
<Typography variant='subheading'>
|
||||
Admin members can approve new team members, send team invitations, and remove team members.
|
||||
</Typography>
|
||||
<TextField
|
||||
select
|
||||
label='Team Role'
|
||||
value={this.state.role}
|
||||
onChange={(e) => this.setState({ role: e.target.value })}
|
||||
fullWidth
|
||||
>
|
||||
{roles.map(role => (
|
||||
<MenuItem key={role.role} value={role.role}>{role.role}</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
{loader}
|
||||
{errors}
|
||||
</DialogContent>
|
||||
@@ -119,8 +133,9 @@ export class ManageMemberRole extends Component {
|
||||
onClick={e => {
|
||||
this.handleSubmit(
|
||||
e,
|
||||
deleteTeam,
|
||||
teamId
|
||||
setTeamMemberRole,
|
||||
teamId,
|
||||
authId
|
||||
)
|
||||
}}
|
||||
color='primary'
|
||||
@@ -130,16 +145,17 @@ export class ManageMemberRole extends Component {
|
||||
</DialogActions>
|
||||
</div>
|
||||
</Dialog>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
}}
|
||||
</Mutation>
|
||||
)
|
||||
}
|
||||
|
||||
async handleSubmit (e, deleteTeam, teamId) {
|
||||
async handleSubmit (e, setTeamMemberRole, teamId, authId) {
|
||||
e.preventDefault()
|
||||
await deleteTeam({ variables: { teamId } })
|
||||
const role = this.state.role
|
||||
await setTeamMemberRole({ variables: { teamId, memberId: authId, role: role } })
|
||||
this.setState({ open: false })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import Grid from '@material-ui/core/Grid'
|
||||
import CardMedia from '@material-ui/core/CardMedia'
|
||||
import Typography from '@material-ui/core/Typography'
|
||||
|
||||
import ManageMemberDelete from './ManageMemberDelete'
|
||||
@@ -12,38 +11,35 @@ import { MessageCard } from '../../common/'
|
||||
export const ManageMembersItem = ({ classes, member, teamId, authId }) => {
|
||||
console.log('ManageMembersItem', member)
|
||||
let profile = null
|
||||
let email = null
|
||||
let memberStatus = null
|
||||
if (member.member !== null) {
|
||||
profile = member.member
|
||||
}
|
||||
let avatar = null
|
||||
if (member.profile !== undefined && member.profile !== null && member.profile.avatar !== undefined && member.profile.avatar !== 'a') {
|
||||
avatar = member.profile.avatar
|
||||
} else {
|
||||
avatar = 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22288%22%20height%3D%22225%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20288%20225%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_164edaf95ee%20text%20%7B%20fill%3A%23eceeef%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_164edaf95ee%22%3E%3Crect%20width%3D%22288%22%20height%3D%22225%22%20fill%3D%22%2355595c%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%2296.32500076293945%22%20y%3D%22118.8%22%3EThumbnail%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E'
|
||||
if (member.member === null && member.email !== null) {
|
||||
email = member.email
|
||||
}
|
||||
if (profile !== null) {
|
||||
if (member.status.length > 0) memberStatus = member.status
|
||||
if (profile !== null || email !== null) {
|
||||
return (
|
||||
<Grid container className={classes.memberContainer}>
|
||||
<Grid item xs={1}>
|
||||
<CardMedia
|
||||
className={classes.cardMemberMedia}
|
||||
image={avatar}
|
||||
title={member.name}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={4}>
|
||||
<Typography gutterBottom variant='headline' component='h2'>
|
||||
{profile.alias}
|
||||
<Typography gutterBottom variant='subheading' component='h2' align='left' >
|
||||
{profile !== null ? profile.alias : email}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={4}>
|
||||
<Typography variant='caption' color='textSecondary'>
|
||||
{member.role} | Member since:
|
||||
<Typography color='textSecondary' variant='body2' component='h4' align='left' >
|
||||
{email !== null ? `${memberStatus[memberStatus.length - 1].status} | Sent: ${memberStatus[memberStatus.length - 1].createdAt}` : `${member.role} | Member since: `}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={3}>
|
||||
<ManageMemberRole teamId={teamId} authId={authId} />
|
||||
<ManageMemberDelete teamId={teamId} authId={authId} />
|
||||
<Grid item xs={4}>
|
||||
{ profile !== null && member.role !== 'OWNER' && (
|
||||
<ManageMemberRole teamId={teamId} authId={profile !== null ? profile.authId : null} className={classes.buttonRight} />
|
||||
)}
|
||||
{(email !== null || member.role !== 'OWNER') && (
|
||||
<ManageMemberDelete teamId={teamId} authId={profile !== null ? profile.authId : null} email={email !== null ? email : null} className={classes.buttonRight} />
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
|
||||
@@ -50,8 +50,8 @@ const styles = theme => ({
|
||||
justifyContent: 'flex-start'
|
||||
},
|
||||
memberContainer: {
|
||||
margin: 40,
|
||||
padding: 12
|
||||
margin: 10,
|
||||
padding: 6
|
||||
}
|
||||
})
|
||||
|
||||
@@ -66,43 +66,40 @@ export const ManageMembersTeamItem = ({ classes, team, authId }) => {
|
||||
if (team.members.length > 0) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{ team.members.map(member => {
|
||||
console.log('ManageMembersTeamItem: ', member)
|
||||
return (
|
||||
<Grid item xs={12} key={`${team.id}-${member.member.alias}`}>
|
||||
<Card className={classes.card}>
|
||||
<div className={classes.cardDetails}>
|
||||
<CardContent className={classes.cardContent}>
|
||||
<Grid container>
|
||||
<Grid item xs={2}>
|
||||
<CardMedia
|
||||
className={classes.cardMedia}
|
||||
image={avatar}
|
||||
title={team.name}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={9}>
|
||||
<Typography gutterBottom variant='headline' component='h2'>
|
||||
{team.name}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={1}>
|
||||
<InviteMemberDialog teamId={team.id} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<ManageMembersItem
|
||||
member={member}
|
||||
teamId={team.id}
|
||||
authId={authId}
|
||||
classes={classes}
|
||||
<Grid item xs={12} key={team.id}>
|
||||
<Card className={classes.card}>
|
||||
<div className={classes.cardDetails}>
|
||||
<CardContent className={classes.cardContent}>
|
||||
<Grid container>
|
||||
<Grid item xs={2}>
|
||||
<CardMedia
|
||||
className={classes.cardMedia}
|
||||
image={avatar}
|
||||
title={team.name}
|
||||
/>
|
||||
</CardContent>
|
||||
</div>
|
||||
</Card>
|
||||
</Grid>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Grid>
|
||||
<Grid item xs={9}>
|
||||
<Typography gutterBottom variant='headline' component='h2'>
|
||||
{team.name}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={1}>
|
||||
<InviteMemberDialog teamId={team.id} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
{team.members.length > 0 && team.members.map((member, index) => (
|
||||
<ManageMembersItem
|
||||
member={member}
|
||||
teamId={team.id}
|
||||
authId={authId}
|
||||
classes={classes}
|
||||
key={`${team.id}-${index}`}
|
||||
/>
|
||||
))}
|
||||
</CardContent>
|
||||
</div>
|
||||
</Card>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
)
|
||||
} else {
|
||||
|
||||
Reference in new issue
Block a user