diff --git a/client/sidebar/header/actions/CreateRoomList.js b/client/sidebar/header/actions/CreateRoomList.js index a3a62ea426d..30be5abd04b 100644 --- a/client/sidebar/header/actions/CreateRoomList.js +++ b/client/sidebar/header/actions/CreateRoomList.js @@ -8,7 +8,7 @@ import { useAtLeastOnePermission, usePermission } from '../../../contexts/Author import { useSetting } from '../../../contexts/SettingsContext'; import { useSetModal } from '../../../contexts/ModalContext'; import CreateChannel from '../CreateChannel'; -import CreateTeamModal from '../../../views/teams/modals/CreateTeamModal'; +import CreateTeamModal from '../../../views/teams/CreateTeamModal'; import CreateRoomListItem from './CreateRoomListItem'; const CREATE_CHANNEL_PERMISSIONS = ['create-c', 'create-p']; diff --git a/client/views/hooks/useMembersList.ts b/client/views/hooks/useMembersList.ts new file mode 100644 index 00000000000..abe93ca5d4a --- /dev/null +++ b/client/views/hooks/useMembersList.ts @@ -0,0 +1,67 @@ +import { useCallback, useMemo, useState } from 'react'; + +import { getConfig } from '../../../app/ui-utils/client/config'; +import { IUser } from '../../../definition/IUser'; +import { useMethod } from '../../contexts/ServerContext'; +import { useScrollableRecordList } from '../../hooks/lists/useScrollableRecordList'; +import { useComponentDidUpdate } from '../../hooks/useComponentDidUpdate'; +import { RecordList } from '../../lib/lists/RecordList'; + +type MembersListOptions = { + rid: string; + type: 'all' | 'autoJoin'; + limit: number; + debouncedText: string; +} + +export const useMembersList = ( + options: MembersListOptions, +): { + membersList: RecordList; + initialItemCount: number; + reload: () => void; + loadMoreItems: (start: number, end: number) => void; + } => { + const getUsersMethod = useMethod('getUsersOfRoom'); + const [membersList, setMembersList] = useState(() => new RecordList()); + const reload = useCallback(() => setMembersList(new RecordList()), []); + + useComponentDidUpdate(() => { + options && reload(); + }, [options, reload]); + + const fetchData = useCallback( + async (start, end) => { + const { records, total } = await getUsersMethod( + options.rid, + options.type, + { + limit: end - start, + skip: start, + }, + options.debouncedText, + ); + + return { + items: records.map((members: any) => { + members._updatedAt = new Date(members._updatedAt); + return members; + }), + itemCount: total, + }; + }, + [getUsersMethod, options], + ); + + const { loadMoreItems, initialItemCount } = useScrollableRecordList(membersList, fetchData, useMemo(() => { + const filesListSize = getConfig('teamsChannelListSize'); + return filesListSize ? parseInt(filesListSize, 10) : undefined; + }, [])); + + return { + reload, + membersList, + loadMoreItems, + initialItemCount, + }; +}; diff --git a/client/views/teams/modals/ChannelToTeamModal/ChannelToTeamModal.js b/client/views/room/contextualBar/Info/ChannelToTeamModal/ChannelToTeamModal.js similarity index 100% rename from client/views/teams/modals/ChannelToTeamModal/ChannelToTeamModal.js rename to client/views/room/contextualBar/Info/ChannelToTeamModal/ChannelToTeamModal.js diff --git a/client/views/teams/modals/ChannelToTeamModal/StepOne.js b/client/views/room/contextualBar/Info/ChannelToTeamModal/StepOne.js similarity index 73% rename from client/views/teams/modals/ChannelToTeamModal/StepOne.js rename to client/views/room/contextualBar/Info/ChannelToTeamModal/StepOne.js index 7ba4d379802..2643a2ca786 100644 --- a/client/views/teams/modals/ChannelToTeamModal/StepOne.js +++ b/client/views/room/contextualBar/Info/ChannelToTeamModal/StepOne.js @@ -1,9 +1,9 @@ import React from 'react'; import { Box } from '@rocket.chat/fuselage'; -import { useTranslation } from '../../../../contexts/TranslationContext'; -import GenericModal from '../../../../components/GenericModal'; -import TeamAutocomplete from '../../TeamAutocomplete'; +import { useTranslation } from '../../../../../contexts/TranslationContext'; +import GenericModal from '../../../../../components/GenericModal'; +import TeamAutocomplete from '../../../../teams/contextualBar/TeamAutocomplete'; const StepOne = ({ diff --git a/client/views/teams/modals/ChannelToTeamModal/StepTwo.js b/client/views/room/contextualBar/Info/ChannelToTeamModal/StepTwo.js similarity index 75% rename from client/views/teams/modals/ChannelToTeamModal/StepTwo.js rename to client/views/room/contextualBar/Info/ChannelToTeamModal/StepTwo.js index 4c0f25a66c3..0fb8c13f576 100644 --- a/client/views/teams/modals/ChannelToTeamModal/StepTwo.js +++ b/client/views/room/contextualBar/Info/ChannelToTeamModal/StepTwo.js @@ -1,8 +1,8 @@ import React from 'react'; import { Box } from '@rocket.chat/fuselage'; -import { useTranslation } from '../../../../contexts/TranslationContext'; -import GenericModal from '../../../../components/GenericModal'; +import { useTranslation } from '../../../../../contexts/TranslationContext'; +import GenericModal from '../../../../../components/GenericModal'; const StepTwo = ({ onClose, diff --git a/client/views/teams/modals/ConvertToTeamModal.js b/client/views/room/contextualBar/Info/ConvertToTeamModal.js similarity index 72% rename from client/views/teams/modals/ConvertToTeamModal.js rename to client/views/room/contextualBar/Info/ConvertToTeamModal.js index a539b73e3e2..2020efd8bbc 100644 --- a/client/views/teams/modals/ConvertToTeamModal.js +++ b/client/views/room/contextualBar/Info/ConvertToTeamModal.js @@ -1,7 +1,7 @@ import React from 'react'; -import GenericModal from '../../../components/GenericModal'; -import { useTranslation } from '../../../contexts/TranslationContext'; +import GenericModal from '../../../../components/GenericModal'; +import { useTranslation } from '../../../../contexts/TranslationContext'; const ChannelToTeamModal = ({ onClose, diff --git a/client/views/room/contextualBar/Info/RoomInfo/RoomInfo.js b/client/views/room/contextualBar/Info/RoomInfo/RoomInfo.js index 116ec42ae34..a7bfebab192 100644 --- a/client/views/room/contextualBar/Info/RoomInfo/RoomInfo.js +++ b/client/views/room/contextualBar/Info/RoomInfo/RoomInfo.js @@ -16,8 +16,8 @@ import { RoomManager } from '../../../../../../app/ui-utils/client/lib/RoomManag import { usePermission } from '../../../../../contexts/AuthorizationContext'; import WarningModal from '../../../../admin/apps/WarningModal'; import MarkdownText from '../../../../../components/MarkdownText'; -import ChannelToTeamModal from '../../../../teams/modals/ChannelToTeamModal/ChannelToTeamModal'; -import ConvertToTeamModal from '../../../../teams/modals/ConvertToTeamModal'; +import ChannelToTeamModal from '../ChannelToTeamModal/ChannelToTeamModal'; +import ConvertToTeamModal from '../ConvertToTeamModal'; import { useTabBarClose } from '../../../providers/ToolboxProvider'; import { useEndpointActionExperimental } from '../../../../../hooks/useEndpointAction'; import InfoPanel, { RetentionPolicyCallout } from '../../../../InfoPanel'; diff --git a/client/views/room/contextualBar/RoomMembers/AddUsers/AddUsers.js b/client/views/room/contextualBar/RoomMembers/AddUsers/AddUsers.js index 5d07cc423af..11303f0da0e 100644 --- a/client/views/room/contextualBar/RoomMembers/AddUsers/AddUsers.js +++ b/client/views/room/contextualBar/RoomMembers/AddUsers/AddUsers.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React from 'react'; import { Field, Button } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; @@ -16,7 +16,6 @@ export const AddUsers = ({ onClickSave, value, onChange, - errors, }) => { const t = useTranslation(); @@ -30,10 +29,7 @@ export const AddUsers = ({ {t('Choose_users')} - - {errors.users && - {errors.users} - } + @@ -46,10 +42,10 @@ export const AddUsers = ({ export default ({ rid, onClickBack, + reload, }) => { const t = useTranslation(); const dispatchToastMessage = useToastMessageDispatch(); - const [errors, setErrors] = useState({}); const onClickClose = useTabBarClose(); const saveAction = useMethod('addUsersToRoom'); @@ -69,21 +65,14 @@ export default ({ }); const handleSave = useMutableCallback(async () => { - if (users.length < 1) { - return setErrors({ - users: t('Select_at_least_one_user'), - }); - } - try { await saveAction({ rid, users }); dispatchToastMessage({ type: 'success', message: t('Users_added') }); onClickBack(); - } catch (e) { - dispatchToastMessage({ type: 'error', message: e }); + reload(); + } catch ({ message }) { + dispatchToastMessage({ type: 'error', message }); } - - setErrors({}); }); return ( @@ -93,7 +82,6 @@ export default ({ onClickSave={handleSave} value={users} onChange={onChangeUsers} - errors={errors} /> ); }; diff --git a/client/views/room/contextualBar/RoomMembers/InviteUsers/InviteUsers.js b/client/views/room/contextualBar/RoomMembers/InviteUsers/InviteUsers.js index 9576badf63c..350ec968ab2 100644 --- a/client/views/room/contextualBar/RoomMembers/InviteUsers/InviteUsers.js +++ b/client/views/room/contextualBar/RoomMembers/InviteUsers/InviteUsers.js @@ -23,14 +23,14 @@ export const InviteUsers = ({ const { copy } = useClipboardWithToast(linkText); return ( - + <> {onClickBack && } {t('Invite_Users')} {onClickClose && } - + {t('Invite_Link')} @@ -45,8 +45,8 @@ export const InviteUsers = ({ {onClickEdit && } - - + + ); }; diff --git a/client/views/room/contextualBar/RoomMembers/List/RoomMembers.js b/client/views/room/contextualBar/RoomMembers/List/RoomMembers.js index 008cde8afc5..c2ecc8d76a0 100644 --- a/client/views/room/contextualBar/RoomMembers/List/RoomMembers.js +++ b/client/views/room/contextualBar/RoomMembers/List/RoomMembers.js @@ -22,23 +22,23 @@ import memoize from 'memoize-one'; import { useTranslation } from '../../../../../contexts/TranslationContext'; import { useUserRoom } from '../../../../../contexts/UserContext'; import VerticalBar from '../../../../../components/VerticalBar'; -import { useMethod } from '../../../../../contexts/ServerContext'; import { AsyncStatePhase } from '../../../../../hooks/useAsyncState'; import { useAtLeastOnePermission } from '../../../../../contexts/AuthorizationContext'; -import { useDataWithLoadMore } from '../../hooks/useDataWithLoadMore'; import { MemberItem } from './components/MemberItem'; import UserInfoWithData from '../../UserInfo'; import InviteUsers from '../InviteUsers/InviteUsers'; import AddUsers from '../AddUsers/AddUsers'; import { useTabBarClose } from '../../../providers/ToolboxProvider'; import ScrollableContentWrapper from '../../../../../components/ScrollableContentWrapper'; +import { useMembersList } from '../../../../hooks/useMembersList'; +import { useRecordList } from '../../../../../hooks/lists/useRecordList'; export const createItemData = memoize((onClickView, rid) => ({ onClickView, rid, })); -const DefaultRow = React.memo(({ user, data, index }) => { +const DefaultRow = React.memo(({ user, data, index, reload }) => { const { onClickView, rid } = data; if (!user) { @@ -53,6 +53,7 @@ const DefaultRow = React.memo(({ user, data, index }) => { status={user.status} name={user.name} onClickView={onClickView} + reload={reload} />; }); @@ -72,6 +73,7 @@ export const RoomMembers = ({ loadMoreItems, renderRow: Row = DefaultRow, rid, + reload, }) => { const t = useTranslation(); const inputRef = useAutoFocus(true); @@ -82,7 +84,7 @@ export const RoomMembers = ({ ], [t]); const itemData = createItemData(onClickView, rid); - const lm = useMutableCallback((start) => loadMoreItems(start + 1, Math.min(50, start + 1 - members.length))); + const lm = useMutableCallback((start) => !loading && loadMoreItems(start)); return ( <> @@ -107,15 +109,16 @@ export const RoomMembers = ({ - { error && - {error} - } - {loading && } + + {error && + {error.message} + } + {!loading && members.length <= 0 && {t('No_results_found')}} {!loading && members.length > 0 && ( - + {t('Showing')}: {members.length} @@ -145,6 +148,7 @@ export const RoomMembers = ({ data={itemData} user={data} index={index} + reload={reload} />} />} @@ -162,11 +166,6 @@ export const RoomMembers = ({ RoomMembers.Option = MemberItem; -const useGetUsersOfRoom = (params) => { - const method = useMethod('getUsersOfRoom'); - return useDataWithLoadMore(useCallback((args) => method(...args), [method]), params); -}; - export default ({ rid, }) => { @@ -179,10 +178,11 @@ export default ({ const [type, setType] = useLocalStorage('members-list-type', 'online'); const [text, setText] = useState(''); - const debouncedText = useDebouncedValue(text, 500); - const params = useMemo(() => [rid, type === 'all', { limit: 50 }, debouncedText], [rid, type, debouncedText]); + const debouncedText = useDebouncedValue(text, 800); + + const { membersList, loadMoreItems, reload } = useMembersList(useMemo(() => ({ rid, type: type === 'all', limit: 50, debouncedText }), [rid, type, debouncedText])); - const { value, phase, more, error } = useGetUsersOfRoom(params); + const { phase, items, itemCount: total } = useRecordList(membersList); const canAddUsers = useAtLeastOnePermission(useMemo(() => [room.t === 'p' ? 'add-user-to-any-p-room' : 'add-user-to-any-c-room', 'add-user-to-joined-room'], [room.t]), rid); @@ -208,12 +208,6 @@ export default ({ const handleBack = useCallback(() => setState({}), [setState]); - const loadMoreItems = useCallback((start, end) => more(([rid, type, , filter]) => [rid, type, { skip: start, limit: end - start }, filter], (prev, next) => ({ - total: next.total, - finished: next.records.length < 50, - records: [...prev.records, ...next.records], - })), [more]); - if (state.tab === 'UserInfo') { return ; } @@ -223,7 +217,7 @@ export default ({ } if (state.tab === 'AddUsers') { - return ; + return ; } return ( @@ -232,16 +226,16 @@ export default ({ loading={phase === AsyncStatePhase.LOADING} type={type} text={text} - error={error} setType={setType} setText={handleTextChange} - members={value?.records} - total={value?.total} + members={items} + total={total} onClickClose={onClickClose} onClickView={viewUser} onClickAdd={canAddUsers && addUser} onClickInvite={canAddUsers && createInvite} loadMoreItems={loadMoreItems} + reload={reload} /> ); }; diff --git a/client/views/room/contextualBar/RoomMembers/List/components/MemberItem.js b/client/views/room/contextualBar/RoomMembers/List/components/MemberItem.js index fd470fbf404..a21d95f04bb 100644 --- a/client/views/room/contextualBar/RoomMembers/List/components/MemberItem.js +++ b/client/views/room/contextualBar/RoomMembers/List/components/MemberItem.js @@ -6,15 +6,14 @@ import { } from '@rocket.chat/fuselage'; import { usePrefersReducedMotion } from '@rocket.chat/fuselage-hooks'; - import { useUserInfoActions } from '../../../../hooks/useUserInfoActions'; import { useActionSpread } from '../../../../../hooks/useActionSpread'; import UserAvatar from '../../../../../../components/avatar/UserAvatar'; import { ReactiveUserStatus } from '../../../../../../components/UserStatus'; import { usePreventProgation } from '../../../../../../hooks/usePreventProgation'; -const UserActions = ({ username, _id, rid }) => { - const { menu: menuOptions } = useActionSpread(useUserInfoActions({ _id, username }, rid), 0); +const UserActions = ({ username, _id, rid, reload }) => { + const { menu: menuOptions } = useActionSpread(useUserInfoActions({ _id, username }, rid, reload), 0); if (!menuOptions) { return null; } @@ -27,7 +26,16 @@ const UserActions = ({ username, _id, rid }) => { />; }; -export const MemberItem = ({ _id, status, name, username, onClickView, style, rid }) => { +export const MemberItem = ({ + _id, + status, + name, + username, + onClickView, + style, + rid, + reload, +}) => { const [showButton, setShowButton] = useState(); const isReduceMotionEnabled = usePrefersReducedMotion(); @@ -50,7 +58,7 @@ export const MemberItem = ({ _id, status, name, username, onClickView, style, ri {name} ({username}) - {showButton ? : : useReactiveValue(useCallback(() => !!RoomRoles.findOne({ rid, 'u._id': uid, roles: role }), [uid, rid, role])); @@ -77,7 +77,7 @@ const WarningModal = ({ text, confirmText, close, confirm, ...props }) => { ; }; -export const useUserInfoActions = (user = {}, rid) => { +export const useUserInfoActions = (user = {}, rid, reload) => { const t = useTranslation(); const dispatchToastMessage = useToastMessageDispatch(); const directRoute = useRoute('direct'); @@ -299,9 +299,10 @@ export const useUserInfoActions = (user = {}, rid) => { userId={user?._id} onClose={closeModal} onCancel={closeModal} - onConfirm={(rooms) => { - removeFromTeam({ teamId: room.teamId, members: [{ userId: user._id }], rooms }); + onConfirm={async (rooms) => { + await removeFromTeam({ teamId: room.teamId, members: [{ userId: user._id }], rooms }); closeModal(); + reload && reload(); }} />); } @@ -310,9 +311,14 @@ export const useUserInfoActions = (user = {}, rid) => { text={t('The_user_will_be_removed_from_s', roomName)} close={closeModal} confirmText={t('Yes_remove_user')} - confirm={() => { removeUserAction({ roomId: rid, userId: uid }); closeModal(); }} + confirm={async () => { + await removeUserAction({ roomId: rid, userId: uid }); + closeModal(); + reload && reload(); + }} />); }); + const removeUserOption = useMemo(() => roomCanRemove && userCanRemove && { label: {room.teamMain ? t('Remove_from_team') : t('Remove_from_room')}, icon: 'sign-out', diff --git a/client/views/teams/modals/CreateTeamModal/CreateTeamModal.tsx b/client/views/teams/CreateTeamModal/CreateTeamModal.tsx similarity index 94% rename from client/views/teams/modals/CreateTeamModal/CreateTeamModal.tsx rename to client/views/teams/CreateTeamModal/CreateTeamModal.tsx index 6efb27b07a0..71816675a8f 100644 --- a/client/views/teams/modals/CreateTeamModal/CreateTeamModal.tsx +++ b/client/views/teams/CreateTeamModal/CreateTeamModal.tsx @@ -3,13 +3,13 @@ import React, { FC, memo, Ref, useCallback, useEffect, useMemo, useState } from import { useMutableCallback, useDebouncedCallback, useAutoFocus } from '@rocket.chat/fuselage-hooks'; import { Box, Modal, ButtonGroup, Button, TextInput, Field, ToggleSwitch } from '@rocket.chat/fuselage'; -import { IUser } from '../../../../../definition/IUser'; -import { useTranslation } from '../../../../contexts/TranslationContext'; -import { useForm } from '../../../../hooks/useForm'; -import { useEndpointActionExperimental } from '../../../../hooks/useEndpointAction'; -import { useSetting } from '../../../../contexts/SettingsContext'; -import { usePermission } from '../../../../contexts/AuthorizationContext'; -import { useMethod } from '../../../../contexts/ServerContext'; +import { IUser } from '../../../../definition/IUser'; +import { useTranslation } from '../../../contexts/TranslationContext'; +import { useForm } from '../../../hooks/useForm'; +import { useEndpointActionExperimental } from '../../../hooks/useEndpointAction'; +import { useSetting } from '../../../contexts/SettingsContext'; +import { usePermission } from '../../../contexts/AuthorizationContext'; +import { useMethod } from '../../../contexts/ServerContext'; import TeamNameInput from './TeamNameInput'; import UsersInput from './UsersInput'; diff --git a/client/views/teams/modals/CreateTeamModal/TeamNameInput.tsx b/client/views/teams/CreateTeamModal/TeamNameInput.tsx similarity index 100% rename from client/views/teams/modals/CreateTeamModal/TeamNameInput.tsx rename to client/views/teams/CreateTeamModal/TeamNameInput.tsx diff --git a/client/views/teams/modals/CreateTeamModal/UsersInput.tsx b/client/views/teams/CreateTeamModal/UsersInput.tsx similarity index 94% rename from client/views/teams/modals/CreateTeamModal/UsersInput.tsx rename to client/views/teams/CreateTeamModal/UsersInput.tsx index f9306525489..f2dbbafa8d6 100644 --- a/client/views/teams/modals/CreateTeamModal/UsersInput.tsx +++ b/client/views/teams/CreateTeamModal/UsersInput.tsx @@ -2,8 +2,8 @@ import { AutoComplete, Box, Option, Options, Chip, AutoCompleteProps } from '@ro import { useDebouncedValue } from '@rocket.chat/fuselage-hooks'; import React, { FC, memo, useCallback, useMemo, useState } from 'react'; -import UserAvatar from '../../../../components/avatar/UserAvatar'; -import { useEndpointData } from '../../../../hooks/useEndpointData'; +import UserAvatar from '../../../components/avatar/UserAvatar'; +import { useEndpointData } from '../../../hooks/useEndpointData'; type UsersInputProps = { value: unknown[]; diff --git a/client/views/teams/modals/CreateTeamModal/index.ts b/client/views/teams/CreateTeamModal/index.ts similarity index 100% rename from client/views/teams/modals/CreateTeamModal/index.ts rename to client/views/teams/CreateTeamModal/index.ts diff --git a/client/views/teams/ChannelDesertionTable.js b/client/views/teams/contextualBar/ChannelDesertionTable.js similarity index 88% rename from client/views/teams/ChannelDesertionTable.js rename to client/views/teams/contextualBar/ChannelDesertionTable.js index ab4e1624c21..dc0cf45b23d 100644 --- a/client/views/teams/ChannelDesertionTable.js +++ b/client/views/teams/contextualBar/ChannelDesertionTable.js @@ -2,10 +2,10 @@ import React from 'react'; import { Box, CheckBox, Table, Icon, Margins } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; -import GenericTable from '../../components/GenericTable'; -import { useRoomIcon } from '../../hooks/useRoomIcon'; -import { useFormatDateAndTime } from '../../hooks/useFormatDateAndTime'; -import { useTranslation } from '../../contexts/TranslationContext'; +import GenericTable from '../../../components/GenericTable'; +import { useRoomIcon } from '../../../hooks/useRoomIcon'; +import { useFormatDateAndTime } from '../../../hooks/useFormatDateAndTime'; +import { useTranslation } from '../../../contexts/TranslationContext'; const ChannelRow = ({ onChange, selected, room, lastOwnerWarning = '', formatDate }) => { const { name, fname, ts, isLastOwner } = room; @@ -64,7 +64,7 @@ const ChannelDesertionTable = ({ fixed={false} pagination={false} > - {({ key, ...room }) => { const roomsArray = Object.values(rooms); diff --git a/client/views/teams/TeamAutocomplete.js b/client/views/teams/contextualBar/TeamAutocomplete.js similarity index 85% rename from client/views/teams/TeamAutocomplete.js rename to client/views/teams/contextualBar/TeamAutocomplete.js index 0fd57414474..d0a3be437ab 100644 --- a/client/views/teams/TeamAutocomplete.js +++ b/client/views/teams/contextualBar/TeamAutocomplete.js @@ -1,9 +1,9 @@ import React, { useMemo, useState } from 'react'; import { AutoComplete, Option, Options } from '@rocket.chat/fuselage'; -import RoomAvatar from '../../components/avatar/RoomAvatar'; -import { useEndpointData } from '../../hooks/useEndpointData'; -import { useUserId } from '../../contexts/UserContext'; +import RoomAvatar from '../../../components/avatar/RoomAvatar'; +import { useEndpointData } from '../../../hooks/useEndpointData'; +import { useUserId } from '../../../contexts/UserContext'; const Avatar = ({ _id, type, avatarETag, test, ...props }) => ; diff --git a/client/views/teams/info/Delete/ChannelDeletionTable.js b/client/views/teams/contextualBar/info/Delete/ChannelDeletionTable.js similarity index 90% rename from client/views/teams/info/Delete/ChannelDeletionTable.js rename to client/views/teams/contextualBar/info/Delete/ChannelDeletionTable.js index 60d3e89b4c4..60dde0ce8bd 100644 --- a/client/views/teams/info/Delete/ChannelDeletionTable.js +++ b/client/views/teams/contextualBar/info/Delete/ChannelDeletionTable.js @@ -2,9 +2,9 @@ import React from 'react'; import { Box, CheckBox, Table, Icon, Margins } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; -import GenericTable from '../../../../components/GenericTable'; -import { useRoomIcon } from '../../../../hooks/useRoomIcon'; -import { useTranslation } from '../../../../contexts/TranslationContext'; +import GenericTable from '../../../../../components/GenericTable'; +import { useRoomIcon } from '../../../../../hooks/useRoomIcon'; +import { useTranslation } from '../../../../../contexts/TranslationContext'; const ChannelRow = ({ onChange, selected, room }) => { const { name, fname, usersCount } = room; diff --git a/client/views/teams/info/Delete/DeleteTeamModal.js b/client/views/teams/contextualBar/info/Delete/DeleteTeamModal.js similarity index 100% rename from client/views/teams/info/Delete/DeleteTeamModal.js rename to client/views/teams/contextualBar/info/Delete/DeleteTeamModal.js diff --git a/client/views/teams/info/Delete/DeleteTeamModal.stories.js b/client/views/teams/contextualBar/info/Delete/DeleteTeamModal.stories.js similarity index 100% rename from client/views/teams/info/Delete/DeleteTeamModal.stories.js rename to client/views/teams/contextualBar/info/Delete/DeleteTeamModal.stories.js diff --git a/client/views/teams/info/Delete/StepOne.js b/client/views/teams/contextualBar/info/Delete/StepOne.js similarity index 73% rename from client/views/teams/info/Delete/StepOne.js rename to client/views/teams/contextualBar/info/Delete/StepOne.js index a1e3c2edc63..0cc80ed6faf 100644 --- a/client/views/teams/info/Delete/StepOne.js +++ b/client/views/teams/contextualBar/info/Delete/StepOne.js @@ -1,8 +1,8 @@ import React from 'react'; import { Box } from '@rocket.chat/fuselage'; -import GenericModal from '../../../../components/GenericModal'; -import { useTranslation } from '../../../../contexts/TranslationContext'; +import GenericModal from '../../../../../components/GenericModal'; +import { useTranslation } from '../../../../../contexts/TranslationContext'; const StepOne = ({ onConfirm, onCancel }) => { const t = useTranslation(); diff --git a/client/views/teams/info/Delete/StepThree.js b/client/views/teams/contextualBar/info/Delete/StepThree.js similarity index 80% rename from client/views/teams/info/Delete/StepThree.js rename to client/views/teams/contextualBar/info/Delete/StepThree.js index 00281c872e5..3a433b682ec 100644 --- a/client/views/teams/info/Delete/StepThree.js +++ b/client/views/teams/contextualBar/info/Delete/StepThree.js @@ -1,8 +1,8 @@ import React from 'react'; -import GenericModal from '../../../../components/GenericModal'; -import RoomLinkList from '../RoomLinkList'; -import { useTranslation } from '../../../../contexts/TranslationContext'; +import GenericModal from '../../../../../components/GenericModal'; +import RoomLinkList from '../../RoomLinkList'; +import { useTranslation } from '../../../../../contexts/TranslationContext'; export const StepThree = ({ deletedRooms, keptRooms, onConfirm, onReturn, onCancel }) => { const t = useTranslation(); diff --git a/client/views/teams/info/Delete/StepTwo.js b/client/views/teams/contextualBar/info/Delete/StepTwo.js similarity index 84% rename from client/views/teams/info/Delete/StepTwo.js rename to client/views/teams/contextualBar/info/Delete/StepTwo.js index 036ec645c2b..d6e80277b80 100644 --- a/client/views/teams/info/Delete/StepTwo.js +++ b/client/views/teams/contextualBar/info/Delete/StepTwo.js @@ -1,8 +1,8 @@ import React from 'react'; -import GenericModal from '../../../../components/GenericModal'; +import GenericModal from '../../../../../components/GenericModal'; import ChannelDeletionTable from './ChannelDeletionTable'; -import { useTranslation } from '../../../../contexts/TranslationContext'; +import { useTranslation } from '../../../../../contexts/TranslationContext'; export const StepTwo = ({ rooms, diff --git a/client/views/teams/info/Delete/index.js b/client/views/teams/contextualBar/info/Delete/index.js similarity index 88% rename from client/views/teams/info/Delete/index.js rename to client/views/teams/contextualBar/info/Delete/index.js index ef217f9332f..59438886cb7 100644 --- a/client/views/teams/info/Delete/index.js +++ b/client/views/teams/contextualBar/info/Delete/index.js @@ -3,7 +3,7 @@ import React, { useMemo } from 'react'; import StepOne from './StepOne'; import StepTwo from './StepTwo'; import StepThree from './StepThree'; -import { useEndpointData } from '../../../../hooks/useEndpointData'; +import { useEndpointData } from '../../../../../hooks/useEndpointData'; import DeleteTeamModal from './DeleteTeamModal'; const DeleteTeamModalWithRooms = ({ teamId, onConfirm, onCancel }) => { diff --git a/client/views/teams/info/Leave/LeaveTeamModal.js b/client/views/teams/contextualBar/info/Leave/LeaveTeamModal.js similarity index 100% rename from client/views/teams/info/Leave/LeaveTeamModal.js rename to client/views/teams/contextualBar/info/Leave/LeaveTeamModal.js diff --git a/client/views/teams/info/Leave/LeaveTeamModal.stories.js b/client/views/teams/contextualBar/info/Leave/LeaveTeamModal.stories.js similarity index 100% rename from client/views/teams/info/Leave/LeaveTeamModal.stories.js rename to client/views/teams/contextualBar/info/Leave/LeaveTeamModal.stories.js diff --git a/client/views/teams/info/Leave/StepOne.js b/client/views/teams/contextualBar/info/Leave/StepOne.js similarity index 85% rename from client/views/teams/info/Leave/StepOne.js rename to client/views/teams/contextualBar/info/Leave/StepOne.js index 9e62e0c2a89..81bc506e43a 100644 --- a/client/views/teams/info/Leave/StepOne.js +++ b/client/views/teams/contextualBar/info/Leave/StepOne.js @@ -1,8 +1,8 @@ import React from 'react'; -import GenericModal from '../../../../components/GenericModal'; +import GenericModal from '../../../../../components/GenericModal'; import ChannelDesertionTable from '../../ChannelDesertionTable'; -import { useTranslation } from '../../../../contexts/TranslationContext'; +import { useTranslation } from '../../../../../contexts/TranslationContext'; export const StepOne = ({ rooms, diff --git a/client/views/teams/info/Leave/StepTwo.js b/client/views/teams/contextualBar/info/Leave/StepTwo.js similarity index 84% rename from client/views/teams/info/Leave/StepTwo.js rename to client/views/teams/contextualBar/info/Leave/StepTwo.js index 022f16c5a88..0be61d5fbeb 100644 --- a/client/views/teams/info/Leave/StepTwo.js +++ b/client/views/teams/contextualBar/info/Leave/StepTwo.js @@ -1,8 +1,8 @@ import React from 'react'; -import GenericModal from '../../../../components/GenericModal'; -import RoomLinkList from '../RoomLinkList'; -import { useTranslation } from '../../../../contexts/TranslationContext'; +import GenericModal from '../../../../../components/GenericModal'; +import RoomLinkList from '../../RoomLinkList'; +import { useTranslation } from '../../../../../contexts/TranslationContext'; export const StepTwo = ({ lastOwnerRooms, keptRooms, onConfirm, onCancel, onClose }) => { const t = useTranslation(); diff --git a/client/views/teams/info/Leave/index.js b/client/views/teams/contextualBar/info/Leave/index.js similarity index 91% rename from client/views/teams/info/Leave/index.js rename to client/views/teams/contextualBar/info/Leave/index.js index dead1f08b1a..5ca352db901 100644 --- a/client/views/teams/info/Leave/index.js +++ b/client/views/teams/contextualBar/info/Leave/index.js @@ -2,8 +2,8 @@ import React, { useContext, useState, useEffect } from 'react'; import StepOne from './StepOne'; import StepTwo from './StepTwo'; -import { useEndpoint } from '../../../../contexts/ServerContext'; -import { UserContext } from '../../../../contexts/UserContext'; +import { useEndpoint } from '../../../../../contexts/ServerContext'; +import { UserContext } from '../../../../../contexts/UserContext'; import LeaveTeamModal from './LeaveTeamModal'; const useJoinedRoomsWithLastOwner = (teamId) => { diff --git a/client/views/teams/info/TeamsInfo.js b/client/views/teams/contextualBar/info/TeamsInfo.js similarity index 87% rename from client/views/teams/info/TeamsInfo.js rename to client/views/teams/contextualBar/info/TeamsInfo.js index e30ea508d15..1cf9e5e9e8d 100644 --- a/client/views/teams/info/TeamsInfo.js +++ b/client/views/teams/contextualBar/info/TeamsInfo.js @@ -2,24 +2,24 @@ import React, { useMemo, useCallback } from 'react'; import { Box, Button, Callout, Option, Menu } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; -import VerticalBar from '../../../components/VerticalBar'; -import RoomAvatar from '../../../components/avatar/RoomAvatar'; -import MarkdownText from '../../../components/MarkdownText'; +import VerticalBar from '../../../../components/VerticalBar'; +import RoomAvatar from '../../../../components/avatar/RoomAvatar'; +import MarkdownText from '../../../../components/MarkdownText'; import DeleteTeamModal from './Delete'; import LeaveTeamModal from './Leave'; -import InfoPanel, { RetentionPolicyCallout } from '../../InfoPanel'; -import { roomTypes, UiTextContext } from '../../../../app/utils'; -import { useTabBarClose, useTabBarOpen } from '../../room/providers/ToolboxProvider'; -import { useEndpointActionExperimental } from '../../../hooks/useEndpointAction'; -import { GenericModalDoNotAskAgain } from '../../../components/GenericModal'; -import { useTranslation } from '../../../contexts/TranslationContext'; -import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext'; -import { useActionSpread } from '../../hooks/useActionSpread'; -import { useRoute } from '../../../contexts/RouterContext'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useSetModal } from '../../../contexts/ModalContext'; -import { useSetting } from '../../../contexts/SettingsContext'; -import { usePermission } from '../../../contexts/AuthorizationContext'; +import InfoPanel, { RetentionPolicyCallout } from '../../../InfoPanel'; +import { roomTypes, UiTextContext } from '../../../../../app/utils'; +import { useTabBarClose, useTabBarOpen } from '../../../room/providers/ToolboxProvider'; +import { useEndpointActionExperimental } from '../../../../hooks/useEndpointAction'; +import { GenericModalDoNotAskAgain } from '../../../../components/GenericModal'; +import { useTranslation } from '../../../../contexts/TranslationContext'; +import { useToastMessageDispatch } from '../../../../contexts/ToastMessagesContext'; +import { useActionSpread } from '../../../hooks/useActionSpread'; +import { useRoute } from '../../../../contexts/RouterContext'; +import { useMethod } from '../../../../contexts/ServerContext'; +import { useSetModal } from '../../../../contexts/ModalContext'; +import { useSetting } from '../../../../contexts/SettingsContext'; +import { usePermission } from '../../../../contexts/AuthorizationContext'; const retentionPolicyMaxAge = { c: 'RetentionPolicy_MaxAge_Channels', diff --git a/client/views/teams/info/TeamsInfo.stories.js b/client/views/teams/contextualBar/info/TeamsInfo.stories.js similarity index 95% rename from client/views/teams/info/TeamsInfo.stories.js rename to client/views/teams/contextualBar/info/TeamsInfo.stories.js index 773ecad6051..dc94755a2ea 100644 --- a/client/views/teams/info/TeamsInfo.stories.js +++ b/client/views/teams/contextualBar/info/TeamsInfo.stories.js @@ -1,6 +1,6 @@ import React from 'react'; -import VerticalBar from '../../../components/VerticalBar'; +import VerticalBar from '../../../../components/VerticalBar'; import { TeamsInfo } from './TeamsInfo'; export default { diff --git a/client/views/teams/info/index.js b/client/views/teams/contextualBar/info/index.js similarity index 75% rename from client/views/teams/info/index.js rename to client/views/teams/contextualBar/info/index.js index 0c3d4550d66..0a6731562d3 100644 --- a/client/views/teams/info/index.js +++ b/client/views/teams/contextualBar/info/index.js @@ -2,12 +2,12 @@ import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; import { Callout } from '@rocket.chat/fuselage'; import React, { useState, useMemo } from 'react'; -import EditChannelWithData from '../../room/contextualBar/Info/EditRoomInfo/EditRoomInfo.js'; -import { AsyncStatePhase } from '../../../hooks/useAsyncState'; -import { useEndpointData } from '../../../hooks/useEndpointData'; -import { useTranslation } from '../../../contexts/TranslationContext'; +import EditChannelWithData from '../../../room/contextualBar/Info/EditRoomInfo/EditRoomInfo.js'; +import { AsyncStatePhase } from '../../../../hooks/useAsyncState'; +import { useEndpointData } from '../../../../hooks/useEndpointData'; +import { useTranslation } from '../../../../contexts/TranslationContext'; import TeamsInfo from './TeamsInfo'; -import VerticalBar from '../../../components/VerticalBar'; +import VerticalBar from '../../../../components/VerticalBar'; export default function TeamsInfoWithRooms({ rid }) { const [editing, setEditing] = useState(false); diff --git a/client/views/teams/info/tabBar.ts b/client/views/teams/contextualBar/info/tabBar.ts similarity index 83% rename from client/views/teams/info/tabBar.ts rename to client/views/teams/contextualBar/info/tabBar.ts index ee8a103aa10..7a30be58b54 100644 --- a/client/views/teams/info/tabBar.ts +++ b/client/views/teams/contextualBar/info/tabBar.ts @@ -1,6 +1,6 @@ import { FC, lazy, LazyExoticComponent } from 'react'; -import { addAction } from '../../room/lib/Toolbox'; +import { addAction } from '../../../room/lib/Toolbox'; addAction('team-info', { groups: ['team'], diff --git a/client/views/teams/members/RemoveUsersModal/RemoveUsersModal.js b/client/views/teams/contextualBar/members/RemoveUsersModal/RemoveUsersModal.js similarity index 87% rename from client/views/teams/members/RemoveUsersModal/RemoveUsersModal.js rename to client/views/teams/contextualBar/members/RemoveUsersModal/RemoveUsersModal.js index b39db266854..d557f58c404 100644 --- a/client/views/teams/members/RemoveUsersModal/RemoveUsersModal.js +++ b/client/views/teams/contextualBar/members/RemoveUsersModal/RemoveUsersModal.js @@ -2,10 +2,11 @@ import React, { useState } from 'react'; import { Box, Margins } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; -import { useTranslation } from '../../../../contexts/TranslationContext'; -import GenericModal from '../../../../components/GenericModal'; +import { useTranslation } from '../../../../../contexts/TranslationContext'; +import GenericModal from '../../../../../components/GenericModal'; import ChannelDesertionTable from '../../ChannelDesertionTable'; -import RoomLinkList from './RoomLinkList'; +import RoomLinkList from '../../RoomLinkList'; +import { usePermission } from '../../../../../contexts/AuthorizationContext'; const STEPS = { LIST_ROOMS: 'LIST_ROOMS', @@ -86,12 +87,12 @@ export const RemoveUsersSecondStep = ({ ; }; -const RemoveUsersModal = ({ +const BaseRemoveUsersModal = ({ onClose, onCancel, onConfirm, rooms, - currentStep = rooms?.length > 0 ? STEPS.LIST_ROOMS : STEPS.CONFIRM_DELETE, + currentStep = rooms?.length === 0 ? STEPS.CONFIRM_DELETE : STEPS.LIST_ROOMS, username, }) => { const [step, setStep] = useState(currentStep); @@ -102,6 +103,8 @@ const RemoveUsersModal = ({ const onContinue = useMutableCallback(() => setStep(STEPS.CONFIRM_DELETE)); const onReturn = useMutableCallback(() => setStep(STEPS.LIST_ROOMS)); + const canViewUserRooms = usePermission('view-all-team-channels'); + const onChangeRoomSelection = useMutableCallback((room) => { if (deletedRooms[room._id]) { setDeletedRooms((deletedRooms) => ({ ...deletedRooms, [room._id]: undefined })); @@ -123,7 +126,7 @@ const RemoveUsersModal = ({ onContinue(); }); - if (step === STEPS.CONFIRM_DELETE) { + if (step === STEPS.CONFIRM_DELETE || !canViewUserRooms) { return ; }; -export default RemoveUsersModal; +export default BaseRemoveUsersModal; diff --git a/client/views/teams/members/RemoveUsersModal/RemoveUsersModal.stories.js b/client/views/teams/contextualBar/members/RemoveUsersModal/RemoveUsersModal.stories.js similarity index 100% rename from client/views/teams/members/RemoveUsersModal/RemoveUsersModal.stories.js rename to client/views/teams/contextualBar/members/RemoveUsersModal/RemoveUsersModal.stories.js diff --git a/client/views/teams/contextualBar/members/RemoveUsersModal/index.js b/client/views/teams/contextualBar/members/RemoveUsersModal/index.js new file mode 100644 index 00000000000..92102bccbb9 --- /dev/null +++ b/client/views/teams/contextualBar/members/RemoveUsersModal/index.js @@ -0,0 +1,40 @@ +import React, { useMemo } from 'react'; +import { Skeleton } from '@rocket.chat/fuselage'; + +import { useEndpointData } from '../../../../../hooks/useEndpointData'; +import BaseRemoveUsersModal from './RemoveUsersModal'; +import GenericModal from '../../../../../components/GenericModal'; +import { useTranslation } from '../../../../../contexts/TranslationContext'; +import { AsyncStatePhase } from '../../../../../lib/asyncState'; + +const initialData = { user: { username: '' } }; + +const RemoveUsersModal = ({ teamId, userId, onClose, onCancel, onConfirm }) => { + const t = useTranslation(); + const { value, phase } = useEndpointData('teams.listRoomsOfUser', useMemo(() => ({ teamId, userId }), [teamId, userId])); + const userDataFetch = useEndpointData('users.info', useMemo(() => ({ userId }), [userId]), initialData); + const { user: { username } } = userDataFetch?.value; + + if (phase === AsyncStatePhase.LOADING) { + return } + confirmText={} + confirmText={t('Cancel')} + onConfirm={onClose} + > + + ; + } + + return ; +}; + +export default RemoveUsersModal; diff --git a/client/views/teams/members/TeamsMembers.js b/client/views/teams/contextualBar/members/TeamsMembers.js similarity index 57% rename from client/views/teams/members/TeamsMembers.js rename to client/views/teams/contextualBar/members/TeamsMembers.js index fc1f2da8bc8..f173b4bd483 100644 --- a/client/views/teams/members/TeamsMembers.js +++ b/client/views/teams/contextualBar/members/TeamsMembers.js @@ -5,21 +5,16 @@ import { useLocalStorage, } from '@rocket.chat/fuselage-hooks'; -import { useTabBarClose } from '../../room/providers/ToolboxProvider'; -import { useUserRoom } from '../../../contexts/UserContext'; -import { useAtLeastOnePermission } from '../../../contexts/AuthorizationContext'; -import UserInfoWithData from '../../room/contextualBar/UserInfo'; -import { AsyncStatePhase } from '../../../hooks/useAsyncState'; -import { RoomMembers } from '../../room/contextualBar/RoomMembers/List/RoomMembers'; -import { useMethod } from '../../../contexts/ServerContext'; -import { useDataWithLoadMore } from '../../room/contextualBar/hooks/useDataWithLoadMore'; -import AddUsers from '../../room/contextualBar/RoomMembers/AddUsers'; -import InviteUsers from '../../room/contextualBar/RoomMembers/InviteUsers'; - -const useGetUsersOfRoom = (params) => { - const method = useMethod('getUsersOfRoom'); - return useDataWithLoadMore(useCallback((args) => method(...args), [method]), params); -}; +import { useTabBarClose } from '../../../room/providers/ToolboxProvider'; +import { useUserRoom } from '../../../../contexts/UserContext'; +import { useAtLeastOnePermission } from '../../../../contexts/AuthorizationContext'; +import UserInfoWithData from '../../../room/contextualBar/UserInfo'; +import { AsyncStatePhase } from '../../../../hooks/useAsyncState'; +import { RoomMembers } from '../../../room/contextualBar/RoomMembers/List/RoomMembers'; +import AddUsers from '../../../room/contextualBar/RoomMembers/AddUsers'; +import InviteUsers from '../../../room/contextualBar/RoomMembers/InviteUsers'; +import { useMembersList } from '../../../hooks/useMembersList'; +import { useRecordList } from '../../../../hooks/lists/useRecordList'; const TeamMembers = ({ rid, @@ -35,9 +30,10 @@ const TeamMembers = ({ const [text, setText] = useState(''); const debouncedText = useDebouncedValue(text, 500); - const params = useMemo(() => [rid, type === 'all', { limit: 50 }, debouncedText], [rid, type, debouncedText]); - const { value, phase, more, error } = useGetUsersOfRoom(params); + const { membersList, loadMoreItems, reload } = useMembersList(useMemo(() => ({ rid, type: type === 'all', limit: 50, debouncedText }), [rid, type, debouncedText])); + + const { phase, items, itemCount: total } = useRecordList(membersList); const canAddUsers = useAtLeastOnePermission(useMemo(() => [room.t === 'p' ? 'add-user-to-any-p-room' : 'add-user-to-any-c-room', 'add-user-to-joined-room'], [room.t]), rid); @@ -63,12 +59,6 @@ const TeamMembers = ({ const handleBack = useCallback(() => setState({}), [setState]); - const loadMoreItems = useCallback((start, end) => more(([rid, type, , filter]) => [rid, type, { skip: start, limit: end - start }, filter], (prev, next) => ({ - total: next.total, - finished: next.records.length < 50, - records: [...prev.records, ...next.records], - })), [more]); - if (state.tab === 'UserInfo') { return ; } @@ -78,7 +68,7 @@ const TeamMembers = ({ } if (state.tab === 'AddUsers') { - return ; + return ; } return ( @@ -87,16 +77,16 @@ const TeamMembers = ({ loading={phase === AsyncStatePhase.LOADING} type={type} text={text} - error={error} setType={setType} setText={handleTextChange} - members={value?.records} - total={value?.total} + members={items} + total={total} onClickClose={onClickClose} onClickView={viewUser} onClickAdd={canAddUsers && addUser} onClickInvite={canAddUsers && createInvite} loadMoreItems={loadMoreItems} + reload={reload} /> ); }; diff --git a/client/views/teams/members/index.js b/client/views/teams/contextualBar/members/index.js similarity index 100% rename from client/views/teams/members/index.js rename to client/views/teams/contextualBar/members/index.js diff --git a/client/views/teams/members/tabBar.ts b/client/views/teams/contextualBar/members/tabBar.ts similarity index 80% rename from client/views/teams/members/tabBar.ts rename to client/views/teams/contextualBar/members/tabBar.ts index 2f8493f7ce8..c7863e6afb2 100644 --- a/client/views/teams/members/tabBar.ts +++ b/client/views/teams/contextualBar/members/tabBar.ts @@ -1,6 +1,6 @@ import { lazy } from 'react'; -import { addAction } from '../../room/lib/Toolbox'; +import { addAction } from '../../../room/lib/Toolbox'; addAction('team-members', { groups: ['team'], diff --git a/client/views/teams/index.js b/client/views/teams/index.js index 25c82ee0492..9c6ed6238a9 100644 --- a/client/views/teams/index.js +++ b/client/views/teams/index.js @@ -1,4 +1,3 @@ import './contextualBar/channels/tabBar'; -import './info/tabBar.ts'; -import './members/tabBar'; -import './info'; +import './contextualBar/info/tabBar'; +import './contextualBar/members/tabBar'; diff --git a/client/views/teams/info/RoomLinkList.js b/client/views/teams/info/RoomLinkList.js deleted file mode 100644 index e51198fef07..00000000000 --- a/client/views/teams/info/RoomLinkList.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; - -import { roomTypes } from '../../../../app/utils'; - -const RoomLinkList = ({ rooms }) => { - const roomsArray = Object.values(rooms); - return roomsArray.map((room, i) => <> - - #{roomTypes.getRoomName(room.t, room)} - - {i === roomsArray.length - 1 ? '.' : ', '} - ); -}; - -export default RoomLinkList; diff --git a/client/views/teams/members/RemoveUsersModal/index.js b/client/views/teams/members/RemoveUsersModal/index.js deleted file mode 100644 index 0e94c49f019..00000000000 --- a/client/views/teams/members/RemoveUsersModal/index.js +++ /dev/null @@ -1,56 +0,0 @@ -import React, { useMemo } from 'react'; -import { Skeleton } from '@rocket.chat/fuselage'; - -import { useEndpointData } from '../../../../hooks/useEndpointData'; -import BaseRemoveUsersModal, { RemoveUsersSecondStep } from './RemoveUsersModal'; -import GenericModal from '../../../../components/GenericModal'; -import { usePermission } from '../../../../contexts/AuthorizationContext'; -import { useTranslation } from '../../../../contexts/TranslationContext'; -import { AsyncStatePhase } from '../../../../lib/asyncState'; - -const RemoveUsersModalWithRooms = ({ teamId, userId, username, onClose, onCancel, onConfirm }) => { - const { value } = useEndpointData('teams.listRoomsOfUser', useMemo(() => ({ teamId, userId }), [teamId, userId])); - - return ; -}; - -const initialData = { user: { username: '' } }; - -const RemoveUsersModal = (props) => { - const t = useTranslation(); - - const { userId } = props; - - const canViewUserRooms = usePermission('view-all-team-channels'); - - const { value, phase } = useEndpointData('users.info', useMemo(() => ({ userId }), [userId]), initialData); - - const { user: { username } } = value; - - if (phase === AsyncStatePhase.LOADING) { - return } - confirmText={} - confirmText={t('Cancel')} - onConfirm={props.onClose} - > - - ; - } - - if (canViewUserRooms) { - return ; - } - - return ; -}; - -export default RemoveUsersModal; diff --git a/definition/IUser.ts b/definition/IUser.ts index 73072e24de7..9f5f2488134 100644 --- a/definition/IUser.ts +++ b/definition/IUser.ts @@ -1,3 +1,4 @@ +import { IRocketChatRecord } from './IRocketChatRecord'; import { USER_STATUS } from './UserStatus'; export interface ILoginToken { @@ -85,7 +86,7 @@ export interface IRole { _id: string; } -export interface IUser { +export interface IUser extends IRocketChatRecord { _id: string; createdAt: Date; roles: string[]; @@ -107,7 +108,7 @@ export interface IUser { oauth?: { authorizedClients: string[]; }; - _updatedAt?: Date; + _updatedAt: Date; statusLivechat?: string; e2e?: { private_key: string; diff --git a/server/methods/getUsersOfRoom.js b/server/methods/getUsersOfRoom.js index 2f570e7b8ad..efeea2233a4 100644 --- a/server/methods/getUsersOfRoom.js +++ b/server/methods/getUsersOfRoom.js @@ -12,6 +12,7 @@ function findUsers({ rid, status, skip, limit, filter = '' }) { nickname: 1, status: 1, avatarETag: 1, + _updatedAt: 1, }, sort: { statusConnection: -1,