From bf2a6e1a62b524ef089d039ea67c8fae3042731f Mon Sep 17 00:00:00 2001 From: awesomeYG <993631441@qq.com> Date: Tue, 30 Jan 2024 11:01:12 +0800 Subject: [PATCH 1/3] fix: full-screen padding --- src/components/MainContent/index.tsx | 3 ++- src/styles/theme.ts | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/MainContent/index.tsx b/src/components/MainContent/index.tsx index 7cddfd5..9a9adb5 100644 --- a/src/components/MainContent/index.tsx +++ b/src/components/MainContent/index.tsx @@ -40,6 +40,7 @@ const MainContent: React.FC<{ dom.style.inset = '0'; dom.style.maxWidth = '100vw'; dom.style.background = '#fff'; + dom.style.padding = '84px 14px 14px 14px'; if (riverHeader) riverHeader.style.display = 'none'; } }); @@ -62,8 +63,8 @@ const MainContent: React.FC<{ dom.style.position = 'unset'; dom.style.inset = '0'; dom.style.maxWidth = 'unset'; + dom.style.padding = '0'; if (riverHeader) { - dom.style.paddingTop = '64px'; riverHeader.style.display = 'block'; } } diff --git a/src/styles/theme.ts b/src/styles/theme.ts index 4d50cc0..7993e0f 100644 --- a/src/styles/theme.ts +++ b/src/styles/theme.ts @@ -107,7 +107,6 @@ const theme = createTheme({ padding-top: ${process.env.NODE_ENV === 'production' ? '64px' : '0'} } #fullscreen-element{ - padding: 14px; overflow: auto; } `, From abf7ae45c70e3d3e42af1e88f4c1302f568b57ab Mon Sep 17 00:00:00 2001 From: awesomeYG <993631441@qq.com> Date: Tue, 30 Jan 2024 12:01:47 +0800 Subject: [PATCH 2/3] feat: add line number --- src/pages/line_number.tsx | 163 ++++++++++++++++++++++++++++++++++++++ src/styles/theme.ts | 7 ++ src/utils/tools.ts | 10 ++- 3 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 src/pages/line_number.tsx diff --git a/src/pages/line_number.tsx b/src/pages/line_number.tsx new file mode 100644 index 0000000..e15b91c --- /dev/null +++ b/src/pages/line_number.tsx @@ -0,0 +1,163 @@ +import alert from '@/components/Alert'; +import MainContent from '@/components/MainContent'; +import TextFieldWithClean from '@/components/TextFieldWithClean'; +import { ToolsForm } from '@/components/Tools'; +import { + Button, + OutlinedInput, + Stack, + TextField, + Typography, +} from '@mui/material'; +import React, { useState } from 'react'; +import CopyToClipboard from 'react-copy-to-clipboard'; + +const LineNumber: React.FC = () => { + const [text, setText] = useState(''); + const [initNumber, setInitNumber] = useState('1'); + const [splitStr, setSplitStr] = useState(' '); + const [outText, setOutText] = useState(''); + + const addLineNumber = () => { + const isNumber = Number.isInteger(+initNumber); + let _outText = ''; + text.split('\n').forEach((item, index) => { + const line = `${ + isNumber ? index + Number(initNumber) : initNumber + }${splitStr}${item}`; + _outText += line + '\n'; + }); + setOutText(_outText); + }; + const handleSaveFile = (event: React.MouseEvent) => { + const url = URL.createObjectURL( + new Blob([outText], { type: 'application/octet-stream' }) + ); + const aTag = document.createElement('a'); + aTag.style.display = 'none'; + aTag.href = url; + aTag.download = '添加行号.txt'; + document.body.appendChild(aTag); + aTag.click(); + URL.revokeObjectURL(url); + }; + return ( + + + setText(event.target.value)} + onClean={() => { + setText(''); + setOutText(''); + }} + variant='outlined' + /> + + + 初始行号: + + } + onChange={(event) => setInitNumber(event.target.value)} + sx={{ + width: '145px', + flexGrow: '0!important', + whiteSpace: 'nowrap', + }} + /> + + 分隔符: + + } + onChange={(event) => setSplitStr(event.target.value)} + sx={{ + width: '145px', + flexGrow: '0!important', + whiteSpace: 'nowrap', + }} + /> + + alert.success('复制成功')} + > + + + + + setOutText('')} + /> + + + ); +}; + +export default LineNumber; diff --git a/src/styles/theme.ts b/src/styles/theme.ts index 7993e0f..3477ecd 100644 --- a/src/styles/theme.ts +++ b/src/styles/theme.ts @@ -122,6 +122,13 @@ const theme = createTheme({ defaultProps: { variant: 'standard', }, + styleOverrides: { + root: { + '& .MuiInputBase-multiline': { + paddingTop: '10px', + }, + }, + }, }, MuiInput: { styleOverrides: { diff --git a/src/utils/tools.ts b/src/utils/tools.ts index dba0a2e..e7d739f 100644 --- a/src/utils/tools.ts +++ b/src/utils/tools.ts @@ -554,7 +554,13 @@ export const allTools: Tool[] = [ tags: [Tags.TEXT], path: '/figlet', key: [], - subTitle: - '将字符转换为大型艺术字, 常用于浏览器控制台和终端', + subTitle: '将字符转换为大型艺术字, 常用于浏览器控制台和终端', + }, + { + label: '在线添加行号', + tags: [Tags.TEXT], + path: '/line_number', + key: [], + subTitle: '在线批量有序添加行号', }, ]; From 832f19a725bb57504108d25fe9c01957fe4c32da Mon Sep 17 00:00:00 2001 From: awesomeYG <993631441@qq.com> Date: Tue, 30 Jan 2024 16:23:30 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20docker=20run=20=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E8=BD=AC=20docker=20compose?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 137 +++++++++++++++++++++ package.json | 1 + src/pages/docker_run_to_docker_compose.tsx | 74 +++++++++++ src/pages/line_number.tsx | 12 +- src/utils/download.ts | 12 ++ src/utils/tools.ts | 7 ++ 6 files changed, 233 insertions(+), 10 deletions(-) create mode 100644 src/pages/docker_run_to_docker_compose.tsx create mode 100644 src/utils/download.ts diff --git a/package-lock.json b/package-lock.json index 1bb3469..ef857ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,7 @@ "big-integer": "^1.6.52", "change-case": "^5.3.0", "clean-css": "^5.3.3", + "composerize-ts": "^0.6.2", "compressorjs": "^1.2.1", "crypto-js": "^4.2.0", "css2less": "^0.1.4", @@ -3915,6 +3916,30 @@ "dot-prop": "^5.1.0" } }, + "node_modules/composerize-ts": { + "version": "0.6.2", + "resolved": "https://registry.npmmirror.com/composerize-ts/-/composerize-ts-0.6.2.tgz", + "integrity": "sha512-8tw5p/FBxg77ubjVftaXA+pknWbkUgbZ4rbZZs2yFUsj2yvO38IvtfpGLfaJ9mGFj324lFEr/OU9xULrKSF9Ag==", + "dependencies": { + "commander": "^10.0.0", + "deepmerge-ts": "^5.0.0", + "flex-js": "^1.0.5", + "ip-cidr": "^3.1.0", + "set-value": "^4.1.0", + "yamljs": "^0.3.0" + }, + "bin": { + "composerize-ts": "cli.js" + } + }, + "node_modules/composerize-ts/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmmirror.com/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "engines": { + "node": ">=14" + } + }, "node_modules/compressorjs": { "version": "1.2.1", "resolved": "https://registry.npmmirror.com/compressorjs/-/compressorjs-1.2.1.tgz", @@ -4625,6 +4650,14 @@ "resolved": "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, + "node_modules/deepmerge-ts": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/deepmerge-ts/-/deepmerge-ts-5.1.0.tgz", + "integrity": "sha512-eS8dRJOckyo9maw9Tu5O5RUi/4inFLrnoLkBe3cPfDMx3WZioXtmOew4TXQaxq7Rhl4xjDtR7c6x8nNTxOvbFw==", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/default-browser": { "version": "4.0.0", "resolved": "https://registry.npmmirror.com/default-browser/-/default-browser-4.0.0.tgz", @@ -5641,6 +5674,11 @@ "resolved": "https://registry.npmmirror.com/flatted/-/flatted-3.2.9.tgz", "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" }, + "node_modules/flex-js": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/flex-js/-/flex-js-1.0.5.tgz", + "integrity": "sha512-Z5uoLzOGtTB/nzaTVVBbwmxOHBzHovAGJHLXE1TUKsQuN1RRWMOWeA08J9RRKtAl9TH9tkaH6fpjA4sLf0DzQw==" + }, "node_modules/follow-redirects": { "version": "1.15.3", "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.3.tgz", @@ -6451,6 +6489,30 @@ "resolved": "https://registry.npmmirror.com/ip/-/ip-1.1.8.tgz", "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" }, + "node_modules/ip-address": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/ip-address/-/ip-address-7.1.0.tgz", + "integrity": "sha512-V9pWC/VJf2lsXqP7IWJ+pe3P1/HCYGBMZrrnT62niLGjAfCbeiwXMUxaeHvnVlz19O27pvXP4azs+Pj/A0x+SQ==", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "1.1.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/ip-cidr": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/ip-cidr/-/ip-cidr-3.1.0.tgz", + "integrity": "sha512-HUCn4snshEX1P8cja/IyU3qk8FVDW8T5zZcegDFbu4w7NojmAhk5NcOgj3M8+0fmumo1afJTPDtJlzsxLdOjtg==", + "dependencies": { + "ip-address": "^7.1.0", + "jsbn": "^1.1.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/is-alphabetical": { "version": "1.0.4", "resolved": "https://registry.npmmirror.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz", @@ -6711,6 +6773,25 @@ "node": ">=12" } }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-primitive": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/is-primitive/-/is-primitive-3.0.1.tgz", + "integrity": "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmmirror.com/is-regex/-/is-regex-1.1.4.tgz", @@ -6856,6 +6937,14 @@ "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/iterator.prototype": { "version": "1.1.2", "resolved": "https://registry.npmmirror.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz", @@ -6961,6 +7050,11 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz", @@ -10220,6 +10314,18 @@ "node": ">= 0.4" } }, + "node_modules/set-value": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/set-value/-/set-value-4.1.0.tgz", + "integrity": "sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw==", + "dependencies": { + "is-plain-object": "^2.0.4", + "is-primitive": "^3.0.1" + }, + "engines": { + "node": ">=11.0" + } + }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmmirror.com/setimmediate/-/setimmediate-1.0.5.tgz", @@ -10375,6 +10481,11 @@ "node": ">= 10.x" } }, + "node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" + }, "node_modules/sql-formatter": { "version": "15.0.2", "resolved": "https://registry.npmmirror.com/sql-formatter/-/sql-formatter-15.0.2.tgz", @@ -11541,6 +11652,32 @@ "node": ">= 6" } }, + "node_modules/yamljs": { + "version": "0.3.0", + "resolved": "https://registry.npmmirror.com/yamljs/-/yamljs-0.3.0.tgz", + "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", + "dependencies": { + "argparse": "^1.0.7", + "glob": "^7.0.5" + }, + "bin": { + "json2yaml": "bin/json2yaml", + "yaml2json": "bin/yaml2json" + } + }, + "node_modules/yamljs/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/yamljs/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmmirror.com/yargs/-/yargs-17.7.2.tgz", diff --git a/package.json b/package.json index 7c48418..123f506 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "big-integer": "^1.6.52", "change-case": "^5.3.0", "clean-css": "^5.3.3", + "composerize-ts": "^0.6.2", "compressorjs": "^1.2.1", "crypto-js": "^4.2.0", "css2less": "^0.1.4", diff --git a/src/pages/docker_run_to_docker_compose.tsx b/src/pages/docker_run_to_docker_compose.tsx new file mode 100644 index 0000000..e9089f7 --- /dev/null +++ b/src/pages/docker_run_to_docker_compose.tsx @@ -0,0 +1,74 @@ +import MainContent from '@/components/MainContent'; +import TextFieldWithClean from '@/components/TextFieldWithClean'; +import { ToolsForm } from '@/components/Tools'; +import { saveFile } from '@/utils/download'; +import { Button, Stack, TextField } from '@mui/material'; +import { composerize } from 'composerize-ts'; +import React, { useState } from 'react'; + +const DockerRunToDockerCompose: React.FC = () => { + const [dockerRun, setDockerRun] = useState( + 'docker run -p 8080:80 -d --name myapp nginx' + ); + const [dockerCompose, setDockerCompose] = useState(''); + const conversionResult = () => { + const res = composerize(dockerRun.trim()).yaml; + setDockerCompose(res); + }; + const handleSaveFile = () => { + saveFile(dockerCompose, 'docker-compose.yml'); + }; + return ( + + + setDockerRun(event.target.value)} + placeholder='请输入docker run命令' + onClean={() => { + setDockerRun(''); + setDockerCompose(''); + }} + variant='outlined' + /> + + + + + + + + ); +}; + +export default DockerRunToDockerCompose; diff --git a/src/pages/line_number.tsx b/src/pages/line_number.tsx index e15b91c..44309ba 100644 --- a/src/pages/line_number.tsx +++ b/src/pages/line_number.tsx @@ -2,6 +2,7 @@ import alert from '@/components/Alert'; import MainContent from '@/components/MainContent'; import TextFieldWithClean from '@/components/TextFieldWithClean'; import { ToolsForm } from '@/components/Tools'; +import { saveFile } from '@/utils/download'; import { Button, OutlinedInput, @@ -30,16 +31,7 @@ const LineNumber: React.FC = () => { setOutText(_outText); }; const handleSaveFile = (event: React.MouseEvent) => { - const url = URL.createObjectURL( - new Blob([outText], { type: 'application/octet-stream' }) - ); - const aTag = document.createElement('a'); - aTag.style.display = 'none'; - aTag.href = url; - aTag.download = '添加行号.txt'; - document.body.appendChild(aTag); - aTag.click(); - URL.revokeObjectURL(url); + saveFile(outText, '添加行号.txt'); }; return ( diff --git a/src/utils/download.ts b/src/utils/download.ts new file mode 100644 index 0000000..c95e350 --- /dev/null +++ b/src/utils/download.ts @@ -0,0 +1,12 @@ +export const saveFile = (text: string, name: string) => { + const url = URL.createObjectURL( + new Blob([text], { type: 'application/octet-stream' }) + ); + const aTag = document.createElement('a'); + aTag.style.display = 'none'; + aTag.href = url; + aTag.download = name; + document.body.appendChild(aTag); + aTag.click(); + URL.revokeObjectURL(url); +}; diff --git a/src/utils/tools.ts b/src/utils/tools.ts index e7d739f..4c16089 100644 --- a/src/utils/tools.ts +++ b/src/utils/tools.ts @@ -563,4 +563,11 @@ export const allTools: Tool[] = [ key: [], subTitle: '在线批量有序添加行号', }, + { + label: 'Docker run 命令转 Docker compose', + tags: [Tags.DEV], + path: '/docker_run_to_docker_compose', + key: [], + subTitle: 'docker run 命令转 docker compose', + }, ];