feat: json pretty

This commit is contained in:
Ibrahima G. Coulibaly
2025-02-27 13:05:38 +00:00
parent 18c305ac9b
commit d2eb7030d8
12 changed files with 78 additions and 49 deletions

47
.idea/workspace.xml generated
View File

@@ -4,13 +4,19 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="b30e2810-c4c1-4aad-b134-794e52cc1c7d" name="Changes" comment="refact: examples">
<list default="true" id="b30e2810-c4c1-4aad-b134-794e52cc1c7d" name="Changes" comment="fix: examples">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/ToolHeader.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/ToolHeader.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/examples/Examples.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/examples/ToolExamples.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/package-lock.json" beforeDir="false" afterPath="$PROJECT_DIR$/package-lock.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/scripts/create-tool.mjs" beforeDir="false" afterPath="$PROJECT_DIR$/scripts/create-tool.mjs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/examples/ExampleCard.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/examples/ExampleCard.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/components/examples/ToolExamples.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/examples/ToolExamples.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/pages/home/Categories.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/home/Categories.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/split/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/tools/string/split/index.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tools/defineTool.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/tools/defineTool.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/tools/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/tools/index.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/utils/string.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils/string.ts" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -78,7 +84,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": "examples",
"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/src/assets",
@@ -677,11 +683,38 @@
</option>
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="RECENT_FILTERS">
<map>
<entry key="Branch">
<value>
<list>
<RecentGroup>
<option name="FILTER_VALUES">
<option value="origin/examples" />
</option>
</RecentGroup>
</list>
</value>
</entry>
</map>
</option>
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
<State>
<option name="FILTERS">
<map>
<entry key="branch">
<value>
<list>
<option value="origin/examples" />
</list>
</value>
</entry>
</map>
</option>
</State>
</value>
</entry>
</map>
@@ -691,7 +724,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: format number" />
<MESSAGE value="feat: rotate ui" />
<MESSAGE value="feat: shuffle ui" />
<MESSAGE value="refactor: remove validation schema" />
@@ -716,7 +748,8 @@
<MESSAGE value="chore: handle enter press on search" />
<MESSAGE value="chore: show tooloptions in example" />
<MESSAGE value="refact: examples" />
<option name="LAST_COMMIT_MESSAGE" value="refact: examples" />
<MESSAGE value="fix: examples" />
<option name="LAST_COMMIT_MESSAGE" value="fix: examples" />
</component>
<component name="XSLT-Support.FileAssociations.UIState">
<expand />

16
package-lock.json generated
View File

@@ -10,8 +10,6 @@
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@hugeicons/core-free-icons": "^1.0.10",
"@hugeicons/react": "^1.0.3",
"@mui/icons-material": "^5.15.20",
"@mui/material": "^5.15.20",
"@playwright/test": "^1.45.0",
@@ -1402,20 +1400,6 @@
"@hapi/hoek": "^9.0.0"
}
},
"node_modules/@hugeicons/core-free-icons": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/@hugeicons/core-free-icons/-/core-free-icons-1.0.10.tgz",
"integrity": "sha512-XMjwTffefQGJ0B3gjnS9IV2UqM5qYT4WUJjD+cD7x6TfwE8rSAb+foGNbcyCjpXKVOnuyaJa+y4ukrPyNY/DBw==",
"license": "MIT"
},
"node_modules/@hugeicons/react": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@hugeicons/react/-/react-1.0.3.tgz",
"integrity": "sha512-NJN8PmxTZlkt3T9a7uNZLhkJlIyQUt+sMxM5Qa/UH1qC1fBkwI7C7HSY/y4f7jjo5SQl7zRkm3hWH9tpWuHmWw==",
"peerDependencies": {
"react": ">=16.0.0"
}
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.14",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",

View File

@@ -27,8 +27,6 @@
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@hugeicons/core-free-icons": "^1.0.10",
"@hugeicons/react": "^1.0.3",
"@mui/icons-material": "^5.15.20",
"@mui/material": "^5.15.20",
"@playwright/test": "^1.45.0",

View File

@@ -79,6 +79,7 @@ import React from 'react';
import * as Yup from 'yup';
const initialValues = {};
type InitialValuesType = typeof initialValues;
const validationSchema = Yup.object({
// splitSeparator: Yup.string().required('The separator is required')
});

View File

