diff --git a/web/modals/threads/members/member.react.js b/web/modals/threads/members/member.react.js index 87a7bd16b..183dcf044 100644 --- a/web/modals/threads/members/member.react.js +++ b/web/modals/threads/members/member.react.js @@ -1,79 +1,138 @@ // @flow +import { + faPlusCircle, + faMinusCircle, + faSignOutAlt, +} from '@fortawesome/free-solid-svg-icons'; import classNames from 'classnames'; import * as React from 'react'; -import { memberIsAdmin, memberHasAdminPowers } from 'lib/shared/thread-utils'; +import { + memberIsAdmin, + memberHasAdminPowers, + threadHasPermission, +} from 'lib/shared/thread-utils'; import { stringForUser } from 'lib/shared/user-utils'; import type { SetState } from 'lib/types/hook-types'; import { type RelativeMemberInfo, type ThreadInfo, + threadPermissions, } from 'lib/types/thread-types'; import Label from '../../../components/label.react'; +import MenuItem from '../../../components/menu-item.react'; import Menu from '../../../components/menu.react'; import SWMansionIcon from '../../../SWMansionIcon.react'; import css from './members-modal.css'; type Props = { +memberInfo: RelativeMemberInfo, +threadInfo: ThreadInfo, +setOpenMenu: SetState, +isMenuOpen: boolean, }; function ThreadMember(props: Props): React.Node { const { memberInfo, threadInfo, setOpenMenu, isMenuOpen } = props; const userName = stringForUser(memberInfo); const onMenuChange = React.useCallback( menuOpen => { if (menuOpen) { setOpenMenu(() => memberInfo.id); } else { setOpenMenu(menu => (menu === memberInfo.id ? null : menu)); } }, [memberInfo.id, setOpenMenu], ); - const menuItems = []; + const menuItems = React.useMemo(() => { + const { role } = memberInfo; + if (!role) { + return []; + } + + const canRemoveMembers = threadHasPermission( + threadInfo, + threadPermissions.REMOVE_MEMBERS, + ); + const canChangeRoles = threadHasPermission( + threadInfo, + threadPermissions.CHANGE_ROLE, + ); + + const actions = []; + + const isAdmin = memberIsAdmin(memberInfo, threadInfo); + if (canChangeRoles && memberInfo.username && isAdmin) { + actions.push( + , + ); + } else if (canChangeRoles && memberInfo.username) { + actions.push( + , + ); + } + + if ( + canRemoveMembers && + !memberInfo.isViewer && + (canChangeRoles || threadInfo.roles[role]?.isDefault) + ) { + actions.push( + , + ); + } + + return actions; + }, [memberInfo, threadInfo]); const userSettingsIcon = React.useMemo( () => , [], ); const label = React.useMemo(() => { if (memberIsAdmin(memberInfo, threadInfo)) { return ; } else if (memberHasAdminPowers(memberInfo)) { return ; } return null; }, [memberInfo, threadInfo]); const memberContainerClasses = classNames(css.memberContainer, { [css.memberContainerWithMenuOpen]: isMenuOpen, }); return (
{userName} {label}
{menuItems}
); } export default ThreadMember;