diff --git a/apps/meteor/client/views/admin/settings/inputs/ActionSettingInput.js b/apps/meteor/client/views/admin/settings/inputs/ActionSettingInput.js deleted file mode 100644 index 5d9184cc42fe..000000000000 --- a/apps/meteor/client/views/admin/settings/inputs/ActionSettingInput.js +++ /dev/null @@ -1,31 +0,0 @@ -import { Button, Field } from '@rocket.chat/fuselage'; -import { useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; -import React from 'react'; - -function ActionSettingInput({ _id, actionText, value, disabled, sectionChanged }) { - const t = useTranslation(); - - const dispatchToastMessage = useToastMessageDispatch(); - const actionMethod = useMethod(value); - - const handleClick = async () => { - try { - const data = await actionMethod(); - const args = [data.message].concat(data.params); - dispatchToastMessage({ type: 'success', message: t(...args) }); - } catch (error) { - dispatchToastMessage({ type: 'error', message: error }); - } - }; - - return ( - <> - - + + {sectionChanged && {t('Save_to_enable_this_action')}} + + ); +} + +export default ActionSettingInput; diff --git a/apps/meteor/client/views/admin/settings/inputs/AssetSettingInput.stories.tsx b/apps/meteor/client/views/admin/settings/inputs/AssetSettingInput.stories.tsx index b1fd40410c27..e2d56a891156 100644 --- a/apps/meteor/client/views/admin/settings/inputs/AssetSettingInput.stories.tsx +++ b/apps/meteor/client/views/admin/settings/inputs/AssetSettingInput.stories.tsx @@ -30,7 +30,7 @@ export const WithValue = Template.bind({}); WithValue.args = { _id: 'setting_id', label: 'Label', - value: { src: 'https://rocket.chat/images/logo.svg' }, + value: { url: 'https://rocket.chat/images/logo.svg' }, }; export const WithFileConstraints = Template.bind({}); diff --git a/apps/meteor/client/views/admin/settings/inputs/AssetSettingInput.js b/apps/meteor/client/views/admin/settings/inputs/AssetSettingInput.tsx similarity index 63% rename from apps/meteor/client/views/admin/settings/inputs/AssetSettingInput.js rename to apps/meteor/client/views/admin/settings/inputs/AssetSettingInput.tsx index 2dafe8165263..009a715acccc 100644 --- a/apps/meteor/client/views/admin/settings/inputs/AssetSettingInput.js +++ b/apps/meteor/client/views/admin/settings/inputs/AssetSettingInput.tsx @@ -1,49 +1,57 @@ import { Button, Field, Icon } from '@rocket.chat/fuselage'; import { useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts'; import { Random } from 'meteor/random'; -import React from 'react'; +import React, { ChangeEventHandler, DragEvent, ReactElement } from 'react'; import './AssetSettingInput.css'; -function AssetSettingInput({ _id, label, value = {}, asset, fileConstraints = {} }) { +type AssetSettingInputProps = { + _id: string; + label: string; + value?: { url: string }; + asset?: any; + fileConstraints?: { extensions: string[] }; +}; + +function AssetSettingInput({ _id, label, value, asset, fileConstraints }: AssetSettingInputProps): ReactElement { const t = useTranslation(); const dispatchToastMessage = useToastMessageDispatch(); const setAsset = useMethod('setAsset'); const unsetAsset = useMethod('unsetAsset'); - const handleUpload = (event) => { - event = event.originalEvent || event; + const isDataTransferEvent = (event: T): event is T & DragEvent => + Boolean('dataTransfer' in event && (event as any).dataTransfer.files); + const handleUpload: ChangeEventHandler = (event): void => { let { files } = event.target; + if (!files || files.length === 0) { - if (event.dataTransfer && event.dataTransfer.files) { + if (isDataTransferEvent(event)) { files = event.dataTransfer.files; - } else { - files = []; } } - Object.values(files).forEach((blob) => { + Object.values(files ?? []).forEach((blob) => { dispatchToastMessage({ type: 'info', message: t('Uploading_file') }); const reader = new FileReader(); reader.readAsBinaryString(blob); - reader.onloadend = async () => { + reader.onloadend = async (): Promise => { try { await setAsset(reader.result, blob.type, asset); dispatchToastMessage({ type: 'success', message: t('File_uploaded') }); } catch (error) { - dispatchToastMessage({ type: 'error', message: error }); + dispatchToastMessage({ type: 'error', message: String(error) }); } }; }); }; - const handleDeleteButtonClick = async () => { + const handleDeleteButtonClick = async (): Promise => { try { await unsetAsset(asset); } catch (error) { - dispatchToastMessage({ type: 'error', message: error }); + dispatchToastMessage({ type: 'error', message: String(error) }); } }; @@ -54,7 +62,7 @@ function AssetSettingInput({ _id, label, value = {}, asset, fileConstraints = {}
- {value.url ? ( + {value?.url ? (
) : (
@@ -62,7 +70,7 @@ function AssetSettingInput({ _id, label, value = {}, asset, fileConstraints = {}
)}
- {value.url ? ( + {value?.url ? (
diff --git a/apps/meteor/client/views/admin/settings/inputs/BooleanSettingInput.js b/apps/meteor/client/views/admin/settings/inputs/BooleanSettingInput.tsx similarity index 52% rename from apps/meteor/client/views/admin/settings/inputs/BooleanSettingInput.js rename to apps/meteor/client/views/admin/settings/inputs/BooleanSettingInput.tsx index 003215074476..6c6a44c832eb 100644 --- a/apps/meteor/client/views/admin/settings/inputs/BooleanSettingInput.js +++ b/apps/meteor/client/views/admin/settings/inputs/BooleanSettingInput.tsx @@ -1,12 +1,31 @@ import { Field, ToggleSwitch } from '@rocket.chat/fuselage'; -import React from 'react'; +import React, { ReactElement, SyntheticEvent } from 'react'; import ResetSettingButton from '../ResetSettingButton'; -function BooleanSettingInput({ _id, label, disabled, readonly, value, hasResetButton, onChangeValue, onResetButtonClick }) { - const handleChange = (event) => { +type BooleanSettingInputProps = { + _id: string; + label: string; + disabled: boolean; + readonly: boolean; + value: boolean; + hasResetButton: boolean; + onChangeValue: (value: boolean) => void; + onResetButtonClick: () => void; +}; +function BooleanSettingInput({ + _id, + label, + disabled, + readonly, + value, + hasResetButton, + onChangeValue, + onResetButtonClick, +}: BooleanSettingInputProps): ReactElement { + const handleChange = (event: SyntheticEvent): void => { const value = event.currentTarget.checked; - onChangeValue && onChangeValue(value); + onChangeValue?.(value); }; return ( diff --git a/apps/meteor/client/views/admin/settings/inputs/CodeMirror.js b/apps/meteor/client/views/admin/settings/inputs/CodeMirror.tsx similarity index 64% rename from apps/meteor/client/views/admin/settings/inputs/CodeMirror.js rename to apps/meteor/client/views/admin/settings/inputs/CodeMirror.tsx index ecd12558b7f6..500a55fc1d47 100644 --- a/apps/meteor/client/views/admin/settings/inputs/CodeMirror.js +++ b/apps/meteor/client/views/admin/settings/inputs/CodeMirror.tsx @@ -1,8 +1,29 @@ import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; -import React, { useEffect, useRef, useState } from 'react'; +import React, { ReactElement, useEffect, useRef, useState } from 'react'; const defaultGutters = ['CodeMirror-linenumbers', 'CodeMirror-foldgutter']; +type CodeMirrorProps = { + id: string; + placeholder?: string; + disabled?: boolean; + autoComplete?: string | undefined; + lineNumbers?: boolean; + lineWrapping?: boolean; + mode?: string; + gutters?: string[]; + foldGutter?: boolean; + matchBrackets?: boolean; + autoCloseBrackets?: boolean; + matchTags?: boolean; + showTrailingSpace?: boolean; + highlightSelectionMatches?: boolean; + readOnly: boolean; + value: string; + defaultValue?: string; + onChange: (value: string) => void; +}; + function CodeMirror({ lineNumbers = true, lineWrapping = true, @@ -19,11 +40,11 @@ function CodeMirror({ defaultValue, onChange, ...props -}) { +}: CodeMirrorProps): ReactElement { const [value, setValue] = useState(valueProp || defaultValue); - const textAreaRef = useRef(); - const editorRef = useRef(); + const textAreaRef = useRef(null); + const editorRef = useRef(null); const handleChange = useMutableCallback(onChange); useEffect(() => { @@ -31,10 +52,12 @@ function CodeMirror({ return; } - const setupCodeMirror = async () => { - const CodeMirror = await import('codemirror/lib/codemirror.js'); + const setupCodeMirror = async (): Promise => { + const jsPath = 'codemirror/lib/codemirror.js'; + const CodeMirror = await import(jsPath); await import('../../../../../app/ui/client/lib/codeMirror/codeMirror'); - await import('codemirror/lib/codemirror.css'); + const cssPath = 'codemirror/lib/codemirror.css'; + await import(cssPath); if (!textAreaRef.current) { return; @@ -54,7 +77,7 @@ function CodeMirror({ readOnly, }); - editorRef.current.on('change', (doc) => { + editorRef?.current?.on('change', (doc: HTMLFormElement) => { const value = doc.getValue(); setValue(value); handleChange(value); @@ -63,7 +86,7 @@ function CodeMirror({ setupCodeMirror(); - return () => { + return (): void => { if (!editorRef.current) { return; } diff --git a/apps/meteor/client/views/admin/settings/inputs/CodeSettingInput.js b/apps/meteor/client/views/admin/settings/inputs/CodeSettingInput.tsx similarity index 75% rename from apps/meteor/client/views/admin/settings/inputs/CodeSettingInput.js rename to apps/meteor/client/views/admin/settings/inputs/CodeSettingInput.tsx index 3c3b8e8ba62c..34cfdb62012f 100644 --- a/apps/meteor/client/views/admin/settings/inputs/CodeSettingInput.js +++ b/apps/meteor/client/views/admin/settings/inputs/CodeSettingInput.tsx @@ -1,11 +1,25 @@ import { Box, Button, Field, Flex } from '@rocket.chat/fuselage'; import { useToggle } from '@rocket.chat/fuselage-hooks'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import React from 'react'; +import React, { ReactElement } from 'react'; import ResetSettingButton from '../ResetSettingButton'; import CodeMirror from './CodeMirror'; +type CodeSettingInputProps = { + _id: string; + label: string; + value?: string; + code: string; + placeholder?: string; + readonly: boolean; + autocomplete: boolean; + disabled: boolean; + hasResetButton: boolean; + onChangeValue: (value: string) => void; + onResetButtonClick: () => void; +}; + function CodeSettingInput({ _id, label, @@ -18,12 +32,12 @@ function CodeSettingInput({ hasResetButton, onChangeValue, onResetButtonClick, -}) { +}: CodeSettingInputProps): ReactElement { const t = useTranslation(); const [fullScreen, toggleFullScreen] = useToggle(false); - const handleChange = (value) => { + const handleChange = (value: string): void => { onChangeValue(value); }; @@ -51,7 +65,7 @@ function CodeSettingInput({ onChange={handleChange} />
-
diff --git a/apps/meteor/client/views/admin/settings/inputs/ColorSettingInput.js b/apps/meteor/client/views/admin/settings/inputs/ColorSettingInput.tsx similarity index 77% rename from apps/meteor/client/views/admin/settings/inputs/ColorSettingInput.js rename to apps/meteor/client/views/admin/settings/inputs/ColorSettingInput.tsx index 6d2c9f001372..31f6da2eef6b 100644 --- a/apps/meteor/client/views/admin/settings/inputs/ColorSettingInput.js +++ b/apps/meteor/client/views/admin/settings/inputs/ColorSettingInput.tsx @@ -1,9 +1,25 @@ import { Box, Field, Flex, InputBox, Margins, TextInput, Select } from '@rocket.chat/fuselage'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import React, { useCallback } from 'react'; +import React, { ReactElement, useCallback } from 'react'; +import type keys from '../../../../../packages/rocketchat-i18n/i18n/en.i18n.json'; import ResetSettingButton from '../ResetSettingButton'; +type ColorSettingInputProps = { + _id: string; + label: string; + value: string; + editor: string; + allowedTypes?: (keyof typeof keys)[]; + placeholder?: string; + readonly?: boolean; + autocomplete?: boolean; + disabled?: boolean; + hasResetButton?: boolean; + onChangeValue?: (value: string) => void; + onChangeEditor?: (value: string) => void; + onResetButtonClick?: () => void; +}; function ColorSettingInput({ _id, label, @@ -18,19 +34,19 @@ function ColorSettingInput({ onChangeValue, onChangeEditor, onResetButtonClick, -}) { +}: ColorSettingInputProps): ReactElement { const t = useTranslation(); const handleChange = useCallback( (event) => { - onChangeValue && onChangeValue(event.currentTarget.value); + onChangeValue?.(event.currentTarget.value); }, [onChangeValue], ); const handleEditorTypeChange = useCallback( (value) => { - onChangeEditor && onChangeEditor(value); + onChangeEditor?.(value); }, [onChangeEditor], ); diff --git a/apps/meteor/client/views/admin/settings/inputs/FontSettingInput.js b/apps/meteor/client/views/admin/settings/inputs/FontSettingInput.tsx similarity index 63% rename from apps/meteor/client/views/admin/settings/inputs/FontSettingInput.js rename to apps/meteor/client/views/admin/settings/inputs/FontSettingInput.tsx index bf93f41c2879..5df670135329 100644 --- a/apps/meteor/client/views/admin/settings/inputs/FontSettingInput.js +++ b/apps/meteor/client/views/admin/settings/inputs/FontSettingInput.tsx @@ -1,8 +1,20 @@ import { Box, Field, Flex, TextInput } from '@rocket.chat/fuselage'; -import React from 'react'; +import React, { FormEventHandler, ReactElement } from 'react'; import ResetSettingButton from '../ResetSettingButton'; +type FontSettingInputProps = { + _id: string; + label: string; + value: string; + placeholder?: string; + readonly?: boolean; + autocomplete?: boolean; + disabled?: boolean; + hasResetButton?: boolean; + onChangeValue?: (value: string) => void; + onResetButtonClick?: () => void; +}; function FontSettingInput({ _id, label, @@ -14,9 +26,9 @@ function FontSettingInput({ hasResetButton, onChangeValue, onResetButtonClick, -}) { - const handleChange = (event) => { - onChangeValue && onChangeValue(event.currentTarget.value); +}: FontSettingInputProps): ReactElement { + const handleChange: FormEventHandler = (event): void => { + onChangeValue?.(event.currentTarget.value); }; return ( diff --git a/apps/meteor/client/views/admin/settings/inputs/GenericSettingInput.js b/apps/meteor/client/views/admin/settings/inputs/GenericSettingInput.tsx similarity index 63% rename from apps/meteor/client/views/admin/settings/inputs/GenericSettingInput.js rename to apps/meteor/client/views/admin/settings/inputs/GenericSettingInput.tsx index d76e39a43684..974994ff6284 100644 --- a/apps/meteor/client/views/admin/settings/inputs/GenericSettingInput.js +++ b/apps/meteor/client/views/admin/settings/inputs/GenericSettingInput.tsx @@ -1,8 +1,20 @@ import { Box, Field, Flex, TextInput } from '@rocket.chat/fuselage'; -import React from 'react'; +import React, { FormEventHandler, ReactElement } from 'react'; import ResetSettingButton from '../ResetSettingButton'; +type GenericSettingInputProps = { + _id: string; + label: string; + value: string; + placeholder?: string; + readonly?: boolean; + autocomplete?: boolean; + disabled?: boolean; + hasResetButton?: boolean; + onChangeValue?: (value: string) => void; + onResetButtonClick?: () => void; +}; function GenericSettingInput({ _id, label, @@ -14,9 +26,9 @@ function GenericSettingInput({ hasResetButton, onChangeValue, onResetButtonClick, -}) { - const handleChange = (event) => { - onChangeValue && onChangeValue(event.currentTarget.value); +}: GenericSettingInputProps): ReactElement { + const handleChange: FormEventHandler = (event): void => { + onChangeValue?.(event.currentTarget.value); }; return ( diff --git a/apps/meteor/client/views/admin/settings/inputs/IntSettingInput.stories.tsx b/apps/meteor/client/views/admin/settings/inputs/IntSettingInput.stories.tsx index 8c7cdd85726a..9c535e27c6eb 100644 --- a/apps/meteor/client/views/admin/settings/inputs/IntSettingInput.stories.tsx +++ b/apps/meteor/client/views/admin/settings/inputs/IntSettingInput.stories.tsx @@ -36,7 +36,7 @@ export const WithValue = Template.bind({}); WithValue.args = { _id: 'setting_id', label: 'Label', - value: 12345, + value: '12345', placeholder: 'Placeholder', }; diff --git a/apps/meteor/client/views/admin/settings/inputs/IntSettingInput.js b/apps/meteor/client/views/admin/settings/inputs/IntSettingInput.tsx similarity index 63% rename from apps/meteor/client/views/admin/settings/inputs/IntSettingInput.js rename to apps/meteor/client/views/admin/settings/inputs/IntSettingInput.tsx index 5c499359427c..4a5257887149 100644 --- a/apps/meteor/client/views/admin/settings/inputs/IntSettingInput.js +++ b/apps/meteor/client/views/admin/settings/inputs/IntSettingInput.tsx @@ -1,8 +1,21 @@ import { Box, Field, Flex, InputBox } from '@rocket.chat/fuselage'; -import React from 'react'; +import React, { FormEventHandler, ReactElement } from 'react'; import ResetSettingButton from '../ResetSettingButton'; +type IntSettingInputProps = { + _id: string; + label: string; + value: string; + placeholder?: string; + readonly?: boolean; + autocomplete?: boolean; + disabled?: boolean; + hasResetButton?: boolean; + onChangeValue?: (value: string | number) => void; + onResetButtonClick?: () => void; +}; + function IntSettingInput({ _id, label, @@ -14,9 +27,9 @@ function IntSettingInput({ onChangeValue, hasResetButton, onResetButtonClick, -}) { - const handleChange = (event) => { - onChangeValue && onChangeValue(parseInt(event.currentTarget.value, 10)); +}: IntSettingInputProps): ReactElement { + const handleChange: FormEventHandler = (event) => { + onChangeValue?.(parseInt(event.currentTarget.value, 10)); }; return ( diff --git a/apps/meteor/client/views/admin/settings/inputs/LanguageSettingInput.stories.tsx b/apps/meteor/client/views/admin/settings/inputs/LanguageSettingInput.stories.tsx index b0d1728028f0..87b78d8aae34 100644 --- a/apps/meteor/client/views/admin/settings/inputs/LanguageSettingInput.stories.tsx +++ b/apps/meteor/client/views/admin/settings/inputs/LanguageSettingInput.stories.tsx @@ -45,10 +45,6 @@ WithResetButton.args = { _id: 'setting_id', label: 'Label', placeholder: 'Placeholder', - value: [ - { key: '1', i18nLabel: '1' }, - { key: '2', i18nLabel: '2' }, - { key: '3', i18nLabel: '3' }, - ], + value: ['1', '2', '3'], hasResetButton: true, }; diff --git a/apps/meteor/client/views/admin/settings/inputs/LanguageSettingInput.js b/apps/meteor/client/views/admin/settings/inputs/LanguageSettingInput.tsx similarity index 68% rename from apps/meteor/client/views/admin/settings/inputs/LanguageSettingInput.js rename to apps/meteor/client/views/admin/settings/inputs/LanguageSettingInput.tsx index f6297a12dc34..850444f2a76e 100644 --- a/apps/meteor/client/views/admin/settings/inputs/LanguageSettingInput.js +++ b/apps/meteor/client/views/admin/settings/inputs/LanguageSettingInput.tsx @@ -1,9 +1,22 @@ import { Box, Field, Flex, Select } from '@rocket.chat/fuselage'; import { useLanguages } from '@rocket.chat/ui-contexts'; -import React from 'react'; +import React, { ReactElement } from 'react'; import ResetSettingButton from '../ResetSettingButton'; +type LanguageSettingInputProps = { + _id: string; + label: string; + value: string | number | string[]; + placeholder?: string; + readonly?: boolean; + autocomplete?: boolean; + disabled?: boolean; + hasResetButton?: boolean; + onChangeValue?: (value: string | number) => void; + onResetButtonClick?: () => void; +}; + function LanguageSettingInput({ _id, label, @@ -15,11 +28,11 @@ function LanguageSettingInput({ hasResetButton, onChangeValue, onResetButtonClick, -}) { +}: LanguageSettingInputProps): ReactElement { const languages = useLanguages(); - const handleChange = (value) => { - onChangeValue(value); + const handleChange = (value: string): void => { + onChangeValue?.(value); }; return ( diff --git a/apps/meteor/client/views/admin/settings/inputs/MultiSelectSettingInput.stories.tsx b/apps/meteor/client/views/admin/settings/inputs/MultiSelectSettingInput.stories.tsx index 286d8e9b2e95..02dde5261c40 100644 --- a/apps/meteor/client/views/admin/settings/inputs/MultiSelectSettingInput.stories.tsx +++ b/apps/meteor/client/views/admin/settings/inputs/MultiSelectSettingInput.stories.tsx @@ -2,7 +2,8 @@ import { Field } from '@rocket.chat/fuselage'; import { ComponentMeta, ComponentStory } from '@storybook/react'; import React from 'react'; -import MultiSelectSettingInput from './MultiSelectSettingInput'; +import type keys from '../../../../../packages/rocketchat-i18n/i18n/en.i18n.json'; +import MultiSelectSettingInput, { valuesOption } from './MultiSelectSettingInput'; export default { title: 'Admin/Settings/Inputs/MultiSelectSettingInput', @@ -17,10 +18,10 @@ export default { const Template: ComponentStory = (args) => ; -const options = [ - { key: '1', i18nLabel: '1' }, - { key: '2', i18nLabel: '2' }, - { key: '3', i18nLabel: '3' }, +const options: valuesOption[] = [ + { key: '1', i18nLabel: '1' as keyof typeof keys }, + { key: '2', i18nLabel: '2' as keyof typeof keys }, + { key: '3', i18nLabel: '3' as keyof typeof keys }, ]; export const Default = Template.bind({}); @@ -45,10 +46,7 @@ WithValue.args = { _id: 'setting_id', label: 'Label', placeholder: 'Placeholder', - value: [ - [1, 'Lorem Ipsum'], - [2, 'Lorem Ipsum'], - ], + value: ['1', 'Lorem Ipsum'], }; export const WithResetButton = Template.bind({}); diff --git a/apps/meteor/client/views/admin/settings/inputs/MultiSelectSettingInput.js b/apps/meteor/client/views/admin/settings/inputs/MultiSelectSettingInput.tsx similarity index 65% rename from apps/meteor/client/views/admin/settings/inputs/MultiSelectSettingInput.js rename to apps/meteor/client/views/admin/settings/inputs/MultiSelectSettingInput.tsx index cce9e1515887..1e049a16660e 100644 --- a/apps/meteor/client/views/admin/settings/inputs/MultiSelectSettingInput.js +++ b/apps/meteor/client/views/admin/settings/inputs/MultiSelectSettingInput.tsx @@ -1,13 +1,29 @@ import { Field, Flex, Box, MultiSelectFiltered, MultiSelect } from '@rocket.chat/fuselage'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import React from 'react'; +import React, { ReactElement } from 'react'; +import type keys from '../../../../../packages/rocketchat-i18n/i18n/en.i18n.json'; import ResetSettingButton from '../ResetSettingButton'; +export type valuesOption = { key: string; i18nLabel: keyof typeof keys }; +type MultiSelectSettingInputProps = { + _id: string; + label: string; + value?: [string, string]; + values: valuesOption[]; + placeholder?: string; + readonly?: boolean; + autocomplete?: boolean; + disabled?: boolean; + hasResetButton?: boolean; + onChangeValue?: (value: string[]) => void; + onResetButtonClick?: () => void; +}; + function MultiSelectSettingInput({ _id, label, - value = [], + value, placeholder, readonly, disabled, @@ -16,11 +32,11 @@ function MultiSelectSettingInput({ onChangeValue, onResetButtonClick, autocomplete, -}) { +}: MultiSelectSettingInputProps): ReactElement { const t = useTranslation(); - const handleChange = (value) => { - onChangeValue && onChangeValue(value); + const handleChange = (value: string[]): void => { + onChangeValue?.(value); // onChangeValue && onChangeValue([...event.currentTarget.querySelectorAll('option')].filter((e) => e.selected).map((el) => el.value)); }; const Component = autocomplete ? MultiSelectFiltered : MultiSelect; diff --git a/apps/meteor/client/views/admin/settings/inputs/PasswordSettingInput.js b/apps/meteor/client/views/admin/settings/inputs/PasswordSettingInput.tsx similarity index 61% rename from apps/meteor/client/views/admin/settings/inputs/PasswordSettingInput.js rename to apps/meteor/client/views/admin/settings/inputs/PasswordSettingInput.tsx index 43e1ba5cdaef..51f3313a2e84 100644 --- a/apps/meteor/client/views/admin/settings/inputs/PasswordSettingInput.js +++ b/apps/meteor/client/views/admin/settings/inputs/PasswordSettingInput.tsx @@ -1,8 +1,21 @@ import { Box, Field, Flex, PasswordInput } from '@rocket.chat/fuselage'; -import React from 'react'; +import React, { EventHandler, ReactElement, SyntheticEvent } from 'react'; import ResetSettingButton from '../ResetSettingButton'; +type PasswordSettingInputProps = { + _id: string; + label: string; + value?: string | number | readonly string[] | undefined; + placeholder?: string; + readonly?: boolean; + autocomplete?: boolean; + disabled?: boolean; + hasResetButton?: boolean; + onChangeValue?: (value: string) => void; + onResetButtonClick?: () => void; +}; + function PasswordSettingInput({ _id, label, @@ -14,9 +27,9 @@ function PasswordSettingInput({ hasResetButton, onChangeValue, onResetButtonClick, -}) { - const handleChange = (event) => { - onChangeValue && onChangeValue(event.currentTarget.value); +}: PasswordSettingInputProps): ReactElement { + const handleChange: EventHandler> = (event) => { + onChangeValue?.(event.currentTarget.value); }; return ( diff --git a/apps/meteor/client/views/admin/settings/inputs/RelativeUrlSettingInput.js b/apps/meteor/client/views/admin/settings/inputs/RelativeUrlSettingInput.tsx similarity index 62% rename from apps/meteor/client/views/admin/settings/inputs/RelativeUrlSettingInput.js rename to apps/meteor/client/views/admin/settings/inputs/RelativeUrlSettingInput.tsx index 9f0c95b339bb..b7bfd80f39e6 100644 --- a/apps/meteor/client/views/admin/settings/inputs/RelativeUrlSettingInput.js +++ b/apps/meteor/client/views/admin/settings/inputs/RelativeUrlSettingInput.tsx @@ -1,9 +1,22 @@ import { Box, Field, Flex, UrlInput } from '@rocket.chat/fuselage'; import { useAbsoluteUrl } from '@rocket.chat/ui-contexts'; -import React from 'react'; +import React, { EventHandler, ReactElement, SyntheticEvent } from 'react'; import ResetSettingButton from '../ResetSettingButton'; +type RelativeUrlSettingInputProps = { + _id: string; + label: string; + value?: string; + placeholder?: string; + readonly?: boolean; + autocomplete?: boolean; + disabled?: boolean; + hasResetButton?: boolean; + onChangeValue?: (value: string) => void; + onResetButtonClick?: () => void; +}; + function RelativeUrlSettingInput({ _id, label, @@ -15,11 +28,11 @@ function RelativeUrlSettingInput({ hasResetButton, onChangeValue, onResetButtonClick, -}) { +}: RelativeUrlSettingInputProps): ReactElement { const getAbsoluteUrl = useAbsoluteUrl(); - const handleChange = (event) => { - onChangeValue && onChangeValue(event.currentTarget.value); + const handleChange: EventHandler> = (event) => { + onChangeValue?.(event.currentTarget.value); }; return ( @@ -35,7 +48,7 @@ function RelativeUrlSettingInput({ void; + onResetButtonClick?: () => void; +}; + function RoomPickSettingInput({ _id, label, @@ -16,14 +30,12 @@ function RoomPickSettingInput({ hasResetButton, onChangeValue, onResetButtonClick, -}) { - value = value || []; - - const wrapperRef = useRef(); +}: RoomPickSettingInputProps): ReactElement { + const wrapperRef = useRef() as MutableRefObject; const valueRef = useRef(value); - const handleRemoveRoomButtonClick = (rid) => () => { - onChangeValue(value.filter(({ _id }) => _id !== rid)); + const handleRemoveRoomButtonClick = (rid: string) => (): void => { + onChangeValue?.((value || []).filter(({ _id }) => _id !== rid)); }; useLayoutEffect(() => { @@ -53,7 +65,7 @@ function RoomPickSettingInput({ template: Template.roomSearch, noMatchTemplate: Template.roomSearchEmpty, matchAll: true, - selector: (match) => ({ name: match }), + selector: (match: string): { name: string } => ({ name: match }), sort: 'name', }, ], @@ -64,12 +76,12 @@ function RoomPickSettingInput({ $('.autocomplete', wrapperRef.current).on('autocompleteselect', (event, doc) => { const { current: value } = valueRef; - onChangeValue([...value.filter(({ _id }) => _id !== doc._id), doc]); - event.currentTarget.value = ''; + onChangeValue?.([...(value || []).filter(({ _id }) => _id !== doc._id), doc]); + (event.currentTarget as HTMLInputElement).value = ''; event.currentTarget.focus(); }); - return () => { + return (): void => { Blaze.remove(view); }; }, [_id, autocomplete, disabled, onChangeValue, placeholder, readonly, valueRef]); @@ -86,7 +98,7 @@ function RoomPickSettingInput({
    - {value.map(({ _id, name }) => ( + {value?.map(({ _id, name }) => (
  • {name}
  • diff --git a/apps/meteor/client/views/admin/settings/inputs/SelectSettingInput.stories.tsx b/apps/meteor/client/views/admin/settings/inputs/SelectSettingInput.stories.tsx index 7cd9cd6e14b1..4a45a5cc89ff 100644 --- a/apps/meteor/client/views/admin/settings/inputs/SelectSettingInput.stories.tsx +++ b/apps/meteor/client/views/admin/settings/inputs/SelectSettingInput.stories.tsx @@ -2,6 +2,7 @@ import { Field } from '@rocket.chat/fuselage'; import { ComponentMeta, ComponentStory } from '@storybook/react'; import React from 'react'; +import type keys from '../../../../../packages/rocketchat-i18n/i18n/en.i18n.json'; import SelectSettingInput from './SelectSettingInput'; export default { @@ -23,9 +24,9 @@ Default.args = { label: 'Label', placeholder: 'Placeholder', values: [ - { key: '1', i18nLabel: '1' }, - { key: '2', i18nLabel: '2' }, - { key: '3', i18nLabel: '3' }, + { key: '1', i18nLabel: '1' as keyof typeof keys }, + { key: '2', i18nLabel: '2' as keyof typeof keys }, + { key: '3', i18nLabel: '3' as keyof typeof keys }, ], }; @@ -35,9 +36,9 @@ Disabled.args = { label: 'Label', placeholder: 'Placeholder', values: [ - { key: '1', i18nLabel: '1' }, - { key: '2', i18nLabel: '2' }, - { key: '3', i18nLabel: '3' }, + { key: '1', i18nLabel: '1' as keyof typeof keys }, + { key: '2', i18nLabel: '2' as keyof typeof keys }, + { key: '3', i18nLabel: '3' as keyof typeof keys }, ], disabled: true, }; @@ -49,9 +50,9 @@ WithValue.args = { placeholder: 'Placeholder', value: '2', values: [ - { key: '1', i18nLabel: '1' }, - { key: '2', i18nLabel: '2' }, - { key: '3', i18nLabel: '3' }, + { key: '1', i18nLabel: '1' as keyof typeof keys }, + { key: '2', i18nLabel: '2' as keyof typeof keys }, + { key: '3', i18nLabel: '3' as keyof typeof keys }, ], }; @@ -61,9 +62,9 @@ WithResetButton.args = { label: 'Label', placeholder: 'Placeholder', values: [ - { key: '1', i18nLabel: '1' }, - { key: '2', i18nLabel: '2' }, - { key: '3', i18nLabel: '3' }, + { key: '1', i18nLabel: '1' as keyof typeof keys }, + { key: '2', i18nLabel: '2' as keyof typeof keys }, + { key: '3', i18nLabel: '3' as keyof typeof keys }, ], hasResetButton: true, }; diff --git a/apps/meteor/client/views/admin/settings/inputs/SelectSettingInput.js b/apps/meteor/client/views/admin/settings/inputs/SelectSettingInput.tsx similarity index 64% rename from apps/meteor/client/views/admin/settings/inputs/SelectSettingInput.js rename to apps/meteor/client/views/admin/settings/inputs/SelectSettingInput.tsx index ab9f846acc84..4671a1a5e54b 100644 --- a/apps/meteor/client/views/admin/settings/inputs/SelectSettingInput.js +++ b/apps/meteor/client/views/admin/settings/inputs/SelectSettingInput.tsx @@ -1,9 +1,24 @@ import { Box, Field, Flex, Select } from '@rocket.chat/fuselage'; import { useTranslation } from '@rocket.chat/ui-contexts'; -import React from 'react'; +import React, { ReactElement } from 'react'; +import type keys from '../../../../../packages/rocketchat-i18n/i18n/en.i18n.json'; import ResetSettingButton from '../ResetSettingButton'; +type SelectSettingInputProps = { + _id: string; + label: string; + value?: string; + values?: { key: string; i18nLabel: keyof typeof keys }[]; + placeholder?: string; + readonly?: boolean; + autocomplete?: boolean; + disabled?: boolean; + hasResetButton?: boolean; + onChangeValue?: (value: string) => void; + onResetButtonClick?: () => void; +}; + function SelectSettingInput({ _id, label, @@ -16,11 +31,11 @@ function SelectSettingInput({ hasResetButton, onChangeValue, onResetButtonClick, -}) { +}: SelectSettingInputProps): ReactElement { const t = useTranslation(); - const handleChange = (value) => { - onChangeValue && onChangeValue(value); + const handleChange = (value: string): void => { + onChangeValue?.(value); }; return ( diff --git a/apps/meteor/client/views/admin/settings/inputs/SelectTimezoneSettingInput.js b/apps/meteor/client/views/admin/settings/inputs/SelectTimezoneSettingInput.tsx similarity index 68% rename from apps/meteor/client/views/admin/settings/inputs/SelectTimezoneSettingInput.js rename to apps/meteor/client/views/admin/settings/inputs/SelectTimezoneSettingInput.tsx index f845957b4df1..0ad6cef76b2e 100644 --- a/apps/meteor/client/views/admin/settings/inputs/SelectTimezoneSettingInput.js +++ b/apps/meteor/client/views/admin/settings/inputs/SelectTimezoneSettingInput.tsx @@ -1,9 +1,22 @@ import { Box, Field, Flex, Select } from '@rocket.chat/fuselage'; import moment from 'moment-timezone'; -import React from 'react'; +import React, { ReactElement } from 'react'; import ResetSettingButton from '../ResetSettingButton'; +type SelectTimezoneSettingInputProps = { + _id: string; + label: string; + value?: string; + placeholder?: string; + readonly?: boolean; + autocomplete?: boolean; + disabled?: boolean; + hasResetButton?: boolean; + onChangeValue?: (value: string) => void; + onResetButtonClick?: () => void; +}; + function SelectTimezoneSettingInput({ _id, label, @@ -15,9 +28,9 @@ function SelectTimezoneSettingInput({ hasResetButton, onChangeValue, onResetButtonClick, -}) { - const handleChange = (value) => { - onChangeValue && onChangeValue(value); +}: SelectTimezoneSettingInputProps): ReactElement { + const handleChange = (value: string): void => { + onChangeValue?.(value); }; return ( diff --git a/apps/meteor/client/views/admin/settings/inputs/StringSettingInput.js b/apps/meteor/client/views/admin/settings/inputs/StringSettingInput.tsx similarity index 69% rename from apps/meteor/client/views/admin/settings/inputs/StringSettingInput.js rename to apps/meteor/client/views/admin/settings/inputs/StringSettingInput.tsx index db36f75b5d2b..a38545666fe4 100644 --- a/apps/meteor/client/views/admin/settings/inputs/StringSettingInput.js +++ b/apps/meteor/client/views/admin/settings/inputs/StringSettingInput.tsx @@ -1,8 +1,22 @@ import { Box, Field, Flex, TextAreaInput, TextInput } from '@rocket.chat/fuselage'; -import React from 'react'; +import React, { EventHandler, ReactElement, SyntheticEvent } from 'react'; import ResetSettingButton from '../ResetSettingButton'; +type StringSettingInputProps = { + _id: string; + label: string; + value?: string; + multiline?: boolean; + placeholder?: string; + readonly?: boolean; + autocomplete?: boolean; + disabled?: boolean; + hasResetButton?: boolean; + onChangeValue?: (value: string) => void; + onResetButtonClick?: () => void; +}; + function StringSettingInput({ _id, label, @@ -15,9 +29,9 @@ function StringSettingInput({ hasResetButton, onChangeValue, onResetButtonClick, -}) { - const handleChange = (event) => { - onChangeValue(event.currentTarget.value); +}: StringSettingInputProps): ReactElement { + const handleChange: EventHandler> = (event) => { + onChangeValue?.(event.currentTarget.value); }; return (