diff --git a/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultiple.js b/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultiple.tsx similarity index 57% rename from apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultiple.js rename to apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultiple.tsx index dea3b0ec81c5eab8aefe862ef5eae444a23ebaa4..b96d734be6deba27ace5c8e7f9e2164cd6bb7836 100644 --- a/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultiple.js +++ b/apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultiple.tsx @@ -1,33 +1,47 @@ import { AutoComplete, Box, Option, Chip } from '@rocket.chat/fuselage'; import { useMutableCallback, useDebouncedValue } from '@rocket.chat/fuselage-hooks'; -import React, { memo, useMemo, useState } from 'react'; +import React, { ComponentProps, memo, ReactElement, useMemo, useState } from 'react'; import { useEndpointData } from '../../hooks/useEndpointData'; import UserAvatar from '../avatar/UserAvatar'; -const query = (term = '') => ({ selector: JSON.stringify({ term }) }); +const query = ( + term = '', +): { + selector: string; +} => ({ selector: JSON.stringify({ term }) }); -const UserAutoCompleteMultiple = (props) => { +type UserAutoCompleteMultipleProps = Omit<ComponentProps<typeof AutoComplete>, 'value' | 'filter' | 'onChange'> & + Omit<ComponentProps<typeof Option>, 'value' | 'is' | 'className' | 'onChange'> & { + onChange: (value: unknown, action: 'remove' | undefined) => void; + value: any; + filter?: string; + }; + +const UserAutoCompleteMultiple = ({ onChange, ...props }: UserAutoCompleteMultipleProps): ReactElement => { const [filter, setFilter] = useState(''); const debouncedFilter = useDebouncedValue(filter, 1000); const { value: data } = useEndpointData( 'users.autocomplete', useMemo(() => query(debouncedFilter), [debouncedFilter]), ); - const options = useMemo(() => (data && data.items.map((user) => ({ value: user.username, label: user.name }))) || [], [data]); + + const options = useMemo(() => data?.items.map((user) => ({ value: user.username, label: user.name })) || [], [data]); + const onClickRemove = useMutableCallback((e) => { e.stopPropagation(); e.preventDefault(); - props.onChange(e.currentTarget.value, 'remove'); + onChange?.(e.currentTarget.value, 'remove'); }); return ( <AutoComplete {...props} + onChange={onChange} filter={filter} setFilter={setFilter} - renderSelected={({ value: selected }) => - selected?.map((value) => ( + renderSelected={({ value: selected }): ReactElement => + selected?.map((value: any) => ( <Chip key={value} {...props} height='x20' value={value} onClick={onClickRemove} mie='x4'> <UserAvatar size='x20' username={value} /> <Box is='span' margin='none' mis='x4'> @@ -36,7 +50,7 @@ const UserAutoCompleteMultiple = (props) => { </Chip> )) } - renderItem={({ value, label, ...props }) => ( + renderItem={({ value, label, ...props }): ReactElement => ( <Option key={value} {...props}> <Option.Avatar> <UserAvatar username={value} size='x20' /> diff --git a/apps/meteor/client/sidebar/header/CreateDirectMessage.tsx b/apps/meteor/client/sidebar/header/CreateDirectMessage.tsx index 566360cc15207512476f1b64e39b54e38df5335c..01375f00eda3b9f0e2d0d190a8762a3e8d058297 100644 --- a/apps/meteor/client/sidebar/header/CreateDirectMessage.tsx +++ b/apps/meteor/client/sidebar/header/CreateDirectMessage.tsx @@ -20,7 +20,7 @@ const CreateDirectMessage: FC<CreateDirectMessageProps> = ({ onClose }) => { const createDirect = useEndpointActionExperimental('POST', 'dm.create'); - const onChangeUsers = useMutableCallback((value: Username, action: string) => { + const onChangeUsers = useMutableCallback((value: Username | any, action: 'remove' | undefined) => { if (!action) { if (users.includes(value)) { return;