diff --git a/apps/meteor/client/components/UserCard/UserCard.tsx b/apps/meteor/client/components/UserCard/UserCard.tsx index 0e79fd03e664..bff7c0747c7e 100644 --- a/apps/meteor/client/components/UserCard/UserCard.tsx +++ b/apps/meteor/client/components/UserCard/UserCard.tsx @@ -1,7 +1,7 @@ import { css } from '@rocket.chat/css-in-js'; import { Box, IconButton, Skeleton } from '@rocket.chat/fuselage'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import React, { forwardRef, ReactNode, ComponentProps } from 'react'; +import React, { forwardRef, ReactNode, ComponentProps, MouseEvent } from 'react'; import MarkdownText from '../MarkdownText'; import * as Status from '../UserStatus'; @@ -22,7 +22,7 @@ const clampStyle = css` type UserCardProps = { className?: string; style?: ComponentProps['style']; - open?: () => void; + open?: (e: MouseEvent) => void; name?: string; username?: string; etag?: string; diff --git a/apps/meteor/client/components/UserCard/UserCardAction.tsx b/apps/meteor/client/components/UserCard/UserCardAction.tsx index 816dc9aed17f..d006382e457e 100644 --- a/apps/meteor/client/components/UserCard/UserCardAction.tsx +++ b/apps/meteor/client/components/UserCard/UserCardAction.tsx @@ -1,10 +1,7 @@ -import { IconButton, Icon } from '@rocket.chat/fuselage'; +import { IconButton } from '@rocket.chat/fuselage'; import React, { ReactElement, ComponentProps } from 'react'; -type UserCardActionProps = { - label?: string; - icon: ComponentProps['name']; -}; +type UserCardActionProps = ComponentProps; const UserCardAction = ({ label, icon, ...props }: UserCardActionProps): ReactElement => ( diff --git a/apps/meteor/client/views/hooks/useActionSpread.ts b/apps/meteor/client/views/hooks/useActionSpread.ts index b1c2fddc9e9b..e742aefda53b 100644 --- a/apps/meteor/client/views/hooks/useActionSpread.ts +++ b/apps/meteor/client/views/hooks/useActionSpread.ts @@ -20,7 +20,9 @@ const mapOptions = ([key, { action, label, icon }]: [string, Action]): [string, ]; export const useActionSpread = ( - actions: Action[], + actions: { + [key: string]: Action; + }, size = 2, ): { actions: [string, Action][]; menu: { [id: string]: MenuOption } | undefined } => useMemo(() => { diff --git a/apps/meteor/client/views/room/UserCard/index.js b/apps/meteor/client/views/room/UserCard/UserCardWithData.tsx similarity index 72% rename from apps/meteor/client/views/room/UserCard/index.js rename to apps/meteor/client/views/room/UserCard/UserCardWithData.tsx index 839326f8fefd..78bd7855f62b 100644 --- a/apps/meteor/client/views/room/UserCard/index.js +++ b/apps/meteor/client/views/room/UserCard/UserCardWithData.tsx @@ -1,7 +1,8 @@ +import { IRoom } from '@rocket.chat/core-typings'; import { PositionAnimated, AnimatedVisibility, Menu, Option } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; -import { useSetting, useRolesDescription, useTranslation } from '@rocket.chat/ui-contexts'; -import React, { useMemo, useRef } from 'react'; +import { useSetting, useRolesDescription } from '@rocket.chat/ui-contexts'; +import React, { useMemo, useRef, ReactElement } from 'react'; import { Backdrop } from '../../../components/Backdrop'; import LocalTime from '../../../components/LocalTime'; @@ -12,17 +13,20 @@ import { useEndpointData } from '../../../hooks/useEndpointData'; import { useActionSpread } from '../../hooks/useActionSpread'; import { useUserInfoActions } from '../hooks/useUserInfoActions'; -const UserCardWithData = ({ username, onClose, target, open, rid }) => { - const ref = useRef(target); +type UserCardWithDataProps = { + username: string; + onClose: () => void; + target: Element; + open: (e: Event) => void; + rid: IRoom['_id']; +}; +const UserCardWithData = ({ username, onClose, target, open, rid }: UserCardWithDataProps): ReactElement => { + const ref = useRef(target); const getRoles = useRolesDescription(); - - const t = useTranslation(); - const showRealNames = useSetting('UI_Use_Real_Name'); const query = useMemo(() => ({ username }), [username]); - const { value: data, phase: state } = useEndpointData('/v1/users.info', query); ref.current = target; @@ -31,19 +35,16 @@ const UserCardWithData = ({ username, onClose, target, open, rid }) => { const loading = state === AsyncStatePhase.LOADING; const defaultValue = loading ? undefined : null; - const { user } = data || { user: {} }; - const { _id, name = username, roles = defaultValue, - status = null, - statusText = status, + statusText, bio = defaultValue, utcOffset = defaultValue, nickname, avatarETag, - } = user; + } = data?.user || {}; return { _id, @@ -52,19 +53,20 @@ const UserCardWithData = ({ username, onClose, target, open, rid }) => { roles: roles && getRoles(roles).map((role, index) => {role}), bio, etag: avatarETag, - localTime: Number.isInteger(utcOffset) && , - status: , + localTime: utcOffset && Number.isInteger(utcOffset) && , + status: _id && , customStatus: statusText, nickname, }; }, [data, username, showRealNames, state, getRoles]); const handleOpen = useMutableCallback((e) => { - open && open(e); - onClose && onClose(); + open?.(e); + onClose?.(); }); - const { actions: actionsDefinition, menu: menuOptions } = useActionSpread(useUserInfoActions(user, rid)); + const userActions = useUserInfoActions({ _id: user._id ?? '', username: user.username }, rid); + const { actions: actionsDefinition, menu: menuOptions } = useActionSpread(userActions); const menu = useMemo(() => { if (!menuOptions) { @@ -74,17 +76,17 @@ const UserCardWithData = ({ username, onClose, target, open, rid }) => { return (