Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore: Convert apps/meteor/client/views/admin/settings/inputs folder #25427

Merged
merged 25 commits into from
May 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
14d1687
Convert ActionSettingInput to tsx
juliajforesti May 6, 2022
53c0c8f
Convert BooleanSettingInput to tsx
juliajforesti May 6, 2022
620f6f7
convert CodeSettingInput to tsx
juliajforesti May 6, 2022
0ae4baf
convert ColorSettingInput to tsx
juliajforesti May 6, 2022
ce284dc
convert FontSettingInput to tsx
juliajforesti May 6, 2022
1c41e68
convert GenericSettingInput to tsx
juliajforesti May 6, 2022
323b75a
convert IntSettingInput to tsx
juliajforesti May 6, 2022
3245681
convert LanguageSettingInput to tsx
juliajforesti May 6, 2022
6c33426
convert MultiSelectSettingInput to tsx
juliajforesti May 6, 2022
80970b1
fix
juliajforesti May 6, 2022
591d4e2
fix
juliajforesti May 6, 2022
4424f3f
fix
juliajforesti May 10, 2022
a1efb40
Merge branch 'develop' of https://github.com/RocketChat/Rocket.Chat i…
juliajforesti May 11, 2022
b5a6828
merge
juliajforesti May 11, 2022
cac7532
import from ui-context
juliajforesti May 12, 2022
4845f1e
fix context import
juliajforesti May 12, 2022
34859dc
fix import
juliajforesti May 12, 2022
5e60dae
Convert StringSettingInput, SelectTimezoneSettingInput, SelectSetting…
juliajforesti May 12, 2022
8f1ec7e
fix
juliajforesti May 13, 2022
5b964d1
AssetSettingInput ts convert
juliajforesti May 13, 2022
dd8826e
fix SelectSettingInput stories
juliajforesti May 13, 2022
c98ce15
fix AssetSettingInput stories
juliajforesti May 13, 2022
702682f
convert RoomPickSettingInput
juliajforesti May 13, 2022
6bcf4a4
fix
juliajforesti May 13, 2022
4c4d749
Merge branch 'develop' of https://github.com/RocketChat/Rocket.Chat i…
juliajforesti May 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Field } from '@rocket.chat/fuselage';
import { ServerMethods } from '@rocket.chat/ui-contexts';
import { ComponentMeta, ComponentStory } from '@storybook/react';
import React from 'react';

import type keys from '../../../../../packages/rocketchat-i18n/i18n/en.i18n.json';
import ActionSettingInput from './ActionSettingInput';

