diff --git a/web/public/locales/zh-CN/translation.json b/web/public/locales/zh-CN/translation.json index 255e5b93be..19039212ca 100644 --- a/web/public/locales/zh-CN/translation.json +++ b/web/public/locales/zh-CN/translation.json @@ -12,17 +12,19 @@ "DeleteConfirm": "确认要删除函数吗?", "SearchPlacehoder": "输入函数名搜索", "CreateTime": "创建时间", - "Editting...": "编辑中 (Ctrl/⌘ + S 保存)", - "LocalSaved...": "已保存本地", - "LocalSavedTip": "(代码已保存到本地,可直接发起调试)", + "Editting...": "已编辑", "FunctionPanel": { "Debug": "调试", "Deploy": "发布", "EmptyText": "请先选择函数" }, + "Message": { + "DeploySuccess": "发布成功" + }, "Common": { "Dialog": { "Confirm": "确定", + "ConfirmDeploy": "确认发布", "Cancel": "取消" } } diff --git a/web/src/components/Editor/CommonDiffEditor.tsx b/web/src/components/Editor/CommonDiffEditor.tsx new file mode 100644 index 0000000000..7a0a6b5e1b --- /dev/null +++ b/web/src/components/Editor/CommonDiffEditor.tsx @@ -0,0 +1,29 @@ +import { DiffEditor as MonacoDiffEditor } from "@monaco-editor/react"; + +export default function CommonDiffEditor(props: { original: string; modified: string }) { + const { original, modified } = props; + + return ( +
+ { + monaco.editor.setTheme("lafEditorTheme"); + }} + original={original} + modified={modified} + language={"typescript"} + /> +
+ ); +} diff --git a/web/src/components/FileStatusIcon/index.tsx b/web/src/components/FileStatusIcon/index.tsx index 1145144ddf..e93efde309 100644 --- a/web/src/components/FileStatusIcon/index.tsx +++ b/web/src/components/FileStatusIcon/index.tsx @@ -1,4 +1,3 @@ -import React from "react"; import { Icon } from "@chakra-ui/icons"; export const FileStatus = { @@ -12,7 +11,7 @@ export default function FileStatusIcon(props: { status: string }) { switch (status) { case FileStatus.modify: return ( - + ); diff --git a/web/src/pages/app/functions/index.tsx b/web/src/pages/app/functions/index.tsx index 1027caa73a..9c4d1e52d5 100644 --- a/web/src/pages/app/functions/index.tsx +++ b/web/src/pages/app/functions/index.tsx @@ -2,8 +2,7 @@ * cloud functions index page ***************************/ -import { useState } from "react"; -import { Badge, Button, Center, HStack } from "@chakra-ui/react"; +import { Badge, Center, HStack } from "@chakra-ui/react"; import { t } from "i18next"; import CopyText from "@/components/CopyText"; @@ -16,50 +15,22 @@ import RightPanel from "../mods/RightPanel"; import DebugPanel from "./mods/DebugPannel"; import DependecyPanel from "./mods/DependecePanel"; +import DeployButton from "./mods/DeployButton"; import FunctionPanel from "./mods/FunctionPanel"; -import { useUpdateFunctionMutation } from "./service"; import useFunctionStore from "./store"; import useFunctionCache from "@/hooks/useFuncitonCache"; import useHotKey from "@/hooks/useHotKey"; -import useGlobalStore from "@/pages/globalStore"; function FunctionPage() { const store = useFunctionStore((store) => store); - const { currentFunction, updateFunctionCode, functionCodes } = store; + const { currentFunction, updateFunctionCode } = store; const functionCache = useFunctionCache(); - const { showSuccess } = useGlobalStore((state) => state); - - const updateFunctionMutation = useUpdateFunctionMutation(); - - const [localSaved, setLocalSaved] = useState(false); - - const deploy = async () => { - const res = await updateFunctionMutation.mutateAsync({ - description: currentFunction?.desc, - code: functionCache.getCache(currentFunction!.id), - methods: currentFunction?.methods, - websocket: currentFunction?.websocket, - name: currentFunction?.name, - }); - if (!res.error) { - store.setCurrentFunction(res.data); - // delete cache after deploy - functionCache.removeCache(currentFunction!.id); - showSuccess("deployed successfully"); - } - }; - - useHotKey("p", async () => { - deploy(); - }); - useHotKey("s", async () => { - setLocalSaved(true); - functionCache.setCache(currentFunction!.id, functionCodes[currentFunction!.id]); + // showInfo("已开启自动保存"); }); return ( @@ -82,22 +53,13 @@ function FunctionPage() { - {localSaved ? ( -
- - {t("LocalSaved...")} - - {t("LocalSavedTip")} -
- ) : ( - currentFunction?.id && + {currentFunction?.id && functionCache.getCache(currentFunction?.id) !== currentFunction?.source?.code && (
- {t("Editting...")}{" "} + {t("Editting...")}
- ) - )} + )} {/* */}
@@ -110,19 +72,7 @@ function FunctionPage() { )} - - + @@ -131,9 +81,8 @@ function FunctionPage() { path={currentFunction?.name || ""} value={functionCache.getCache(currentFunction!.id)} onChange={(value) => { - setLocalSaved(false); updateFunctionCode(currentFunction, value || ""); - // functionCache.setCache(currentFunction!.id, value || ""); + functionCache.setCache(currentFunction!.id, value || ""); }} /> ) : ( diff --git a/web/src/pages/app/functions/mods/DebugPannel/index.tsx b/web/src/pages/app/functions/mods/DebugPannel/index.tsx index b0c9dad384..49a509bc68 100644 --- a/web/src/pages/app/functions/mods/DebugPannel/index.tsx +++ b/web/src/pages/app/functions/mods/DebugPannel/index.tsx @@ -42,6 +42,10 @@ export default function DebugPanel() { runningCode(); }); + useHotKey("s", () => { + runningCode(); + }); + const runningCode = async () => { if (isLoading || !currentFunction?.id) return; setIsLoading(true); diff --git a/web/src/pages/app/functions/mods/DeployButton/index.tsx b/web/src/pages/app/functions/mods/DeployButton/index.tsx new file mode 100644 index 0000000000..744ce70d93 --- /dev/null +++ b/web/src/pages/app/functions/mods/DeployButton/index.tsx @@ -0,0 +1,98 @@ +import React from "react"; +import { + Button, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + useDisclosure, +} from "@chakra-ui/react"; +import { t } from "i18next"; + +import CommonDiffEditor from "@/components/Editor/CommonDiffEditor"; + +import { useUpdateFunctionMutation } from "../../service"; +import useFunctionStore from "../../store"; + +import useFunctionCache from "@/hooks/useFuncitonCache"; +import useHotKey from "@/hooks/useHotKey"; +import useGlobalStore from "@/pages/globalStore"; + +export default function DeployButton() { + const { isOpen, onOpen, onClose } = useDisclosure(); + const store = useFunctionStore((state) => state); + const functionCache = useFunctionCache(); + + const { showSuccess } = useGlobalStore((state) => state); + + const updateFunctionMutation = useUpdateFunctionMutation(); + + useHotKey("p", async () => { + onOpen(); + }); + + const deploy = async () => { + const res = await updateFunctionMutation.mutateAsync({ + description: store.currentFunction?.desc, + code: functionCache.getCache(store.currentFunction!.id), + methods: store.currentFunction?.methods, + websocket: store.currentFunction?.websocket, + name: store.currentFunction?.name, + }); + if (!res.error) { + store.setCurrentFunction(res.data); + // delete cache after deploy + functionCache.removeCache(store.currentFunction!.id); + onClose(); + showSuccess(t("Message.DeploySuccess")); + } + }; + + return ( + <> + + + + + + Code Diff + + + + + + + + + + + + + ); +} diff --git a/web/src/pages/globalStore.ts b/web/src/pages/globalStore.ts index 088ec8373b..cb41e60148 100644 --- a/web/src/pages/globalStore.ts +++ b/web/src/pages/globalStore.ts @@ -23,6 +23,7 @@ type State = { init(appid?: string): void; showSuccess: (text: string | React.ReactNode) => void; + showInfo: (text: string | React.ReactNode) => void; showError: (text: string | React.ReactNode) => void; }; @@ -92,6 +93,19 @@ const useGlobalStore = create()( }, }); }, + + showInfo: (text: string | React.ReactNode) => { + toast({ + position: "top", + title: text, + variant: "subtle", + duration: 1000, + containerStyle: { + maxWidth: "100%", + minWidth: "100px", + }, + }); + }, })), ), );