Skip to content

Commit 9de7851

Browse files
committed
adding removing member option
1 parent 7c11c03 commit 9de7851

File tree

5 files changed

+225
-8
lines changed

5 files changed

+225
-8
lines changed

packages/components/__generated__/RemoveMemberMutation.graphql.ts

+119
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/components/modules/profiles/Members/MemberItem/index.tsx

+59-7
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ import { FC, useState } from 'react'
33
import { useCurrentProfile } from '@baseapp-frontend/authentication'
44
import { AvatarWithPlaceholder, ConfirmDialog } from '@baseapp-frontend/design-system'
55

6-
import { Box, Button, MenuItem, SelectChangeEvent, Typography } from '@mui/material'
6+
import { Box, Button, MenuItem, SelectChangeEvent, Typography, useTheme } from '@mui/material'
77
import { useFragment } from 'react-relay'
88

99
import { ProfileItemFragment$key } from '../../../../__generated__/ProfileItemFragment.graphql'
1010
import { useChangeUserRoleMutation } from '../../graphql/mutations/ChangeUserRole'
11+
import { useRemoveMemberMutation } from '../../graphql/mutations/RemoveMember'
1112
import { ProfileItemFragment } from '../../graphql/queries/ProfileItem'
12-
import { MemberRoles, MemberStatuses, roleOptions } from '../constants'
13+
import { MemberActions, MemberRoles, MemberStatuses, roleOptions } from '../constants'
1314
import { capitalizeFirstLetter } from '../utils'
1415
import { MemberItemContainer, MemberPersonalInformation, Select } from './styled'
1516
import { MemberItemProps } from './types'
@@ -25,12 +26,16 @@ const MemberItem: FC<MemberItemProps> = ({
2526
userId,
2627
searchQuery,
2728
}) => {
29+
const theme = useTheme()
30+
2831
const memberProfile = useFragment<ProfileItemFragment$key>(ProfileItemFragment, member)
2932

3033
const { currentProfile } = useCurrentProfile()
3134

3235
const [changeUserRole, isChangingUserRole] = useChangeUserRoleMutation()
36+
const [removeMember, isRemovingMember] = useRemoveMemberMutation()
3337
const [openConfirmChangeMember, setOpenConfirmChangeMember] = useState(false)
38+
const [openConfirmRemoveMember, setOpenConfirmRemoveMember] = useState(false)
3439

3540
if (!memberProfile) return null
3641

@@ -39,6 +44,25 @@ const MemberItem: FC<MemberItemProps> = ({
3944

4045
const haveMemberRoleAndStatus = memberRole && status
4146

47+
const removeProfileMember = () => {
48+
if (currentProfile?.id && userId) {
49+
removeMember({
50+
variables: { input: { profileId: currentProfile.id, userId } },
51+
})
52+
}
53+
}
54+
55+
const confirmRemoveProfileMember = () => {
56+
if (currentProfile?.id && userId) {
57+
removeProfileMember()
58+
}
59+
setOpenConfirmRemoveMember(false)
60+
}
61+
62+
const handleRemoveMemberDialog = () => {
63+
setOpenConfirmRemoveMember(!openConfirmRemoveMember)
64+
}
65+
4266
const changeRole = (roleType: MemberRoles) => {
4367
if (currentProfile?.id && userId) {
4468
changeUserRole({
@@ -76,16 +100,27 @@ const MemberItem: FC<MemberItemProps> = ({
76100
<Box>
77101
<Select
78102
value={memberRole}
79-
onChange={(event, _) =>
80-
handleRoleChange(event as SelectChangeEvent<{ value: MemberRoles }>)
81-
}
103+
onChange={(event, _) => {
104+
const { value } = event.target
105+
if (value === MemberActions.remove) {
106+
handleRemoveMemberDialog()
107+
} else {
108+
handleRoleChange(event as SelectChangeEvent<{ value: MemberRoles }>)
109+
}
110+
}}
82111
displayEmpty
83112
variant="filled"
84113
size="small"
85-
disabled={isChangingUserRole}
114+
disabled={isChangingUserRole || isRemovingMember}
86115
>
87116
{roleOptions.map(({ value, label }) => (
88-
<MenuItem key={value} value={value}>
117+
<MenuItem
118+
key={value}
119+
value={value}
120+
sx={{
121+
color: value === MemberActions.remove ? theme.palette.error.main : 'inherit',
122+
}}
123+
>
89124
{label}
90125
</MenuItem>
91126
))}
@@ -130,6 +165,23 @@ const MemberItem: FC<MemberItemProps> = ({
130165
}
131166
cancelText="Back"
132167
/>
168+
<ConfirmDialog
169+
title="Remove member"
170+
open={openConfirmRemoveMember}
171+
onClose={handleRemoveMemberDialog}
172+
content={
173+
<Typography variant="body1">
174+
Are you sure you want to remove this member? This action will revoke their access to the
175+
organization profile.
176+
</Typography>
177+
}
178+
cancelText="Back"
179+
action={
180+
<Button variant="contained" color="error" onClick={confirmRemoveProfileMember}>
181+
Remove
182+
</Button>
183+
}
184+
/>
133185
<MemberPersonalInformation isActive={status === MemberStatuses.active || false}>
134186
<AvatarWithPlaceholder
135187
width={avatarWidth}

packages/components/modules/profiles/Members/MemberListItem/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const MemberListItem: FC<MemberListItemProps> = ({
2020
const nextMemberFragment = useFragment(MemberItemFragment, nextMember)
2121
const prevMemberFragment = useFragment(MemberItemFragment, prevMember)
2222

23-
const isActiveMember = memberFragment.status === MemberStatuses.active
23+
const isActiveMember = memberFragment?.status === MemberStatuses.active
2424
const isPreviousMemberInactive = prevMemberFragment?.status !== MemberStatuses.active
2525
const isPreviousMemberUndefined = !prevMemberFragment?.status
2626
const isNextMemberUndefined = !nextMemberFragment?.status

packages/components/modules/profiles/Members/constants.ts

+8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ export enum MemberRoles {
1313
manager = 'MANAGER',
1414
}
1515

16+
export enum MemberActions {
17+
remove = 'REMOVE',
18+
}
19+
1620
export const roleOptions = [
1721
{
1822
value: MemberRoles.admin,
@@ -22,4 +26,8 @@ export const roleOptions = [
2226
value: MemberRoles.manager,
2327
label: capitalizeFirstLetter(MemberRoles.manager.toLowerCase()),
2428
},
29+
{
30+
value: MemberActions.remove,
31+
label: capitalizeFirstLetter(MemberActions.remove.toLowerCase()),
32+
},
2533
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { useNotification } from '@baseapp-frontend/utils'
2+
3+
import { Disposable, UseMutationConfig, graphql, useMutation } from 'react-relay'
4+
5+
import { RemoveMemberMutation } from '../../../../__generated__/RemoveMemberMutation.graphql'
6+
7+
export const ProfileRemoveMemberMutationQuery = graphql`
8+
mutation RemoveMemberMutation($input: ProfileRemoveMemberInput!) {
9+
profileRemoveMember(input: $input) {
10+
deletedId @deleteRecord
11+
}
12+
}
13+
`
14+
15+
export const useRemoveMemberMutation = (): [
16+
(config: UseMutationConfig<RemoveMemberMutation>) => Disposable,
17+
boolean,
18+
] => {
19+
const { sendToast } = useNotification()
20+
const [commitMutation, isMutationInFlight] = useMutation<RemoveMemberMutation>(
21+
ProfileRemoveMemberMutationQuery,
22+
)
23+
24+
const commit = (config: UseMutationConfig<RemoveMemberMutation>) =>
25+
commitMutation({
26+
...config,
27+
onCompleted: (response, errors) => {
28+
sendToast('Member removed successfully', { type: 'success' })
29+
config?.onCompleted?.(response, errors)
30+
},
31+
onError: (error) => {
32+
sendToast(error.message, { type: 'error' })
33+
config?.onError?.(error)
34+
},
35+
})
36+
37+
return [commit, isMutationInFlight]
38+
}

0 commit comments

Comments
 (0)