refactor: use ToolContent

This commit is contained in:
Ibrahima G. Coulibaly
2025-03-09 17:22:14 +00:00
parent b4322335cc
commit b168edea82
8 changed files with 250 additions and 271 deletions

1
.gitignore vendored
View File

@@ -40,3 +40,4 @@ yarn-error.log*
/playwright-report
dist.zip
.aider*

50
.idea/workspace.xml generated
View File

@@ -4,9 +4,15 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="b30e2810-c4c1-4aad-b134-794e52cc1c7d" name="Changes" comment="chore: remove unnecessary files">
<list default="true" id="b30e2810-c4c1-4aad-b134-794e52cc1c7d" name="Changes" comment="refactor: validateJson">
<change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/tools/string/text-replacer/service.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/tools/string/text-replacer/service.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/tools/list/duplicate/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/tools/list/duplicate/index.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/tools/list/find-unique/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/tools/list/find-unique/index.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/tools/list/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/tools/list/index.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/tools/list/shuffle/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/tools/list/shuffle/index.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/tools/string/join/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/tools/string/join/index.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/tools/string/to-morse/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/tools/string/to-morse/index.tsx" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -23,7 +29,7 @@
<option name="PUSH_AUTO_UPDATE" value="true" />
<option name="RECENT_BRANCH_BY_REPOSITORY">
<map>
<entry key="$PROJECT_DIR$" value="truncate" />
<entry key="$PROJECT_DIR$" value="fork/ady-cf/feature/validate-json" />
</map>
</option>
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
@@ -68,6 +74,13 @@
&quot;number&quot;: 33
},
&quot;lastSeen&quot;: 1741282429036
},
{
&quot;id&quot;: {
&quot;id&quot;: &quot;PR_kwDOMJIfts5zyFTs&quot;,
&quot;number&quot;: 15
},
&quot;lastSeen&quot;: 1741535540953
}
]
}</component>
@@ -77,6 +90,9 @@
&quot;accountId&quot;: &quot;45f8cd51-000f-4ba4-a4c6-c4d96ac9b1e5&quot;
}
}</component>
<component name="HighlightingSettingsPerFile">
<setting file="file://$PROJECT_DIR$/node_modules/react-image-crop/dist/index.d.ts" root0="SKIP_INSPECTION" />
</component>
<component name="KubernetesApiProvider">{
&quot;isMigrated&quot;: true
}</component>
@@ -119,7 +135,7 @@
"git-widget-placeholder": "main",
"ignore.virus.scanning.warn.message": "true",
"kotlin-language-version-configured": "true",
"last_opened_file_path": "C:/Users/Ibrahima/IdeaProjects/omni-tools/.husky",
"last_opened_file_path": "C:/Users/Ibrahima/IdeaProjects/omni-tools/src/pages/tools/list/duplicate/index.tsx",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
@@ -137,7 +153,7 @@
"project.structure.last.edited": "Problems",
"project.structure.proportion": "0.0",
"project.structure.side.proportion": "0.2",
"settings.editor.selected.configurable": "settings.typescriptcompiler",
"settings.editor.selected.configurable": "refactai_advanced_settings",
"ts.external.directory.path": "C:\\Users\\Ibrahima\\IdeaProjects\\omni-tools\\node_modules\\typescript\\lib",
"vue.rearranger.settings.migration": "true"
}
@@ -323,14 +339,8 @@
<workItem from="1740933006573" duration="3679000" />
<workItem from="1741475969294" duration="4215000" />
<workItem from="1741494053121" duration="178000" />
</task>
<task id="LOCAL-00105" summary="feat: compress png">
<option name="closed" value="true" />
<created>1740321912140</created>
<option name="number" value="00105" />
<option name="presentableId" value="LOCAL-00105" />
<option name="project" value="LOCAL" />
<updated>1740321912140</updated>
<workItem from="1741537936314" duration="1294000" />
<workItem from="1741539602311" duration="1240000" />
</task>
<task id="LOCAL-00106" summary="fix: compress png">
<option name="closed" value="true" />
@@ -716,7 +726,15 @@
<option name="project" value="LOCAL" />
<updated>1741492943849</updated>
</task>
<option name="localTasksCounter" value="154" />
<task id="LOCAL-00154" summary="refactor: validateJson">
<option name="closed" value="true" />
<created>1741535390090</created>
<option name="number" value="00154" />
<option name="presentableId" value="LOCAL-00154" />
<option name="project" value="LOCAL" />
<updated>1741535390090</updated>
</task>
<option name="localTasksCounter" value="155" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
@@ -763,7 +781,6 @@
<option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="false" />
<option name="CHECK_NEW_TODO" value="false" />
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
<MESSAGE value="chore: handle enter press on search" />
<MESSAGE value="chore: show tooloptions in example" />
<MESSAGE value="refact: examples" />
<MESSAGE value="fix: examples" />
@@ -788,7 +805,8 @@
<MESSAGE value="feat: change pgn opacity" />
<MESSAGE value="feat: crop png" />
<MESSAGE value="chore: remove unnecessary files" />
<option name="LAST_COMMIT_MESSAGE" value="chore: remove unnecessary files" />
<MESSAGE value="refactor: validateJson" />
<option name="LAST_COMMIT_MESSAGE" value="refactor: validateJson" />
</component>
<component name="XSLT-Support.FileAssociations.UIState">
<expand />

