From 511e4b12b883479b50ee5d9202ff24cf02ff6f17 Mon Sep 17 00:00:00 2001 From: Debdut Chakraborty Date: Fri, 22 Apr 2022 14:05:24 +0530 Subject: [PATCH 1/4] Convert UserStatusMenu component to typescript --- .../{UserStatusMenu.js => UserStatusMenu.tsx} | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) rename apps/meteor/client/components/{UserStatusMenu.js => UserStatusMenu.tsx} (54%) diff --git a/apps/meteor/client/components/UserStatusMenu.js b/apps/meteor/client/components/UserStatusMenu.tsx similarity index 54% rename from apps/meteor/client/components/UserStatusMenu.js rename to apps/meteor/client/components/UserStatusMenu.tsx index a95dda44fd58..5674e82cd855 100644 --- a/apps/meteor/client/components/UserStatusMenu.js +++ b/apps/meteor/client/components/UserStatusMenu.tsx @@ -1,17 +1,33 @@ +import { UserStatus as UserStatusType } from '@rocket.chat/core-typings'; import { Button, PositionAnimated, Options, useCursor, Box } from '@rocket.chat/fuselage'; +import type { Placements } from '@rocket.chat/fuselage-hooks'; import React, { useRef, useCallback, useState, useMemo, useEffect } from 'react'; import { useSetting } from '../contexts/SettingsContext'; import { useTranslation } from '../contexts/TranslationContext'; import { UserStatus } from './UserStatus'; -const UserStatusMenu = ({ onChange, optionWidth = undefined, initialStatus = 'offline', placement = 'bottom-end', ...props }) => { +type UserStatusMenuProps = { + margin: string; + onChange: (type: UserStatusType) => void; + initialStatus?: UserStatusType; + optionWidth?: any; + placement?: Placements; +}; + +const UserStatusMenu = ({ + margin, + onChange, + initialStatus = UserStatusType.OFFLINE, + optionWidth = undefined, + placement = 'bottom-end', +}: UserStatusMenuProps): React.ReactElement => { const t = useTranslation(); - const [status, setStatus] = useState(initialStatus); - const allowInvisibleStatus = useSetting('Accounts_AllowInvisibleStatusOption'); + const [status, setStatus] = useState(initialStatus); + const allowInvisibleStatus = useSetting('Accounts_AllowInvisibleStatusOption') as boolean; const options = useMemo(() => { - const renderOption = (status, label) => ( + const renderOption = (status: UserStatusType, label: string): React.ReactElement => ( @@ -20,14 +36,14 @@ const UserStatusMenu = ({ onChange, optionWidth = undefined, initialStatus = 'of ); - const statuses = [ - ['online', renderOption('online', t('Online'))], - ['away', renderOption('away', t('Away'))], - ['busy', renderOption('busy', t('Busy'))], + const statuses: Array<[value: UserStatusType, label: React.ReactElement]> = [ + [UserStatusType.ONLINE, renderOption(UserStatusType.ONLINE, t('Online'))], + [UserStatusType.AWAY, renderOption(UserStatusType.AWAY, t('Away'))], + [UserStatusType.BUSY, renderOption(UserStatusType.BUSY, t('Busy'))], ]; if (allowInvisibleStatus) { - statuses.push(['offline', renderOption('offline', t('Invisible'))]); + statuses.push([UserStatusType.OFFLINE, renderOption(UserStatusType.OFFLINE, t('Invisible'))]); } return statuses; @@ -39,9 +55,13 @@ const UserStatusMenu = ({ onChange, optionWidth = undefined, initialStatus = 'of hide(); }); - const ref = useRef(); + const ref = useRef(null); const onClick = useCallback(() => { - ref.current.focus() & show(); + if (!ref?.current) { + return; + } + (ref.current as HTMLButtonElement).focus(); + show(); ref.current.classList.add('focus-visible'); }, [show]); @@ -58,7 +78,7 @@ const UserStatusMenu = ({ onChange, optionWidth = undefined, initialStatus = 'of return ( <> - From 019fd629b95d1766bf86adc552220d9fe031eb59 Mon Sep 17 00:00:00 2001 From: Debdut Chakraborty Date: Fri, 6 May 2022 14:37:29 +0000 Subject: [PATCH 2/4] change ref type --- apps/meteor/client/components/UserStatusMenu.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/meteor/client/components/UserStatusMenu.tsx b/apps/meteor/client/components/UserStatusMenu.tsx index 5674e82cd855..56ab24a1097c 100644 --- a/apps/meteor/client/components/UserStatusMenu.tsx +++ b/apps/meteor/client/components/UserStatusMenu.tsx @@ -55,12 +55,12 @@ const UserStatusMenu = ({ hide(); }); - const ref = useRef(null); + const ref = useRef(null); const onClick = useCallback(() => { if (!ref?.current) { return; } - (ref.current as HTMLButtonElement).focus(); + ref.current.focus(); show(); ref.current.classList.add('focus-visible'); }, [show]); From 47f021a53722f8641493ea50ccd162bd77642e05 Mon Sep 17 00:00:00 2001 From: Debdut Chakraborty Date: Fri, 6 May 2022 17:33:06 +0000 Subject: [PATCH 3/4] review suggestions --- apps/meteor/client/components/UserStatusMenu.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/meteor/client/components/UserStatusMenu.tsx b/apps/meteor/client/components/UserStatusMenu.tsx index 56ab24a1097c..bfb140a05d4d 100644 --- a/apps/meteor/client/components/UserStatusMenu.tsx +++ b/apps/meteor/client/components/UserStatusMenu.tsx @@ -1,17 +1,17 @@ import { UserStatus as UserStatusType } from '@rocket.chat/core-typings'; import { Button, PositionAnimated, Options, useCursor, Box } from '@rocket.chat/fuselage'; import type { Placements } from '@rocket.chat/fuselage-hooks'; -import React, { useRef, useCallback, useState, useMemo, useEffect } from 'react'; +import React, { ReactElement, ComponentProps, useRef, useCallback, useState, useMemo, useEffect } from 'react'; import { useSetting } from '../contexts/SettingsContext'; import { useTranslation } from '../contexts/TranslationContext'; import { UserStatus } from './UserStatus'; type UserStatusMenuProps = { - margin: string; + margin: ComponentProps['margin']; onChange: (type: UserStatusType) => void; initialStatus?: UserStatusType; - optionWidth?: any; + optionWidth?: ComponentProps['width']; placement?: Placements; }; @@ -21,13 +21,13 @@ const UserStatusMenu = ({ initialStatus = UserStatusType.OFFLINE, optionWidth = undefined, placement = 'bottom-end', -}: UserStatusMenuProps): React.ReactElement => { +}: UserStatusMenuProps): ReactElement => { const t = useTranslation(); const [status, setStatus] = useState(initialStatus); const allowInvisibleStatus = useSetting('Accounts_AllowInvisibleStatusOption') as boolean; const options = useMemo(() => { - const renderOption = (status: UserStatusType, label: string): React.ReactElement => ( + const renderOption = (status: UserStatusType, label: string): ReactElement => ( @@ -36,7 +36,7 @@ const UserStatusMenu = ({ ); - const statuses: Array<[value: UserStatusType, label: React.ReactElement]> = [ + const statuses: Array<[value: UserStatusType, label: ReactElement]> = [ [UserStatusType.ONLINE, renderOption(UserStatusType.ONLINE, t('Online'))], [UserStatusType.AWAY, renderOption(UserStatusType.AWAY, t('Away'))], [UserStatusType.BUSY, renderOption(UserStatusType.BUSY, t('Busy'))], From ff08ff3586cf4221c2daf554b49e9f09d9a31aea Mon Sep 17 00:00:00 2001 From: Tasso Evangelista Date: Mon, 9 May 2022 18:25:56 -0300 Subject: [PATCH 4/4] Remove explicit generic type --- apps/meteor/client/components/UserStatusMenu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/client/components/UserStatusMenu.tsx b/apps/meteor/client/components/UserStatusMenu.tsx index 16aa386bbdf5..c435f26cc8e1 100644 --- a/apps/meteor/client/components/UserStatusMenu.tsx +++ b/apps/meteor/client/components/UserStatusMenu.tsx @@ -22,7 +22,7 @@ const UserStatusMenu = ({ placement = 'bottom-end', }: UserStatusMenuProps): ReactElement => { const t = useTranslation(); - const [status, setStatus] = useState(initialStatus); + const [status, setStatus] = useState(initialStatus); const allowInvisibleStatus = useSetting('Accounts_AllowInvisibleStatusOption') as boolean; const options = useMemo(() => {