export default {
Expand All @@ -15,22 +17,22 @@ const Template: ComponentStory<typeof ActionSettingInput> = (args) => <ActionSet
export const Default = Template.bind({});
Default.args = {
_id: 'setting_id',
actionText: 'Action text',
value: 'methodName',
actionText: 'Action text' as keyof typeof keys,
value: 'methodName' as keyof ServerMethods,
};

export const Disabled = Template.bind({});
Disabled.args = {
_id: 'setting_id',
actionText: 'Action text',
value: 'methodName',
actionText: 'Action text' as keyof typeof keys,
value: 'methodName' as keyof ServerMethods,
disabled: true,
};

export const WithinChangedSection = Template.bind({});
WithinChangedSection.args = {
_id: 'setting_id',
actionText: 'Action text',
value: 'methodName',
actionText: 'Action text' as keyof typeof keys,
value: 'methodName' as keyof ServerMethods,
sectionChanged: true,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Button, Field } from '@rocket.chat/fuselage';
import { useMethod, ServerMethods, useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts';
import React, { ReactElement } from 'react';

import type keys from '../../../../../packages/rocketchat-i18n/i18n/en.i18n.json';

type ActionSettingInputProps = {
_id: string;
actionText: keyof typeof keys;
value: keyof ServerMethods;
disabled: boolean;
sectionChanged: boolean;
};
function ActionSettingInput({ _id, actionText, value, disabled, sectionChanged }: ActionSettingInputProps): ReactElement {
const t = useTranslation();

const dispatchToastMessage = useToastMessageDispatch();
const actionMethod = useMethod(value);

const handleClick = async (): Promise<void> => {
try {
const data: { message: keyof typeof keys; params: string[] } = await actionMethod();

dispatchToastMessage({ type: 'success', message: t(data.message, ...data.params) });
} catch (error) {
dispatchToastMessage({ type: 'error', message: String(error) });
}
};

return (
<>
<Field.Row>
<Button data-qa-setting-id={_id} disabled={disabled || sectionChanged} primary onClick={handleClick}>
{t(actionText)}
</Button>
</Field.Row>
{sectionChanged && <Field.Hint>{t('Save_to_enable_this_action')}</Field.Hint>}
</>
);
}

export default ActionSettingInput;
Original file line number Diff line number Diff line change
Expand Up @@ -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({});
Expand Down
Original file line number Diff line number Diff line change
@@ -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 = <T,>(event: T): event is T & DragEvent<HTMLInputElement> =>
Boolean('dataTransfer' in event && (event as any).dataTransfer.files);

const handleUpload: ChangeEventHandler<HTMLInputElement> = (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<void> => {
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<void> => {
try {
await unsetAsset(asset);
} catch (error) {
dispatchToastMessage({ type: 'error', message: error });
dispatchToastMessage({ type: 'error', message: String(error) });
}
};

Expand All @@ -54,15 +62,15 @@ function AssetSettingInput({ _id, label, value = {}, asset, fileConstraints = {}
</Field.Label>
<Field.Row>
<div className='settings-file-preview'>
{value.url ? (
{value?.url ? (
<div className='preview' style={{ backgroundImage: `url(${value.url}?_dc=${Random.id()})` }} />
) : (
<div className='preview no-file background-transparent-light secondary-font-color'>
<Icon name='upload' />
</div>
)}
<div className='action'>
{value.url ? (
{value?.url ? (
<Button onClick={handleDeleteButtonClick}>
<Icon name='trash' />
{t('Delete')}
Expand All @@ -73,7 +81,7 @@ function AssetSettingInput({ _id, label, value = {}, asset, fileConstraints = {}
<input
className='AssetSettingInput__input'
type='file'
accept={fileConstraints.extensions && fileConstraints.extensions.length && `.${fileConstraints.extensions.join(', .')}`}
accept={`.${fileConstraints?.extensions?.join(', .')}`}
onChange={handleUpload}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -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<HTMLInputElement>): void => {
const value = event.currentTarget.checked;
onChangeValue && onChangeValue(value);
onChangeValue?.(value);
};

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -19,22 +40,24 @@ function CodeMirror({
defaultValue,
onChange,
...props
}) {
}: CodeMirrorProps): ReactElement {
const [value, setValue] = useState(valueProp || defaultValue);

const textAreaRef = useRef();
const editorRef = useRef();
const textAreaRef = useRef<HTMLTextAreaElement>(null);
const editorRef = useRef<HTMLFormElement | null>(null);
const handleChange = useMutableCallback(onChange);

useEffect(() => {
if (editorRef.current) {
return;
}

const setupCodeMirror = async () => {
const CodeMirror = await import('codemirror/lib/codemirror.js');
const setupCodeMirror = async (): Promise<void> => {
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;
Expand All @@ -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);
Expand All @@ -63,7 +86,7 @@ function CodeMirror({

setupCodeMirror();

return () => {
return (): void => {
if (!editorRef.current) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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);
};

Expand Down Expand Up @@ -51,7 +65,7 @@ function CodeSettingInput({
onChange={handleChange}
/>
<div className='buttons'>
<Button primary onClick={() => toggleFullScreen()}>
<Button primary onClick={(): void => toggleFullScreen()}>
{fullScreen ? t('Exit_Full_Screen') : t('Full_Screen')}
</Button>
</div>
Expand Down
Loading