View File

@@ -8,12 +8,5 @@ const validationSchema = Yup.object({
// splitSeparator: Yup.string().required('The separator is required')
});
export default function Duplicate() {
return (
<ToolContent
title="Duplicate"
initialValues={initialValues}
compute={() => {}}
resultComponent={<Box>Lorem ipsum</Box>}
/>
);
return <Box>Lorem ipsum</Box>;
}

View File

@@ -2,9 +2,8 @@ import { Box } from '@mui/material';
import React, { useState } from 'react';
import ToolTextInput from '@components/input/ToolTextInput';
import ToolTextResult from '@components/result/ToolTextResult';
import ToolOptions from '@components/options/ToolOptions';
import ToolContent from '@components/ToolContent';
import { findUniqueCompute, SplitOperatorType } from './service';
import ToolInputAndResult from '@components/ToolInputAndResult';
import SimpleRadio from '@components/options/SimpleRadio';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
@@ -64,95 +63,89 @@ export default function FindUnique() {
};
return (
<Box>
<ToolInputAndResult
input={
<ToolTextInput
title={'Input list'}
value={input}
onChange={setInput}
/>
<ToolContent
title="Find Unique"
initialValues={initialValues}
compute={compute}
input={input}
setInput={setInput}
inputComponent={
<ToolTextInput title={'Input list'} value={input} onChange={setInput} />
}
resultComponent={<ToolTextResult title={'Unique items'} value={result} />}
getGroups={({ values, updateField }) => [
{
title: 'Input List Delimiter',
component: (
<Box>
{splitOperators.map(({ title, description, type }) => (
<SimpleRadio
key={type}
onClick={() => updateField('splitOperatorType', type)}
title={title}
description={description}
checked={values.splitOperatorType === type}
/>
))}
<TextFieldWithDesc
description={'Set a delimiting symbol or regular expression.'}
value={values.splitSeparator}
onOwnChange={(val) => updateField('splitSeparator', val)}
/>
</Box>
)
},
{
title: 'Output List Delimiter',
component: (
<Box>
<TextFieldWithDesc
value={values.joinSeparator}
onOwnChange={(value) => updateField('joinSeparator', value)}
/>
<CheckboxWithDesc
title={'Trim top list items'}
description={
'Remove leading and trailing spaces before comparing items'
}
checked={values.trimItems}
onChange={(value) => updateField('trimItems', value)}
/>
<CheckboxWithDesc
title={'Skip empty items'}
description={
"Don't include the empty list items in the output."
}
checked={values.deleteEmptyItems}
onChange={(value) => updateField('deleteEmptyItems', value)}
/>
</Box>
)
},
{
title: 'Unique Item Options',
component: (
<Box>
<CheckboxWithDesc
title={'Find Absolutely Unique Items'}
description={
'Display only those items of the list that exist in a single copy.'
}
checked={values.absolutelyUnique}
onChange={(value) => updateField('absolutelyUnique', value)}
/>
<CheckboxWithDesc
title={'Case Sensitive Items'}
description={
'Output items with different case as unique elements in the list.'
}
checked={values.caseSensitive}
onChange={(value) => updateField('caseSensitive', value)}
/>
</Box>
)
}
result={<ToolTextResult title={'Unique items'} value={result} />}
/>
<ToolOptions
compute={compute}
getGroups={({ values, updateField }) => [
{
title: 'Input List Delimiter',
component: (
<Box>
{splitOperators.map(({ title, description, type }) => (
<SimpleRadio
key={type}
onClick={() => updateField('splitOperatorType', type)}
title={title}
description={description}
checked={values.splitOperatorType === type}
/>
))}
<TextFieldWithDesc
description={'Set a delimiting symbol or regular expression.'}
value={values.splitSeparator}
onOwnChange={(val) => updateField('splitSeparator', val)}
/>
</Box>
)
},
{
title: 'Output List Delimiter',
component: (
<Box>
<TextFieldWithDesc
value={values.joinSeparator}
onOwnChange={(value) => updateField('joinSeparator', value)}
/>
<CheckboxWithDesc
title={'Trim top list items'}
description={
'Remove leading and trailing spaces before comparing items'
}
checked={values.trimItems}
onChange={(value) => updateField('trimItems', value)}
/>
<CheckboxWithDesc
title={'Skip empty items'}
description={
"Don't include the empty list items in the output."
}
checked={values.deleteEmptyItems}
onChange={(value) => updateField('deleteEmptyItems', value)}
/>
</Box>
)
},
{
title: 'Unique Item Options',
component: (
<Box>
<CheckboxWithDesc
title={'Find Absolutely Unique Items'}
description={
'Display only those items of the list that exist in a single copy.'
}
checked={values.absolutelyUnique}
onChange={(value) => updateField('absolutelyUnique', value)}
/>
<CheckboxWithDesc
title={'Case Sensitive Items'}
description={
'Output items with different case as unique elements in the list.'
}
checked={values.caseSensitive}
onChange={(value) => updateField('caseSensitive', value)}
/>
</Box>
)
}
]}
initialValues={initialValues}
input={input}
/>
</Box>
]}
/>
);
}