@@ -17,7 +17,7 @@ export interface ExampleCardProps<T> {
sampleText: string;
sampleResult: string;
sampleOptions: T;
changeInputResult: (newOptions: T) => void;
changeInputResult: (newInput: string, newOptions: T) => void;
getGroups: GetGroupsType<T>;
}
@@ -35,7 +35,7 @@ export default function ExampleCard<T>({
<Card
raised
onClick={() => {
changeInputResult(sampleOptions);
changeInputResult(sampleText, sampleOptions);
}}
sx={{
bgcolor: theme.palette.background.default,

View File

@@ -15,6 +15,7 @@ export interface ExampleProps<T> {
exampleCards: CardExampleType<T>[];
getGroups: GetGroupsType<T>;
formRef: React.RefObject<FormikProps<T>>;
setInput: React.Dispatch<React.SetStateAction<string>>;
}
export default function ToolExamples<T>({
@@ -22,9 +23,11 @@ export default function ToolExamples<T>({
subtitle,
exampleCards,
getGroups,
formRef
formRef,
setInput
}: ExampleProps<T>) {
function changeInputResult(newOptions: T) {
function changeInputResult(newInput: string, newOptions: T) {
setInput(newInput);
formRef.current?.setValues(newOptions);
const toolsElement = document.getElementById('tool');
if (toolsElement) {

View File

@@ -1,12 +1,12 @@
import { getToolsByCategory } from '@tools/index';
import Grid from '@mui/material/Grid';
import { Card, CardContent, Stack } from '@mui/material';
import { HugeiconsIcon } from '@hugeicons/react';
import { Link, useNavigate } from 'react-router-dom';
import Typography from '@mui/material/Typography';
import Button from '@mui/material/Button';
import { useState } from 'react';
import { categoriesColors } from 'config/uiConfig';
import { Icon } from '@iconify/react';
type ArrayElement<ArrayType extends readonly unknown[]> =
ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
@@ -20,7 +20,6 @@ const SingleCategory = function ({
}) {
const navigate = useNavigate();
const [hovered, setHovered] = useState<boolean>(false);
const Icon = category.icon;
const toggleHover = () => setHovered((prevState) => !prevState);
return (
<Grid
@@ -38,8 +37,9 @@ const SingleCategory = function ({
>
<CardContent>
<Stack direction={'row'} spacing={2} alignItems={'center'}>
<HugeiconsIcon
icon={Icon}
<Icon
icon={category.icon}
fontSize={'60px'}
style={{
transform: `scale(${hovered ? 1.1 : 1}`
}}

View File

@@ -179,6 +179,7 @@ export default function JoinText({ title }: ToolComponentProps) {
exampleCards={exampleCards}
getGroups={getGroups}
formRef={formRef}
setInput={setInput}
/>
</Box>
);

View File

@@ -211,6 +211,7 @@ export default function SplitText({ title }: ToolComponentProps) {
exampleCards={exampleCards}
getGroups={getGroups}
formRef={formRef}
setInput={setInput}
/>
</Box>
);

View File

@@ -12,7 +12,13 @@ interface ToolOptions {
shortDescription: string;
}
export type ToolCategory = 'string' | 'png' | 'number' | 'gif' | 'list';
export type ToolCategory =
| 'string'
| 'png'
| 'number'
| 'gif'
| 'list'
| 'json';
export interface DefinedTool {
type: ToolCategory;

View File

@@ -6,18 +6,13 @@ import { numberTools } from '../pages/tools/number';
import { videoTools } from '../pages/tools/video';
import { listTools } from '../pages/tools/list';
import { Entries } from 'type-fest';
import {
ArrangeByNumbers19Icon,
Gif01Icon,
HugeiconsIcon,
LeftToRightListBulletIcon,
Png01Icon,
TextIcon
} from '@hugeicons/core-free-icons';
import { jsonTools } from '../pages/tools/json';
import { IconifyIcon } from '@iconify/react';
export const tools: DefinedTool[] = [
...imageTools,
...stringTools,
...jsonTools,
...listTools,
...videoTools,
...numberTools
@@ -26,38 +21,44 @@ const categoriesConfig: {
type: ToolCategory;
value: string;
title?: string;
icon: typeof HugeiconsIcon;
icon: IconifyIcon | string;
}[] = [
{
type: 'string',
title: 'Text',
icon: TextIcon,
icon: 'solar:text-bold-duotone',
value:
'Tools for working with text convert text to images, find and replace text, split text into fragments, join text lines, repeat text, and much more.'
},
{
type: 'png',
icon: Png01Icon,
icon: 'ph:file-png-thin',
value:
'Tools for working with PNG images convert PNGs to JPGs, create transparent PNGs, change PNG colors, crop, rotate, resize PNGs, and much more.'
},
{
type: 'number',
icon: ArrangeByNumbers19Icon,
icon: 'lsicon:number-filled',
value:
'Tools for working with numbers generate number sequences, convert numbers to words and words to numbers, sort, round, factor numbers, and much more.'
},
{
type: 'gif',
icon: Gif01Icon,
icon: 'material-symbols-light:gif-rounded',
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',
icon: LeftToRightListBulletIcon,
icon: 'solar:list-bold-duotone',
value:
'Tools for working with lists sort, reverse, randomize lists, find unique and duplicate list items, change list item separators, and much more.'
},
{
type: 'json',
icon: 'lets-icons:json-light',
value:
'Tools for working with JSON data structures prettify and minify JSON objects, flatten JSON arrays, stringify JSON values, analyze data, and much more'
}
];
export const filterTools = (
@@ -82,7 +83,7 @@ export const filterTools = (
export const getToolsByCategory = (): {
title: string;
description: string;
icon: typeof HugeiconsIcon;
icon: IconifyIcon | string;
type: string;
example: { title: string; path: string };
tools: DefinedTool[];

View File

@@ -9,6 +9,7 @@ export function isNumber(number: any) {
export const replaceSpecialCharacters = (str: string) => {
return str
.replace(/\\"/g, '"')
.replace(/\\n/g, '\n')
.replace(/\\t/g, '\t')
.replace(/\\r/g, '\r')