refactor: tool options components

This commit is contained in:
Ibrahima G. Coulibaly
2024-06-23 15:14:14 +01:00
parent 4604c32a9c
commit 1c1ec0c1e6
8 changed files with 142 additions and 135 deletions

25
.idea/workspace.xml generated
View File

@@ -4,10 +4,15 @@
<option name="autoReloadType" value="SELECTIVE" /> <option name="autoReloadType" value="SELECTIVE" />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="b30e2810-c4c1-4aad-b134-794e52cc1c7d" name="Changes" comment="chore: tools by category"> <list default="true" id="b30e2810-c4c1-4aad-b134-794e52cc1c7d" name="Changes" comment="feat: copy and import file">
<change afterPath="$PROJECT_DIR$/src/components/options/CheckboxWithDesc.tsx" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/components/options/RadioWithTextField.tsx" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/components/options/TextFieldWithDesc.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/ToolOptions.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/options/ToolOptions.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/input/ToolTextInput.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/input/ToolTextInput.tsx" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/components/input/ToolTextInput.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/input/ToolTextInput.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/string/split/meta.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/string/split/meta.ts" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/pages/string/join/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/string/join/index.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/string/split/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/string/split/index.tsx" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -80,6 +85,7 @@
<recent name="C:\Users\HP\IdeaProjects\omni-tools\src" /> <recent name="C:\Users\HP\IdeaProjects\omni-tools\src" />
</key> </key>
<key name="MoveFile.RECENT_KEYS"> <key name="MoveFile.RECENT_KEYS">
<recent name="C:\Users\HP\IdeaProjects\omni-tools\src\components\options" />
<recent name="C:\Users\HP\IdeaProjects\omni-tools\src\pages\images\png\change-colors-in-png" /> <recent name="C:\Users\HP\IdeaProjects\omni-tools\src\pages\images\png\change-colors-in-png" />
<recent name="C:\Users\HP\IdeaProjects\omni-tools\src\tools" /> <recent name="C:\Users\HP\IdeaProjects\omni-tools\src\tools" />
</key> </key>
@@ -129,7 +135,7 @@
<workItem from="1719006951159" duration="2377000" /> <workItem from="1719006951159" duration="2377000" />
<workItem from="1719021128819" duration="3239000" /> <workItem from="1719021128819" duration="3239000" />
<workItem from="1719083989394" duration="7971000" /> <workItem from="1719083989394" duration="7971000" />
<workItem from="1719092003308" duration="9218000" /> <workItem from="1719092003308" duration="11298000" />
</task> </task>
<task id="LOCAL-00001" summary="feat: use vite and ts"> <task id="LOCAL-00001" summary="feat: use vite and ts">
<option name="closed" value="true" /> <option name="closed" value="true" />
@@ -347,7 +353,15 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1719102365836</updated> <updated>1719102365836</updated>
</task> </task>
<option name="localTasksCounter" value="28" /> <task id="LOCAL-00028" summary="feat: copy and import file">
<option name="closed" value="true" />
<created>1719103372481</created>
<option name="number" value="00028" />
<option name="presentableId" value="LOCAL-00028" />
<option name="project" value="LOCAL" />
<updated>1719103372481</updated>
</task>
<option name="localTasksCounter" value="29" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
@@ -391,7 +405,8 @@
<MESSAGE value="feat: search tools" /> <MESSAGE value="feat: search tools" />
<MESSAGE value="fix: deploy message" /> <MESSAGE value="fix: deploy message" />
<MESSAGE value="chore: tools by category" /> <MESSAGE value="chore: tools by category" />
<option name="LAST_COMMIT_MESSAGE" value="chore: tools by category" /> <MESSAGE value="feat: copy and import file" />
<option name="LAST_COMMIT_MESSAGE" value="feat: copy and import file" />
</component> </component>
<component name="XSLT-Support.FileAssociations.UIState"> <component name="XSLT-Support.FileAssociations.UIState">
<expand /> <expand />

View File

