diff --git a/web/modals/threads/members/members-modal.css b/web/modals/threads/members/members-modal.css index d48cdf2a1..5738a49e1 100644 --- a/web/modals/threads/members/members-modal.css +++ b/web/modals/threads/members/members-modal.css @@ -1,89 +1,89 @@ div.modalContentContainer { height: 617px; overflow: hidden; display: flex; flex-direction: column; row-gap: 16px; } -div.membersListTabs { +div.membersListTabsContent { flex: 1; overflow: hidden; } div.addNewMembers button { width: 100%; } div.membersList { - overflow: auto; - padding: 8px 0; + height: 100%; + overflow-y: scroll; color: var(--members-modal-member-text); } div.noScroll { overflow: hidden; } div.memberContainer { display: flex; flex-direction: row; justify-content: space-between; padding: 8px 16px; } div.memberContainer:hover { cursor: pointer; background-color: var(--drawer-open-community-bg); border-radius: 8px; } div.memberInfo { font-size: var(--l-font-18); display: flex; align-items: center; gap: 10px; } div.memberAction { position: relative; } h5.memberletterHeader { margin: 16px; color: var(--members-modal-member-text); font-size: var(--s-font-14); } div.noUsers { padding-top: 16px; text-align: center; } div.addMembersContent { display: flex; flex-direction: column; overflow: auto; color: var(--fg); height: 617px; } div.addMembersPendingList { display: flex; flex-direction: row; flex-wrap: wrap; gap: 6px; padding: 8px; } div.addMembersListContainer { overflow: auto; flex: 1; } div.addMembersFooter { display: flex; justify-content: end; column-gap: 16px; margin-top: 16px; } diff --git a/web/modals/threads/members/members-modal.react.js b/web/modals/threads/members/members-modal.react.js index 5b60c79a1..453cce952 100644 --- a/web/modals/threads/members/members-modal.react.js +++ b/web/modals/threads/members/members-modal.react.js @@ -1,154 +1,152 @@ // @flow import * as React from 'react'; import { useModalContext } from 'lib/components/modal-provider.react.js'; import { useUserSearchIndex } from 'lib/selectors/nav-selectors.js'; import { threadInfoSelector } from 'lib/selectors/thread-selectors.js'; import { roleIsAdminRole, threadHasPermission, } from 'lib/shared/thread-utils.js'; import { threadPermissions } from 'lib/types/thread-permission-types.js'; import { type RelativeMemberInfo } from 'lib/types/thread-types.js'; import { useRolesFromCommunityThreadInfo } from 'lib/utils/role-utils.js'; import { AddMembersModal } from './add-members-modal.react.js'; import ThreadMembersList from './members-list.react.js'; import css from './members-modal.css'; import Button from '../../../components/button.react.js'; import Tabs, { type TabData } from '../../../components/tabs.react.js'; import { useSelector } from '../../../redux/redux-utils.js'; import SearchModal from '../../search-modal.react.js'; type TabType = 'All Members' | 'Admins'; const tabsData: $ReadOnlyArray> = [ { id: 'All Members', header: 'All Members', }, { id: 'Admins', header: 'Admins', }, ]; type ContentProps = { +searchText: string, +threadID: string, }; function ThreadMembersModalContent(props: ContentProps): React.Node { const { threadID, searchText } = props; const [tab, setTab] = React.useState('All Members'); const threadInfo = useSelector(state => threadInfoSelector(state)[threadID]); const { members: threadMembersNotFiltered } = threadInfo; const userSearchIndex = useUserSearchIndex(threadMembersNotFiltered); const userIDs = React.useMemo( () => userSearchIndex.getSearchResults(searchText), [searchText, userSearchIndex], ); const allMembers = React.useMemo( () => threadMembersNotFiltered.filter( (member: RelativeMemberInfo) => searchText.length === 0 || userIDs.includes(member.id), ), [searchText.length, threadMembersNotFiltered, userIDs], ); const roles = useRolesFromCommunityThreadInfo(threadInfo, allMembers); const adminMembers = React.useMemo( () => allMembers.filter((member: RelativeMemberInfo) => roleIsAdminRole(roles.get(member.id)), ), [allMembers, roles], ); const tabs = React.useMemo( () => , [tab], ); const tabContent = React.useMemo(() => { if (tab === 'All Members') { return ( ); } return ( ); }, [adminMembers, allMembers, tab, threadInfo]); const { pushModal, popModal } = useModalContext(); const onClickAddMembers = React.useCallback(() => { pushModal(); }, [popModal, pushModal, threadID]); const canAddMembers = threadHasPermission( threadInfo, threadPermissions.ADD_MEMBERS, ); const addMembersButton = React.useMemo(() => { if (!canAddMembers) { return null; } return (
); }, [canAddMembers, onClickAddMembers]); const threadMembersModalContent = React.useMemo( () => (
-
- {tabs} - {tabContent} -
+ {tabs} +
{tabContent}
{addMembersButton}
), [addMembersButton, tabContent, tabs], ); return threadMembersModalContent; } type Props = { +threadID: string, +onClose: () => void, }; function ThreadMembersModal(props: Props): React.Node { const { onClose, threadID } = props; const renderModalContent = React.useCallback( (searchText: string) => ( ), [threadID], ); return ( {renderModalContent} ); } export default ThreadMembersModal;