mirror of
https://github.com/iib0011/omni-tools.git
synced 2025-09-15 03:59:31 +02:00
fix: radio and list sort init
This commit is contained in:
40
.idea/workspace.xml
generated
40
.idea/workspace.xml
generated
@@ -6,12 +6,16 @@
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="b30e2810-c4c1-4aad-b134-794e52cc1c7d" name="Changes" comment="style: lint">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/components/Hero.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/Hero.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/components/options/RadioWithTextField.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/options/RadioWithTextField.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/components/options/SimpleRadio.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/options/SimpleRadio.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/components/options/TextFieldWithDesc.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/options/TextFieldWithDesc.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/pages/list/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/list/index.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/pages/list/sort/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/list/sort/index.tsx" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/pages/list/sort/meta.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/list/sort/meta.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/pages/list/sort/service.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/list/sort/service.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/pages/list/sort/sort.service.test.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/list/sort/sort.service.test.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/utils/string.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils/string.ts" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/pages/number/sum/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/number/sum/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" />
|
||||
<change beforePath="$PROJECT_DIR$/src/tools/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/tools/index.ts" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@@ -61,7 +65,7 @@
|
||||
"Vitest.mergeText.executor": "Run",
|
||||
"Vitest.mergeText.should merge lines and preserve blank lines when deleteBlankLines is false.executor": "Run",
|
||||
"Vitest.mergeText.should merge lines, preserve blank lines and trailing spaces when both deleteBlankLines and deleteTrailingSpaces are false.executor": "Run",
|
||||
"git-widget-placeholder": "chesterkxng",
|
||||
"git-widget-placeholder": "main",
|
||||
"ignore.virus.scanning.warn.message": "true",
|
||||
"kotlin-language-version-configured": "true",
|
||||
"last_opened_file_path": "C:/Users/HP/IdeaProjects/omni-tools/src/assets",
|
||||
@@ -109,7 +113,7 @@
|
||||
<recent name="C:\Users\HP\IdeaProjects\omni-tools\src\tools" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunManager" selected="npm.test">
|
||||
<component name="RunManager" selected="npm.dev">
|
||||
<configuration name="JoinText Component.should merge text pieces with specified join character" type="JavaScriptTestRunnerPlaywright" temporary="true" nameIsGenerated="true">
|
||||
<node-interpreter value="project" />
|
||||
<playwright-package value="$PROJECT_DIR$/node_modules/@playwright/test" />
|
||||
@@ -165,8 +169,8 @@
|
||||
</configuration>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="npm.test" />
|
||||
<item itemvalue="npm.dev" />
|
||||
<item itemvalue="npm.test" />
|
||||
<item itemvalue="npm.lint" />
|
||||
<item itemvalue="npm.test:e2e" />
|
||||
<item itemvalue="Playwright.JoinText Component.should merge text pieces with specified join character" />
|
||||
@@ -206,14 +210,6 @@
|
||||
<workItem from="1719492452780" duration="8000" />
|
||||
<workItem from="1719496624579" duration="6148000" />
|
||||
</task>
|
||||
<task id="LOCAL-00024" summary="feat: search tools">
|
||||
<option name="closed" value="true" />
|
||||
<created>1719095463056</created>
|
||||
<option name="number" value="00024" />
|
||||
<option name="presentableId" value="LOCAL-00024" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1719095463056</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00025" summary="fix: deploy message">
|
||||
<option name="closed" value="true" />
|
||||
<created>1719096461432</created>
|
||||
@@ -598,7 +594,15 @@
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1719499895862</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="73" />
|
||||
<task id="LOCAL-00073" summary="fix: misc">
|
||||
<option name="closed" value="true" />
|
||||
<created>1719510922051</created>
|
||||
<option name="number" value="00073" />
|
||||
<option name="presentableId" value="LOCAL-00073" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1719510922051</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="74" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
@@ -654,9 +658,9 @@
|
||||
<MESSAGE value="refactor: optimize imports" />
|
||||
<MESSAGE value="feat: change gif speed" />
|
||||
<MESSAGE value="chore: remove unused deps" />
|
||||
<MESSAGE value="fix: misc" />
|
||||
<MESSAGE value="style: lint" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="style: lint" />
|
||||
<MESSAGE value="fix: misc" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="fix: misc" />
|
||||
</component>
|
||||
<component name="XSLT-Support.FileAssociations.UIState">
|
||||
<expand />
|
||||
|
@@ -80,7 +80,11 @@ export default function Hero() {
|
||||
/>
|
||||
)}
|
||||
renderOption={(props, option) => (
|
||||
<Box component="li" {...props} onClick={() => navigate(option.path)}>
|
||||
<Box
|
||||
component="li"
|
||||
{...props}
|
||||
onClick={() => navigate('/' + option.path)}
|
||||
>
|
||||
<Box>
|
||||
<Typography fontWeight={'bold'}>{option.name}</Typography>
|
||||
<Typography fontSize={12}>{option.shortDescription}</Typography>
|
||||
|
@@ -3,34 +3,31 @@ import React from 'react';
|
||||
import TextFieldWithDesc from './TextFieldWithDesc';
|
||||
import SimpleRadio from './SimpleRadio';
|
||||
|
||||
const RadioWithTextField = <T,>({
|
||||
fieldName,
|
||||
radioValue,
|
||||
const RadioWithTextField = ({
|
||||
title,
|
||||
onRadioChange,
|
||||
onRadioClick,
|
||||
checked,
|
||||
value,
|
||||
description,
|
||||
onTextChange,
|
||||
typeDescription
|
||||
radioDescription
|
||||
}: {
|
||||
fieldName: string;
|
||||
title: string;
|
||||
radioValue: T;
|
||||
onRadioChange: (val: T) => void;
|
||||
checked: boolean;
|
||||
onRadioClick: () => void;
|
||||
value: string;
|
||||
description: string;
|
||||
onTextChange: (value: string) => void;
|
||||
typeDescription?: string;
|
||||
radioDescription?: string;
|
||||
}) => {
|
||||
const onChange = () => onRadioChange(radioValue);
|
||||
return (
|
||||
<Box>
|
||||
<SimpleRadio
|
||||
value={radioValue}
|
||||
onChange={onChange}
|
||||
fieldName={fieldName}
|
||||
checked={checked}
|
||||
onClick={onRadioClick}
|
||||
title={title}
|
||||
description={typeDescription}
|
||||
description={radioDescription}
|
||||
/>
|
||||
<TextFieldWithDesc
|
||||
value={value}
|
||||
|
@@ -1,39 +1,31 @@
|
||||
import { Box, Stack } from '@mui/material';
|
||||
import { Field } from 'formik';
|
||||
import { Box, Radio, Stack } from '@mui/material';
|
||||
import { Field, useFormikContext } from 'formik';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { globalDescriptionFontSize } from '../../config/uiConfig';
|
||||
import React from 'react';
|
||||
import { globalDescriptionFontSize } from '../../config/uiConfig';
|
||||
|
||||
interface SimpleRadioProps {
|
||||
onChange: () => void;
|
||||
fieldName: string;
|
||||
value: any;
|
||||
title: string;
|
||||
description?: string;
|
||||
checked: boolean;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
export default function SimpleRadio({
|
||||
onChange,
|
||||
fieldName,
|
||||
value,
|
||||
const SimpleRadio: React.FC<SimpleRadioProps> = ({
|
||||
onClick,
|
||||
title,
|
||||
description
|
||||
}: SimpleRadioProps) {
|
||||
description,
|
||||
checked
|
||||
}) => {
|
||||
return (
|
||||
<Box>
|
||||
<Stack
|
||||
direction={'row'}
|
||||
sx={{ mt: 2, mb: 1, cursor: 'pointer' }}
|
||||
onClick={onChange}
|
||||
alignItems={'center'}
|
||||
spacing={1}
|
||||
onClick={onClick}
|
||||
>
|
||||
<Field
|
||||
type="radio"
|
||||
name={fieldName}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<Radio checked={checked} onClick={onClick} />
|
||||
<Typography>{title}</Typography>
|
||||
</Stack>
|
||||
{description && (
|
||||
@@ -43,4 +35,6 @@ export default function SimpleRadio({
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default SimpleRadio;
|
||||
|
@@ -3,7 +3,7 @@ import Typography from '@mui/material/Typography';
|
||||
import React from 'react';
|
||||
|
||||
type OwnProps = {
|
||||
description: string;
|
||||
description?: string;
|
||||
value: string | number;
|
||||
onChange: (value: string) => void;
|
||||
placeholder?: string;
|
||||
@@ -24,9 +24,11 @@ const TextFieldWithDesc = ({
|
||||
onChange={(event) => onChange(event.target.value)}
|
||||
{...props}
|
||||
/>
|
||||
<Typography fontSize={12} mt={1}>
|
||||
{description}
|
||||
</Typography>
|
||||
{description && (
|
||||
<Typography fontSize={12} mt={1}>
|
||||
{description}
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
@@ -1,2 +1,3 @@
|
||||
import { tool as listSort } from './sort/meta';
|
||||
export const listTools = [];
|
||||
|
||||
export const listTools = [listSort];
|
||||
|
@@ -1,11 +1,107 @@
|
||||
import { Box } from '@mui/material';
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import ToolTextInput from '../../../components/input/ToolTextInput';
|
||||
import ToolTextResult from '../../../components/result/ToolTextResult';
|
||||
import * as Yup from 'yup';
|
||||
import ToolOptions from '../../../components/options/ToolOptions';
|
||||
import { Sort, SortingMethod, SplitOperatorType } from './service';
|
||||
import ToolInputAndResult from '../../../components/ToolInputAndResult';
|
||||
import SimpleRadio from '../../../components/options/SimpleRadio';
|
||||
|
||||
const initialValues = {};
|
||||
const validationSchema = Yup.object({
|
||||
// splitSeparator: Yup.string().required('The separator is required')
|
||||
});
|
||||
export default function Sort() {
|
||||
return <Box>Lorem ipsum</Box>;
|
||||
const initialValues = {
|
||||
splitSeparatorType: 'symbol' as SplitOperatorType,
|
||||
sortingMethod: 'alphabetic' as SortingMethod,
|
||||
increasing: true,
|
||||
splitSeparator: ',',
|
||||
joinSeparator: ',',
|
||||
removeDuplicated: false,
|
||||
caseSensitive: false
|
||||
};
|
||||
const splitOperators: {
|
||||
title: string;
|
||||
description: string;
|
||||
type: SplitOperatorType;
|
||||
}[] = [
|
||||
{
|
||||
title: 'Use a Symbol for Splitting',
|
||||
description: 'Delimit input list items with a character.',
|
||||
type: 'symbol'
|
||||
},
|
||||
{
|
||||
title: 'Use a Regex for Splitting',
|
||||
type: 'regex',
|
||||
description: 'Delimit input list items with a regular expression.'
|
||||
}
|
||||
];
|
||||
|
||||
export default function SplitText() {
|
||||
const [input, setInput] = useState<string>('');
|
||||
const [result, setResult] = useState<string>('');
|
||||
// const formRef = useRef<FormikProps<typeof initialValues>>(null);
|
||||
const computeExternal = (optionsValues: typeof initialValues, input: any) => {
|
||||
const {
|
||||
splitSeparatorType,
|
||||
joinSeparator,
|
||||
splitSeparator,
|
||||
increasing,
|
||||
caseSensitive,
|
||||
removeDuplicated,
|
||||
sortingMethod
|
||||
} = optionsValues;
|
||||
|
||||
setResult(
|
||||
Sort(
|
||||
sortingMethod,
|
||||
splitSeparatorType,
|
||||
input,
|
||||
increasing,
|
||||
splitSeparator,
|
||||
joinSeparator,
|
||||
removeDuplicated,
|
||||
caseSensitive
|
||||
)
|
||||
);
|
||||
};
|
||||
const validationSchema = Yup.object({
|
||||
// splitSeparator: Yup.string().required('The separator is required')
|
||||
});
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<ToolInputAndResult
|
||||
input={
|
||||
<ToolTextInput
|
||||
title={'Input list'}
|
||||
value={input}
|
||||
onChange={setInput}
|
||||
/>
|
||||
}
|
||||
result={<ToolTextResult title={'Sorted list'} value={result} />}
|
||||
/>
|
||||
<ToolOptions
|
||||
compute={computeExternal}
|
||||
getGroups={({ values, setFieldValue, handleChange }) => [
|
||||
{
|
||||
title: 'Input item separator',
|
||||
component: splitOperators.map(({ title, description, type }) => (
|
||||
<SimpleRadio
|
||||
key={type}
|
||||
onClick={() => setFieldValue('splitSeparatorType', type)}
|
||||
title={title}
|
||||
description={description}
|
||||
checked={values.splitSeparatorType === type}
|
||||
/>
|
||||
))
|
||||
},
|
||||
{
|
||||
title: 'Sort method',
|
||||
component: <Box></Box>
|
||||
}
|
||||
]}
|
||||
initialValues={initialValues}
|
||||
input={input}
|
||||
validationSchema={validationSchema}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
@@ -6,8 +6,9 @@ export const tool = defineTool('list', {
|
||||
name: 'Sort',
|
||||
path: 'sort',
|
||||
// image,
|
||||
description: '',
|
||||
shortDescription: '',
|
||||
description:
|
||||
'This is a super simple browser-based application that sorts items in a list and arranges them in increasing or decreasing order. You can sort the items alphabetically, numerically, or by their length. You can also remove duplicate and empty items, as well as trim individual items that have whitespace around them. You can use any separator character to separate the input list items or alternatively use a regular expression to separate them. Additionally, you can create a new delimiter for the sorted output list.',
|
||||
shortDescription: 'Quickly sort a list',
|
||||
keywords: ['sort'],
|
||||
component: lazy(() => import('./index'))
|
||||
});
|
||||
|
@@ -67,7 +67,7 @@ export default function SplitText() {
|
||||
withTextField ? (
|
||||
<RadioWithTextField
|
||||
key={type}
|
||||
radioValue={type}
|
||||
checked={type === values.extractionType}
|
||||
title={title}
|
||||
fieldName={'extractionType'}
|
||||
description={description}
|
||||
@@ -76,9 +76,7 @@ export default function SplitText() {
|
||||
? values[textValueAccessor].toString()
|
||||
: ''
|
||||
}
|
||||
onRadioChange={(type) =>
|
||||
setFieldValue('extractionType', type)
|
||||
}
|
||||
onRadioClick={() => setFieldValue('extractionType', type)}
|
||||
onTextChange={(val) =>
|
||||
textValueAccessor
|
||||
? setFieldValue(textValueAccessor, val)
|
||||
@@ -88,9 +86,8 @@ export default function SplitText() {
|
||||
) : (
|
||||
<SimpleRadio
|
||||
key={title}
|
||||
onChange={() => setFieldValue('extractionType', type)}
|
||||
fieldName={'extractionType'}
|
||||
value={values.extractionType}
|
||||
onClick={() => setFieldValue('extractionType', type)}
|
||||
checked={values.extractionType === type}
|
||||
description={description}
|
||||
title={title}
|
||||
/>
|
||||
|
@@ -122,14 +122,12 @@ export default function SplitText() {
|
||||
component: splitOperators.map(({ title, description, type }) => (
|
||||
<RadioWithTextField
|
||||
key={type}
|
||||
radioValue={type}
|
||||
checked={type === values.splitSeparatorType}
|
||||
title={title}
|
||||
fieldName={'splitSeparatorType'}
|
||||
description={description}
|
||||
value={values[`${type}Value`]}
|
||||
onRadioChange={(type) =>
|
||||
setFieldValue('splitSeparatorType', type)
|
||||
}
|
||||
onRadioClick={() => setFieldValue('splitSeparatorType', type)}
|
||||
onTextChange={(val) => setFieldValue(`${type}Value`, val)}
|
||||
/>
|
||||
))
|
||||
|
@@ -4,12 +4,14 @@ import { DefinedTool } from './defineTool';
|
||||
import { capitalizeFirstLetter } from '../utils/string';
|
||||
import { numberTools } from '../pages/number';
|
||||
import { videoTools } from '../pages/video';
|
||||
import { listTools } from '../pages/list';
|
||||
|
||||
export const tools: DefinedTool[] = [
|
||||
...imageTools,
|
||||
...stringTools,
|
||||
...numberTools,
|
||||
...videoTools
|
||||
...videoTools,
|
||||
...listTools
|
||||
];
|
||||
const categoriesDescriptions: { type: string; value: string }[] = [
|
||||
{
|
||||
@@ -31,6 +33,11 @@ const categoriesDescriptions: { type: string; value: string }[] = [
|
||||
type: 'gif',
|
||||
value:
|
||||
'Tools for working with GIF animations – create transparent GIFs, extract GIF frames, add text to GIF, crop, rotate, reverse GIFs, and much more.'
|
||||
},
|
||||
{
|
||||
type: 'list',
|
||||
value:
|
||||
'Tools for working with lists – sort, reverse, randomize lists, find unique and duplicate list items, change list item separators, and much more.'
|
||||
}
|
||||
];
|
||||
export const filterTools = (
|
||||
|
Reference in New Issue
Block a user