@@ -23,7 +23,7 @@ export default function ToolTextInput({
.writeText(value) .writeText(value)
.then(() => showSnackBar('Text copied', 'success')) .then(() => showSnackBar('Text copied', 'success'))
.catch((err) => { .catch((err) => {
showSnackBar('Failed to copy: ', err); showSnackBar('Failed to copy: ' + err, 'error');
}); });
}; };
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => { const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {

View File

@@ -0,0 +1,34 @@
import React from 'react';
import { Box, Checkbox, FormControlLabel, Typography } from '@mui/material';
const CheckboxWithDesc = ({
title,
description,
checked,
onChange
}: {
title: string;
description: string;
checked: boolean;
onChange: (value: boolean) => void;
}) => {
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
onChange(event.target.checked);
};
return (
<Box>
<FormControlLabel
control={
<Checkbox defaultChecked checked={checked} onChange={handleChange} />
}
label={title}
/>
<Typography fontSize={12} mt={1}>
{description}
</Typography>
</Box>
);
};
export default CheckboxWithDesc;

View File

@@ -0,0 +1,46 @@
import { SplitOperatorType } from '../../pages/string/split/service';
import { Box, Stack } from '@mui/material';
import { Field } from 'formik';
import Typography from '@mui/material/Typography';
import React from 'react';
import TextFieldWithDesc from './TextFieldWithDesc';
const RadioWithTextField = <T,>({
fieldName,
type,
title,
onTypeChange,
value,
description,
onTextChange
}: {
fieldName: string;
title: string;
type: T;
onTypeChange: (val: T) => void;
value: string;
description: string;
onTextChange: (value: string) => void;
}) => {
const onChange = () => onTypeChange(type);
return (
<Box>
<Stack
direction={'row'}
sx={{ mt: 2, mb: 1, cursor: 'pointer' }}
onClick={onChange}
alignItems={'center'}
spacing={1}
>
<Field type="radio" name={fieldName} value={type} onChange={onChange} />
<Typography>{title}</Typography>
</Stack>
<TextFieldWithDesc
value={value}
onChange={onTextChange}
description={description}
/>
</Box>
);
};
export default RadioWithTextField;

View File

@@ -0,0 +1,31 @@
import { Box, TextField } from '@mui/material';
import Typography from '@mui/material/Typography';
import React from 'react';
const TextFieldWithDesc = ({
description,
value,
onChange,
placeholder
}: {
description: string;
value: string;
onChange: (value: string) => void;
placeholder?: string;
}) => {
return (
<Box>
<TextField
placeholder={placeholder}
sx={{ backgroundColor: 'white' }}
value={value}
onChange={(event) => onChange(event.target.value)}
/>
<Typography fontSize={12} mt={1}>
{description}
</Typography>
</Box>
);
};
export default TextFieldWithDesc;

View File

@@ -12,9 +12,11 @@ import { Formik, FormikProps, useFormikContext } from 'formik';
import * as Yup from 'yup'; import * as Yup from 'yup';
import ToolTextInput from '../../../components/input/ToolTextInput'; import ToolTextInput from '../../../components/input/ToolTextInput';
import ToolTextResult from '../../../components/result/ToolTextResult'; import ToolTextResult from '../../../components/result/ToolTextResult';
import ToolOptions from '../../../components/ToolOptions'; import ToolOptions from '../../../components/options/ToolOptions';
import { mergeText } from './service'; import { mergeText } from './service';
import { CustomSnackBarContext } from '../../../contexts/CustomSnackBarContext'; import { CustomSnackBarContext } from '../../../contexts/CustomSnackBarContext';
import TextFieldWithDesc from '../../../components/options/TextFieldWithDesc';
import CheckboxWithDesc from '../../../components/options/CheckboxWithDesc';
const initialValues = { const initialValues = {
joinCharacter: '', joinCharacter: '',
@@ -52,66 +54,8 @@ const blankTrailingOptions: {
} }
]; ];
const InputWithDesc = ({
placeholder,
description,
value,
onChange
}: {
placeholder: string;
description: string;
value: string;
onChange: (value: string) => void;
}) => {
return (
<Box width={240}>
<TextField
sx={{ backgroundColor: 'white', padding: 0 }}
size="small"
placeholder={placeholder}
value={value}
onChange={(event) => onChange(event.target.value)}
/>
<Typography fontSize={12} mt={1}>
{description}
</Typography>
</Box>
);
};
const CheckboxWithDesc = ({
title,
description,
checked,
onChange
}: {
title: string;
description: string;
checked: boolean;
onChange: (value: boolean) => void;
}) => {
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
onChange(event.target.checked);
};
return (
<Box>
<FormControlLabel
control={
<Checkbox defaultChecked checked={checked} onChange={handleChange} />
}
label={title}
/>
<Typography fontSize={12} mt={1}>
{description}
</Typography>
</Box>
);
};
export default function JoinText() { export default function JoinText() {
const [input, setInput] = useState<string>(''); const [input, setInput] = useState<string>('');
const formRef = useRef<FormikProps<typeof initialValues>>(null);
const { showSnackBar } = useContext(CustomSnackBarContext); const { showSnackBar } = useContext(CustomSnackBarContext);
const [result, setResult] = useState<string>(''); const [result, setResult] = useState<string>('');
@@ -121,7 +65,6 @@ export default function JoinText() {
useEffect(() => { useEffect(() => {
try { try {
console.log('Form values:', values['joinCharacter']);
setResult(mergeText(input, deleteBlank, deleteTrailing, joinCharacter)); setResult(mergeText(input, deleteBlank, deleteTrailing, joinCharacter));
} catch (exception: unknown) { } catch (exception: unknown) {
if (exception instanceof Error) if (exception instanceof Error)
@@ -129,7 +72,6 @@ export default function JoinText() {
} }
}, [values, input]); }, [values, input]);
console.log('deleteBlank', deleteBlank);
return null; return null;
}; };
@@ -151,7 +93,6 @@ export default function JoinText() {
<Formik <Formik
initialValues={initialValues} initialValues={initialValues}
validationSchema={validationSchema} validationSchema={validationSchema}
innerRef={formRef}
onSubmit={() => {}} onSubmit={() => {}}
> >
{({ setFieldValue, values }) => ( {({ setFieldValue, values }) => (
@@ -159,7 +100,7 @@ export default function JoinText() {
<FormikListenerComponent input={input} /> <FormikListenerComponent input={input} />
<Box> <Box>
<Typography fontSize={22}>Text Merged Options</Typography> <Typography fontSize={22}>Text Merged Options</Typography>
<InputWithDesc <TextFieldWithDesc
placeholder={mergeOptions.placeholder} placeholder={mergeOptions.placeholder}
value={values['joinCharacter']} value={values['joinCharacter']}
onChange={(value) => onChange={(value) =>

View File

@@ -6,9 +6,11 @@ import ToolTextInput from '../../../components/input/ToolTextInput';
import ToolTextResult from '../../../components/result/ToolTextResult'; import ToolTextResult from '../../../components/result/ToolTextResult';
import { Field, Formik, FormikProps, useFormikContext } from 'formik'; import { Field, Formik, FormikProps, useFormikContext } from 'formik';
import * as Yup from 'yup'; import * as Yup from 'yup';
import ToolOptions from '../../../components/ToolOptions'; import ToolOptions from '../../../components/options/ToolOptions';
import { compute, SplitOperatorType } from './service'; import { compute, SplitOperatorType } from './service';
import { CustomSnackBarContext } from '../../../contexts/CustomSnackBarContext'; import { CustomSnackBarContext } from '../../../contexts/CustomSnackBarContext';
import RadioWithTextField from '../../../components/options/RadioWithTextField';
import TextFieldWithDesc from '../../../components/options/TextFieldWithDesc';
const initialValues = { const initialValues = {
splitSeparatorType: 'symbol' as SplitOperatorType, splitSeparatorType: 'symbol' as SplitOperatorType,
@@ -74,72 +76,11 @@ const outputOptions: {
accessor: 'charAfterChunk' accessor: 'charAfterChunk'
} }
]; ];
const CustomRadioButton = ({
fieldName,
type,
title,
onTypeChange,
value,
description,
onTextChange
}: {
fieldName: string;
title: string;
type: SplitOperatorType;
onTypeChange: (val: string) => void;
value: string;
description: string;
onTextChange: (value: string) => void;
}) => {
const onChange = () => onTypeChange(type);
return (
<Box>
<Stack
direction={'row'}
sx={{ mt: 2, mb: 1, cursor: 'pointer' }}
onClick={onChange}
alignItems={'center'}
spacing={1}
>
<Field type="radio" name={fieldName} value={type} onChange={onChange} />
<Typography>{title}</Typography>
</Stack>
<InputWithDesc
value={value}
onChange={onTextChange}
description={description}
/>
</Box>
);
};
const InputWithDesc = ({
description,
value,
onChange
}: {
description: string;
value: string;
onChange: (value: string) => void;
}) => {
return (
<Box>
<TextField
sx={{ backgroundColor: 'white' }}
value={value}
onChange={(event) => onChange(event.target.value)}
/>
<Typography fontSize={12} mt={1}>
{description}
</Typography>
</Box>
);
};
export default function SplitText() { export default function SplitText() {
const [input, setInput] = useState<string>(''); const [input, setInput] = useState<string>('');
const [result, setResult] = useState<string>(''); const [result, setResult] = useState<string>('');
const formRef = useRef<FormikProps<typeof initialValues>>(null); // const formRef = useRef<FormikProps<typeof initialValues>>(null);
const { showSnackBar } = useContext(CustomSnackBarContext); const { showSnackBar } = useContext(CustomSnackBarContext);
const FormikListenerComponent = () => { const FormikListenerComponent = () => {
@@ -197,7 +138,6 @@ export default function SplitText() {
<Formik <Formik
initialValues={initialValues} initialValues={initialValues}
validationSchema={validationSchema} validationSchema={validationSchema}
innerRef={formRef}
onSubmit={() => {}} onSubmit={() => {}}
> >
{({ setFieldValue, values }) => ( {({ setFieldValue, values }) => (
@@ -206,7 +146,7 @@ export default function SplitText() {
<Box> <Box>
<Typography fontSize={22}>Split separator options</Typography> <Typography fontSize={22}>Split separator options</Typography>
{splitOperators.map(({ title, description, type }) => ( {splitOperators.map(({ title, description, type }) => (
<CustomRadioButton <RadioWithTextField
key={type} key={type}
type={type} type={type}
title={title} title={title}
@@ -223,7 +163,7 @@ export default function SplitText() {
<Box> <Box>
<Typography fontSize={22}>Output separator options</Typography> <Typography fontSize={22}>Output separator options</Typography>
{outputOptions.map((option) => ( {outputOptions.map((option) => (
<InputWithDesc <TextFieldWithDesc
key={option.accessor} key={option.accessor}
value={values[option.accessor]} value={values[option.accessor]}
onChange={(value) => setFieldValue(option.accessor, value)} onChange={(value) => setFieldValue(option.accessor, value)}