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",
+ },
+ });
+ },
})),
),
);