diff --git a/.changeset/twelve-boats-pretend.md b/.changeset/twelve-boats-pretend.md new file mode 100644 index 0000000000..feaf3cfcfc --- /dev/null +++ b/.changeset/twelve-boats-pretend.md @@ -0,0 +1,7 @@ +--- +"@scow/portal-server": patch +"@scow/portal-web": patch +"@scow/docs": patch +--- + +Web Shell 支持跳转到文件编辑页面 diff --git a/apps/portal-server/assets/scow-shell-file.sh b/apps/portal-server/assets/scow-shell-file.sh index 1a6a0391d9..4f60f12e77 100644 --- a/apps/portal-server/assets/scow-shell-file.sh +++ b/apps/portal-server/assets/scow-shell-file.sh @@ -25,6 +25,7 @@ sdown () { echo "SCOW is downloading file $@ in directory `pwd`" echo "This command is only valid for SCOW web shells." } + sopen () { if [ "$1" == "-h" ]; then echo "Usage: sopen [-h]" @@ -34,3 +35,32 @@ sopen () { echo "SCOW is opening the file system `pwd`" echo "This command is only valid for SCOW web shells." } + +sedit () { + if [ "$1" == "-h" ]; then + echo "Usage: sedit [-h] [FILE]" + echo "Use the sedit command to open a text editor. (only valid in SCOW)." + return 0 + fi + if [ "$#" -eq 0 ]; then + echo "Error: Please enter the file you want to edit." + echo "Usage: sedit [file_path]" + return 0 + elif [ "$#" -gt 1 ]; then + echo "Error: The sedit command only accepts one argument." + echo "Usage: sedit [file_path]" + return 0 + fi + result=$(echo $@ | grep "/") + if [[ "$result" != "" ]] + then + echo "sedit does not support relative paths. Please enter the file name." + return 0 + fi + if [ ! -f "$@" ]; then + echo "File $@ does not exist." + return 0 + fi + echo "SCOW is redirecting to the editor for the file $@ in directory `pwd`" + echo "This command is only valid for SCOW web shells." +} diff --git a/apps/portal-web/src/i18n/en.ts b/apps/portal-web/src/i18n/en.ts index faa9bc9c55..3c50d7a301 100644 --- a/apps/portal-web/src/i18n/en.ts +++ b/apps/portal-web/src/i18n/en.ts @@ -560,11 +560,14 @@ export default { popoverContent3: "Download a file", popoverContentFile: "File Name", popoverContent4: "By entering", - popoverContent5: ", the file in your current path will be downloaded locally. Relative paths " - + "are not supported at the moment.", - popoverContent6: "If you need to download files from other directories, please use", + popoverContent5: ", the file in your current path will be downloaded locally. ", + popoverContent6: "Relative paths are not supported at the moment. " + + "If you need to download or edit files from other directories, please use", popoverContent7: "command to navigate to the file system.", popoverContent8: "Usage example: ", + popoverContent9: "Edit a file", + popoverContent10: "After entering the command ", + popoverContent11: ", you will be redirected to a file editing page where you can edit the specified file. ", command: "Command", }, index: { diff --git a/apps/portal-web/src/i18n/zh_cn.ts b/apps/portal-web/src/i18n/zh_cn.ts index 8019e154f7..7a87c16246 100644 --- a/apps/portal-web/src/i18n/zh_cn.ts +++ b/apps/portal-web/src/i18n/zh_cn.ts @@ -560,11 +560,16 @@ export default { popoverContent3: "文件下载", popoverContentFile:"文件名", popoverContent4: ",输入", - popoverContent5: ",您当前路径下的该文件会被下载到本地,目前不支持输入相对路径,", + popoverContent5: ",您当前路径下的该文件会被下载到本地", - popoverContent6: "如果需要下载其他目录下的文件请使用", + popoverContent6: "目前不支持输入相对路径,如果需要下载或编辑其他目录下的文件请使用", popoverContent7: "命令跳转到文件系统。", popoverContent8: "使用示例:", + + popoverContent9: "文件编辑", + popoverContent10: ",输入", + popoverContent11: "命令后跳转到文件编辑页面, 您可以编辑指定的文件", + command:"命令", }, index: { diff --git a/apps/portal-web/src/pageComponents/filemanager/FileManager.tsx b/apps/portal-web/src/pageComponents/filemanager/FileManager.tsx index 7c5dd3d6e9..f4e8639e95 100644 --- a/apps/portal-web/src/pageComponents/filemanager/FileManager.tsx +++ b/apps/portal-web/src/pageComponents/filemanager/FileManager.tsx @@ -19,6 +19,7 @@ import { ScissorOutlined, SnippetsOutlined, UploadOutlined, UpOutlined, } from "@ant-design/icons"; import { DEFAULT_PAGE_SIZE } from "@scow/lib-web/build/utils/pagination"; +import { queryToString } from "@scow/lib-web/build/utils/querystring"; import { getI18nConfigCurrentText } from "@scow/lib-web/build/utils/systemLanguage"; import { App, Button, Divider, Space } from "antd"; import Link from "next/link"; @@ -348,6 +349,17 @@ export const FileManager: React.FC = ({ cluster, path, urlPrefix }) => { } }; + const editFile = queryToString(router.query.edit); + + useEffect(() => { + if (editFile !== "") { + const foundFile = files.find((file) => file.name === editFile); + if (foundFile && foundFile.type !== "DIR") { + handlePreview(editFile, foundFile.size); + } + } + }, [editFile, files]); + return (
diff --git a/apps/portal-web/src/pageComponents/shell/Shell.tsx b/apps/portal-web/src/pageComponents/shell/Shell.tsx index 0a656a833d..2da0ff7723 100644 --- a/apps/portal-web/src/pageComponents/shell/Shell.tsx +++ b/apps/portal-web/src/pageComponents/shell/Shell.tsx @@ -39,6 +39,8 @@ const OPEN_FILE = "This command is only valid for SCOW web shells"; const OPEN_EXPLORER_PREFIX = "SCOW is opening the file system"; const DOWNLOAD_FILE_PREFIX = "SCOW is downloading file "; const DOWNLOAD_FILE_SUFFIX = " in directory "; +const EDIT_FILE_PREFIX = "SCOW is redirecting to the editor for the file "; +const EDIT_FILE_SUFFIX = " in directory "; export const Shell: React.FC = ({ user, cluster, loginNode, path }) => { @@ -95,6 +97,8 @@ export const Shell: React.FC = ({ user, cluster, loginNode, path }) => { }); }; + + socket.onmessage = (e) => { const message = JSON.parse(e.data) as ShellOutputData; switch (message.$case) { @@ -114,6 +118,11 @@ export const Shell: React.FC = ({ user, cluster, loginNode, path }) => { const fileEndIndex = result.search(DOWNLOAD_FILE_SUFFIX); const file = result.substring(fileStartIndex + DOWNLOAD_FILE_PREFIX.length, fileEndIndex); window.location.href = urlToDownload(cluster, join(path, file), true); + } else if (result.includes(EDIT_FILE_PREFIX)) { + const fileStartIndex = result.search(EDIT_FILE_PREFIX); + const fileEndIndex = result.search(EDIT_FILE_SUFFIX); + const file = result.substring(fileStartIndex + EDIT_FILE_PREFIX.length, fileEndIndex); + window.open(join(publicConfig.BASE_PATH, "/files", cluster, path + "?edit=" + file)); } } term.write(data); diff --git a/apps/portal-web/src/pages/shell/[cluster]/[loginNode]/[[...path]].tsx b/apps/portal-web/src/pages/shell/[cluster]/[loginNode]/[[...path]].tsx index 3a0d49740e..bf016ee694 100644 --- a/apps/portal-web/src/pages/shell/[cluster]/[loginNode]/[[...path]].tsx +++ b/apps/portal-web/src/pages/shell/[cluster]/[loginNode]/[[...path]].tsx @@ -121,9 +121,19 @@ export const ShellPage: NextPage = requireAuth(() => true)(({ userStore }) => { {t("pages.shell.loginNode.popoverContent4")} sdown [{t("pages.shell.loginNode.popoverContentFile")}] {t("pages.shell.loginNode.popoverContent5")}
+ {t("pages.shell.loginNode.popoverContent8")}sdown hello.txt +

+

{t("pages.shell.loginNode.popoverContent9")}: + sedit [{t("pages.shell.loginNode.popoverContentFile")}] + {t("pages.shell.loginNode.popoverContent10")} + sedit [{t("pages.shell.loginNode.popoverContentFile")}] + {t("pages.shell.loginNode.popoverContent11")}
+ {t("pages.shell.loginNode.popoverContent8")}sedit hello.txt +

+

{t("pages.shell.loginNode.popoverContent6")}sopen - {t("pages.shell.loginNode.popoverContent7")}
- {t("pages.shell.loginNode.popoverContent8")}sdown hello.txt

+ {t("pages.shell.loginNode.popoverContent7")} +

)} > diff --git a/docs/docs/deploy/config/portal/shell.md b/docs/docs/deploy/config/portal/shell.md index ffe3df3225..7398cae869 100644 --- a/docs/docs/deploy/config/portal/shell.md +++ b/docs/docs/deploy/config/portal/shell.md @@ -7,8 +7,12 @@ title: Shell终端文件传输功能 Shell终端支持输入命令跳转到文件系统,进行文件的上传和下载;支持下载指定文件。 +## `sopen`命令 + 输入`sopen`命令后,会跳转到文件系统的当前目录,用户可以在图形界面进行文件上传或者下载。 +## `sdown`命令 + 输入`sdown [文件名]`,用户当前路径的该文件会被下载到本地,目前仅支持直接输入当前目录下的文件名,不支持相对路径,如果需要下载其他目录下的文件请使用`sopen`命令跳转到文件系统。如果用户输入了相对路径,会提示用户不能使用相对路径。 使用示例: @@ -21,7 +25,18 @@ sdown hello.txt 1. 可以进入A目录,然后`sdown [文件名]`下载 2. 也可以`sopen`进入文件系统以后,在图形界面切换到A目录选择文件进行下载。 +## `sedit`命令 + +输入`sedit [文件名]`后会跳转到图形界面的文本编辑器。 + +使用示例: + +```bash +sedit hello.txt +``` + +## 注意 -`sopen`和`sdown [文件名]`这两个命令仅在SCOW的Shell终端中使用有效。 +`sopen`、`sdown [文件名]`和`sedit [文件名]`这三个命令仅在SCOW的Shell终端中使用有效。 在系统启动时,系统会自动上传到登录节点的`/etc/profile.d/`目录下一个`scow-shell-file.sh`脚本,用于在Shell终端中进行文件系统的跳转和文件的下载。如果`/etc/profile.d/`目录不存在会创建该目录。