mirror of
https://github.com/iib0011/omni-tools.git
synced 2025-12-29 16:16:02 +00:00
refactor: tools folder inside pages
This commit is contained in:
190
src/pages/tools/string/join/index.tsx
Normal file
190
src/pages/tools/string/join/index.tsx
Normal file
@@ -0,0 +1,190 @@
|
||||
import { Box } from '@mui/material';
|
||||
import React, { useState } from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import ToolTextInput from '@components/input/ToolTextInput';
|
||||
import ToolTextResult from '@components/result/ToolTextResult';
|
||||
import ToolOptions 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 Examples from '@components/examples/Examples';
|
||||
|
||||
const initialValues = {
|
||||
joinCharacter: '',
|
||||
deleteBlank: true,
|
||||
deleteTrailing: true
|
||||
};
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
joinCharacter: Yup.string().required('Join character is required'),
|
||||
deleteBlank: Yup.boolean().required('Delete blank is required'),
|
||||
deleteTrailing: Yup.boolean().required('Delete trailing is required')
|
||||
});
|
||||
|
||||
const mergeOptions = {
|
||||
placeholder: 'Join Character',
|
||||
description:
|
||||
'Symbol that connects broken\n' + 'pieces of text. (Space by default.)\n',
|
||||
accessor: 'joinCharacter' as keyof typeof initialValues
|
||||
};
|
||||
|
||||
const blankTrailingOptions: {
|
||||
title: string;
|
||||
description: string;
|
||||
accessor: keyof typeof initialValues;
|
||||
}[] = [
|
||||
{
|
||||
title: 'Delete Blank Lines',
|
||||
description: "Delete lines that don't have\n text symbols.\n",
|
||||
accessor: 'deleteBlank'
|
||||
},
|
||||
{
|
||||
title: 'Delete Trailing Spaces',
|
||||
description: 'Remove spaces and tabs at\n the end of the lines.\n',
|
||||
accessor: 'deleteTrailing'
|
||||
}
|
||||
];
|
||||
|
||||
const exampleCards = [
|
||||
{
|
||||
title: 'Merge a To-Do List',
|
||||
description:
|
||||
"In this example, we merge a bullet point list into one sentence, separating each item by the word 'and'. We also remove all empty lines and trailing spaces. If we didn't remove the empty lines, then they'd be joined with the separator word, making the separator word appear multiple times. If we didn't remove the trailing tabs and spaces, then they'd create extra spacing in the joined text and it wouldn't look nice.",
|
||||
sampleText: `clean the house
|
||||
|
||||
go shopping
|
||||
feed the cat
|
||||
|
||||
make dinner
|
||||
build a rocket ship and fly away`,
|
||||
sampleResult: `clean the house and go shopping and feed the cat and make dinner and build a rocket ship and fly away`,
|
||||
requiredOptions: {
|
||||
joinCharacter: 'and',
|
||||
deleteBlankLines: true,
|
||||
deleteTrailingSpaces: true
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Comma Separated List',
|
||||
description:
|
||||
'This example joins a column of words into a comma separated list of words.',
|
||||
sampleText: `computer
|
||||
memory
|
||||
processor
|
||||
mouse
|
||||
keyboard`,
|
||||
sampleResult: `computer, memory, processor, mouse, keyboard`,
|
||||
requiredOptions: {
|
||||
joinCharacter: ',',
|
||||
deleteBlankLines: false,
|
||||
deleteTrailingSpaces: false
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Vertical Word to Horizontal',
|
||||
description:
|
||||
'This example rotates words from a vertical position to horizontal. An empty separator is used for this purpose.',
|
||||
sampleText: `T
|
||||
e
|
||||
x
|
||||
t
|
||||
a
|
||||
b
|
||||
u
|
||||
l
|
||||
o
|
||||
u
|
||||
s
|
||||
!`,
|
||||
sampleResult: `Textabulous!`,
|
||||
requiredOptions: {
|
||||
joinCharacter: '',
|
||||
deleteBlankLines: false,
|
||||
deleteTrailingSpaces: false
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
export default function JoinText() {
|
||||
const [input, setInput] = useState<string>('');
|
||||
const [result, setResult] = useState<string>('');
|
||||
|
||||
const compute = (optionsValues: typeof initialValues, input: any) => {
|
||||
const { joinCharacter, deleteBlank, deleteTrailing } = optionsValues;
|
||||
setResult(mergeText(input, deleteBlank, deleteTrailing, joinCharacter));
|
||||
};
|
||||
|
||||
function changeInputResult(input: string, result: string) {
|
||||
setInput(input);
|
||||
setResult(result);
|
||||
|
||||
const toolsElement = document.getElementById('tool');
|
||||
if (toolsElement) {
|
||||
toolsElement.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<ToolInputAndResult
|
||||
input={
|
||||
<ToolTextInput
|
||||
title={'Text Pieces'}
|
||||
value={input}
|
||||
onChange={setInput}
|
||||
/>
|
||||
}
|
||||
result={<ToolTextResult title={'Joined Text'} value={result} />}
|
||||
/>
|
||||
<ToolOptions
|
||||
compute={compute}
|
||||
getGroups={({ values, updateField }) => [
|
||||
{
|
||||
title: 'Text Merged Options',
|
||||
component: (
|
||||
<TextFieldWithDesc
|
||||
placeholder={mergeOptions.placeholder}
|
||||
value={values['joinCharacter']}
|
||||
onOwnChange={(value) =>
|
||||
updateField(mergeOptions.accessor, value)
|
||||
}
|
||||
description={mergeOptions.description}
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'Blank Lines and Trailing Spaces',
|
||||
component: blankTrailingOptions.map((option) => (
|
||||
<CheckboxWithDesc
|
||||
key={option.accessor}
|
||||
title={option.title}
|
||||
checked={!!values[option.accessor]}
|
||||
onChange={(value) => updateField(option.accessor, value)}
|
||||
description={option.description}
|
||||
/>
|
||||
))
|
||||
}
|
||||
]}
|
||||
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" />
|
||||
<Examples
|
||||
title="Text Joiner Examples"
|
||||
subtitle="Click to try!"
|
||||
exampleCards={exampleCards.map((card) => ({
|
||||
...card,
|
||||
changeInputResult
|
||||
}))}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
14
src/pages/tools/string/join/meta.ts
Normal file
14
src/pages/tools/string/join/meta.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
import image from '@assets/text.png';
|
||||
|
||||
export const tool = defineTool('string', {
|
||||
path: 'join',
|
||||
name: 'Text Joiner',
|
||||
image,
|
||||
description:
|
||||
"World's Simplest Text Tool World's simplest browser-based utility for joining text. Load your text in the input form on the left and you'll automatically get merged text on the right. Powerful, free, and fast. Load text – get joined lines",
|
||||
shortDescription: 'Quickly merge texts',
|
||||
keywords: ['text', 'join'],
|
||||
component: lazy(() => import('./index'))
|
||||
});
|
||||
17
src/pages/tools/string/join/service.ts
Normal file
17
src/pages/tools/string/join/service.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
export function mergeText(
|
||||
text: string,
|
||||
deleteBlankLines: boolean = true,
|
||||
deleteTrailingSpaces: boolean = true,
|
||||
joinCharacter: string = ''
|
||||
): string {
|
||||
let processedLines: string[] = text.split('\n');
|
||||
if (deleteTrailingSpaces) {
|
||||
processedLines = processedLines.map((line) => line.trimEnd());
|
||||
}
|
||||
|
||||
if (deleteBlankLines) {
|
||||
processedLines = processedLines.filter((line) => line.trim());
|
||||
}
|
||||
|
||||
return processedLines.join(joinCharacter);
|
||||
}
|
||||
18
src/pages/tools/string/join/string-join.e2e.spec.ts
Normal file
18
src/pages/tools/string/join/string-join.e2e.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
test.describe('JoinText Component', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/string/join');
|
||||
});
|
||||
|
||||
test('should merge text pieces with specified join character', async ({
|
||||
page
|
||||
}) => {
|
||||
// Input the text pieces
|
||||
await page.getByTestId('text-input').fill('1\n2');
|
||||
|
||||
const result = await page.getByTestId('text-result').inputValue();
|
||||
|
||||
expect(result).toBe('12');
|
||||
});
|
||||
});
|
||||
64
src/pages/tools/string/join/string-join.service.test.ts
Normal file
64
src/pages/tools/string/join/string-join.service.test.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { mergeText } from './service';
|
||||
|
||||
describe('mergeText', () => {
|
||||
it('should merge lines with default settings (delete blank lines, delete trailing spaces, join with empty string)', () => {
|
||||
const input = 'line1 \n \nline2\nline3 \n\nline4';
|
||||
const expected = 'line1line2line3line4';
|
||||
expect(mergeText(input)).toBe(expected);
|
||||
});
|
||||
|
||||
it('should merge lines and preserve blank lines when deleteBlankLines is false', () => {
|
||||
const input = 'line1 \n \nline2\nline3 \n\nline4';
|
||||
const expected = 'line1line2line3line4';
|
||||
expect(mergeText(input, false, true, '')).toBe(expected);
|
||||
});
|
||||
|
||||
it('should merge lines and preserve trailing spaces when deleteTrailingSpaces is false', () => {
|
||||
const input = 'line1 \n \nline2\nline3 \n\nline4';
|
||||
const expected = 'line1 line2line3 line4';
|
||||
expect(mergeText(input, true, false)).toBe(expected);
|
||||
});
|
||||
|
||||
it('should merge lines, preserve blank lines and trailing spaces when both deleteBlankLines and deleteTrailingSpaces are false', () => {
|
||||
const input = 'line1 \n \nline2\nline3 \n\nline4';
|
||||
const expected = 'line1 line2line3 line4';
|
||||
expect(mergeText(input, false, false)).toBe(expected);
|
||||
});
|
||||
|
||||
it('should merge lines with a specified joinCharacter', () => {
|
||||
const input = 'line1 \n \nline2\nline3 \n\nline4';
|
||||
const expected = 'line1 line2 line3 line4';
|
||||
expect(mergeText(input, true, true, ' ')).toBe(expected);
|
||||
});
|
||||
|
||||
it('should handle empty input', () => {
|
||||
const input = '';
|
||||
const expected = '';
|
||||
expect(mergeText(input)).toBe(expected);
|
||||
});
|
||||
|
||||
it('should handle input with only blank lines', () => {
|
||||
const input = ' \n \n\n';
|
||||
const expected = '';
|
||||
expect(mergeText(input)).toBe(expected);
|
||||
});
|
||||
|
||||
it('should handle input with only trailing spaces', () => {
|
||||
const input = 'line1 \nline2 \nline3 ';
|
||||
const expected = 'line1line2line3';
|
||||
expect(mergeText(input)).toBe(expected);
|
||||
});
|
||||
|
||||
it('should handle single line input', () => {
|
||||
const input = 'single line';
|
||||
const expected = 'single line';
|
||||
expect(mergeText(input)).toBe(expected);
|
||||
});
|
||||
|
||||
it('should join lines with new line character when joinCharacter is set to "\\n"', () => {
|
||||
const input = 'line1 \n \nline2\nline3 \n\nline4';
|
||||
const expected = 'line1\nline2\nline3\nline4';
|
||||
expect(mergeText(input, true, true, '\n')).toBe(expected);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user