View File

@@ -11,15 +11,15 @@ import { tool as listShuffle } from './shuffle/meta';
import { tool as listSort } from './sort/meta';
export const listTools = [
listSort, // TODO: Check if uses ToolContent - Needs update to use ToolContent - Implemented ToolContent
listSort,
// listUnwrap,
listReverse, // TODO: Check if uses ToolContent - Needs update to use ToolContent
listFindUnique, // TODO: Check if uses ToolContent - Needs update to use ToolContent
listFindMostPopular, // TODO: Check if uses ToolContent - Needs update to use ToolContent
listGroup, // TODO: Check if uses ToolContent - Needs update to use ToolContent
listReverse,
listFindUnique,
listFindMostPopular,
listGroup,
// listWrap,
listRotate, // TODO: Check if uses ToolContent - Needs update to use ToolContent
listShuffle // TODO: Check if uses ToolContent - Needs update to use ToolContent
listRotate,
listShuffle
// listTruncate,
// listDuplicate
];

View File

@@ -2,12 +2,11 @@ import { Box } from '@mui/material';
import React, { useState } from 'react';
import ToolTextInput from '@components/input/ToolTextInput';
import ToolTextResult from '@components/result/ToolTextResult';
import ToolOptions from '@components/options/ToolOptions';
import ToolContent from '@components/ToolContent';
import { shuffleList, SplitOperatorType } from './service';
import ToolInputAndResult from '@components/ToolInputAndResult';
import SimpleRadio from '@components/options/SimpleRadio';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import { isNumber } from '../../../../utils/string';
import { isNumber } from '@utils/string';
const initialValues = {
splitOperatorType: 'symbol' as SplitOperatorType,
@@ -51,69 +50,65 @@ export default function Shuffle() {
};
return (
<Box>
<ToolInputAndResult
input={
<ToolTextInput
title={'Input list'}
value={input}
onChange={setInput}
/>
<ToolContent
title="Shuffle"
initialValues={initialValues}
compute={compute}
input={input}
setInput={setInput}
inputComponent={
<ToolTextInput title={'Input list'} value={input} onChange={setInput} />
}
resultComponent={
<ToolTextResult title={'Shuffled list'} value={result} />
}
getGroups={({ values, updateField }) => [
{
title: 'Input list separator',
component: (
<Box>
{splitOperators.map(({ title, description, type }) => (
<SimpleRadio
key={type}
onClick={() => updateField('splitOperatorType', type)}
title={title}
description={description}
checked={values.splitOperatorType === type}
/>
))}
<TextFieldWithDesc
description={'Set a delimiting symbol or regular expression.'}
value={values.splitSeparator}
onOwnChange={(val) => updateField('splitSeparator', val)}
/>
</Box>
)
},
{
title: 'Shuffled List Length',
component: (
<Box>
<TextFieldWithDesc
description={'Output this many random items'}
value={values.length}
onOwnChange={(val) => updateField('length', val)}
/>
</Box>
)
},
{
title: 'Shuffled List Separator',
component: (
<Box>
<TextFieldWithDesc
value={values.joinSeparator}
onOwnChange={(value) => updateField('joinSeparator', value)}
description={'Use this separator in the randomized list.'}
/>
</Box>
)
}
result={<ToolTextResult title={'Shuffled list'} value={result} />}
/>
<ToolOptions
compute={compute}
getGroups={({ values, updateField }) => [
{
title: 'Input list separator',
component: (
<Box>
{splitOperators.map(({ title, description, type }) => (
<SimpleRadio
key={type}
onClick={() => updateField('splitOperatorType', type)}
title={title}
description={description}
checked={values.splitOperatorType === type}
/>
))}
<TextFieldWithDesc
description={'Set a delimiting symbol or regular expression.'}
value={values.splitSeparator}
onOwnChange={(val) => updateField('splitSeparator', val)}
/>
</Box>
)
},
{
title: 'Shuffled List Length',
component: (
<Box>
<TextFieldWithDesc
description={'Output this many random items'}
value={values.length}
onOwnChange={(val) => updateField('length', val)}
/>
</Box>
)
},
{
title: 'Shuffled List Separator',
component: (
<Box>
<TextFieldWithDesc
value={values.joinSeparator}
onOwnChange={(value) => updateField('joinSeparator', value)}
description={'Use this separator in the randomized list.'}
/>
</Box>
)
}
]}
initialValues={initialValues}
input={input}
/>
</Box>
]}
/>
);
}

View File

@@ -1,20 +1,13 @@
import { Box } from '@mui/material';
import React, { useRef, useState } from 'react';
import React, { useState } from 'react';
import * as Yup from 'yup';
import ToolTextInput from '@components/input/ToolTextInput';
import ToolTextResult from '@components/result/ToolTextResult';
import ToolOptions, { GetGroupsType } from '@components/options/ToolOptions';
import ToolContent from '@components/ToolContent';
import { GetGroupsType } from '@components/options/ToolOptions';
import { mergeText } from './service';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
import ToolInputAndResult from '@components/ToolInputAndResult';
import ToolInfo from '@components/ToolInfo';
import Separator from '@components/Separator';
import ToolExamples, {
CardExampleType
} from '@components/examples/ToolExamples';
import { FormikProps } from 'formik';
import { CardExampleType } from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';
const initialValues = {
@@ -116,7 +109,6 @@ s
export default function JoinText({ title }: ToolComponentProps) {
const [input, setInput] = useState<string>('');
const [result, setResult] = useState<string>('');
const formRef = useRef<FormikProps<InitialValuesType>>(null);
const compute = (optionsValues: InitialValuesType, input: any) => {
const { joinCharacter, deleteBlank, deleteTrailing } = optionsValues;
setResult(mergeText(input, deleteBlank, deleteTrailing, joinCharacter));
@@ -151,36 +143,27 @@ export default function JoinText({ title }: ToolComponentProps) {
}
];
return (
<Box>
<ToolInputAndResult
input={
<ToolTextInput
title={'Text Pieces'}
value={input}
onChange={setInput}
/>
}
result={<ToolTextResult title={'Joined Text'} value={result} />}
/>
<ToolOptions
formRef={formRef}
compute={compute}
getGroups={getGroups}
initialValues={initialValues}
input={input}
/>
<ToolInfo
title="What Is a Text Joiner?"
description="With this tool you can join parts of the text together. It takes a list of text values, separated by newlines, and merges them together. You can set the character that will be placed between the parts of the combined text. Also, you can ignore all empty lines and remove spaces and tabs at the end of all lines. Textabulous!"
/>
<Separator backgroundColor="#5581b5" margin="50px" />
<ToolExamples
title={title}
exampleCards={exampleCards}
getGroups={getGroups}
formRef={formRef}
setInput={setInput}
/>
</Box>
<ToolContent
title={title}
initialValues={initialValues}
compute={compute}
input={input}
setInput={setInput}
inputComponent={
<ToolTextInput
title={'Text Pieces'}
value={input}
onChange={setInput}
/>
}
resultComponent={<ToolTextResult title={'Joined Text'} value={result} />}
getGroups={getGroups}
toolInfo={{
title: 'What Is a Text Joiner?',
description:
'With this tool you can join parts of the text together. It takes a list of text values, separated by newlines, and merges them together. You can set the character that will be placed between the parts of the combined text. Also, you can ignore all empty lines and remove spaces and tabs at the end of all lines. Textabulous!'
}}
exampleCards={exampleCards}
/>
);
}

View File

@@ -1,11 +1,9 @@
import { Box } from '@mui/material';
import ToolContent from '@components/ToolContent';
import React, { useState } from 'react';
import ToolTextInput from '@components/input/ToolTextInput';
import ToolTextResult from '@components/result/ToolTextResult';
import ToolOptions from '@components/options/ToolOptions';
import { compute } from './service';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import ToolInputAndResult from '@components/ToolInputAndResult';
const initialValues = {
dotSymbol: '.',
@@ -22,42 +20,40 @@ export default function ToMorse() {
};
return (
<Box>
<ToolInputAndResult
input={<ToolTextInput value={input} onChange={setInput} />}
result={<ToolTextResult title={'Morse code'} value={result} />}
/>
<ToolOptions
compute={computeOptions}
getGroups={({ values, updateField }) => [
{
title: 'Short Signal',
component: (
<TextFieldWithDesc
description={
'Symbol that will correspond to the dot in Morse code.'
}
value={values.dotSymbol}
onOwnChange={(val) => updateField('dotSymbol', val)}
/>
)
},
{
title: 'Long Signal',
component: (
<TextFieldWithDesc
description={
'Symbol that will correspond to the dash in Morse code.'
}
value={values.dashSymbol}
onOwnChange={(val) => updateField('dashSymbol', val)}
/>
)
}
]}
initialValues={initialValues}
input={input}
/>
</Box>
<ToolContent
title="To Morse"
initialValues={initialValues}
compute={computeOptions}
input={input}
setInput={setInput}
inputComponent={<ToolTextInput value={input} onChange={setInput} />}
resultComponent={<ToolTextResult title={'Morse code'} value={result} />}
getGroups={({ values, updateField }) => [
{
title: 'Short Signal',
component: (
<TextFieldWithDesc
description={
'Symbol that will correspond to the dot in Morse code.'
}
value={values.dotSymbol}
onOwnChange={(val) => updateField('dotSymbol', val)}
/>
)
},
{
title: 'Long Signal',
component: (
<TextFieldWithDesc
description={
'Symbol that will correspond to the dash in Morse code.'
}
value={values.dashSymbol}
onOwnChange={(val) => updateField('dashSymbol', val)}
/>
)
}
]}
/>
);
}