Skip to content

Commit

Permalink
feat(web): add func deploy confirm & code diff info (#550)
Browse files Browse the repository at this point in the history
  • Loading branch information
LeezQ authored Dec 16, 2022
1 parent 9d6f8b0 commit 682dcc5
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 65 deletions.
8 changes: 5 additions & 3 deletions web/public/locales/zh-CN/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,19 @@
"DeleteConfirm": "确认要删除函数吗?",
"SearchPlacehoder": "输入函数名搜索",
"CreateTime": "创建时间",
"Editting...": "编辑中 (Ctrl/⌘ + S 保存)",
"LocalSaved...": "已保存本地",
"LocalSavedTip": "(代码已保存到本地,可直接发起调试)",
"Editting...": "已编辑",
"FunctionPanel": {
"Debug": "调试",
"Deploy": "发布",
"EmptyText": "请先选择函数"
},
"Message": {
"DeploySuccess": "发布成功"
},
"Common": {
"Dialog": {
"Confirm": "确定",
"ConfirmDeploy": "确认发布",
"Cancel": "取消"
}
}
Expand Down
29 changes: 29 additions & 0 deletions web/src/components/Editor/CommonDiffEditor.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="">
<MonacoDiffEditor
options={{
readOnly: true,
automaticLayout: true,
minimap: {
enabled: false,
},
fontSize: 14,
// fontFamily: "monospace",
scrollBeyondLastLine: false,
}}
height="70vh"
onMount={(editor, monaco) => {
monaco.editor.setTheme("lafEditorTheme");
}}
original={original}
modified={modified}
language={"typescript"}
/>
</div>
);
}
3 changes: 1 addition & 2 deletions web/src/components/FileStatusIcon/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from "react";
import { Icon } from "@chakra-ui/icons";

export const FileStatus = {
Expand All @@ -12,7 +11,7 @@ export default function FileStatusIcon(props: { status: string }) {
switch (status) {
case FileStatus.modify:
return (
<Icon viewBox="0 0 48 48" fill="blue.400">
<Icon viewBox="0 0 30 30" fill="yellow.500">
<path d="M0 23.0361C0 23.9858 0.766071 24.753 1.71429 24.753C2.6625 24.753 3.42857 23.9858 3.42857 23.0361H0ZM1.71429 2.43373L3.13929 1.47873C2.72143 0.850996 1.93929 0.56664 1.21607 0.786613C0.492857 1.00659 0 1.67724 0 2.43373H1.71429ZM12 17.8855L10.575 18.8405C10.8911 19.3181 11.4268 19.6024 12 19.6024C12.5732 19.6024 13.1089 19.3181 13.425 18.8405L12 17.8855ZM22.2857 2.43373H24C24 1.67724 23.5071 1.01195 22.7839 0.791979C22.0607 0.572005 21.2786 0.850996 20.8607 1.48409L22.2857 2.43373ZM20.5714 23.0361C20.5714 23.9858 21.3375 24.753 22.2857 24.753C23.2339 24.753 24 23.9858 24 23.0361H20.5714ZM3.42857 23.0361V2.43373H0V23.0361H3.42857ZM0.289286 3.38874L10.575 18.8405L13.4304 16.9359L3.14464 1.48409L0.289286 3.38874ZM13.4304 18.8405L23.7161 3.38874L20.8607 1.47873L10.575 16.9305L13.4304 18.8352V18.8405ZM20.5714 2.43373V23.0361H24V2.43373H20.5714Z" />
</Icon>
);
Expand Down
69 changes: 9 additions & 60 deletions web/src/pages/app/functions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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 (
Expand All @@ -82,22 +53,13 @@ function FunctionPage() {
</span>
</span>
<span className="ml-4 ">
{localSaved ? (
<div>
<Badge colorScheme="gray" className="mr-2">
{t("LocalSaved...")}
</Badge>
<span className="ml-2 text-slate-500 text-sm">{t("LocalSavedTip")}</span>
</div>
) : (
currentFunction?.id &&
{currentFunction?.id &&
functionCache.getCache(currentFunction?.id) !==
currentFunction?.source?.code && (
<div>
<Badge colorScheme="purple">{t("Editting...")}</Badge>{" "}
<Badge colorScheme="purple">{t("Editting...")}</Badge>
</div>
)
)}
)}

{/* <FileStatusIcon status={FileStatus.deleted} /> */}
</span>
Expand All @@ -110,19 +72,7 @@ function FunctionPage() {
<CopyText text={store.getFunctionUrl()} />
</span>
)}

<Button
size="sm"
borderRadius={4}
disabled={store.getFunctionUrl() === ""}
colorScheme="blue"
padding="0 12px"
onClick={() => {
deploy();
}}
>
{t("FunctionPanel.Deploy")} (⌘ + P)
</Button>
<DeployButton />
</HStack>
</PanelHeader>
</div>
Expand All @@ -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 || "");
}}
/>
) : (
Expand Down
4 changes: 4 additions & 0 deletions web/src/pages/app/functions/mods/DebugPannel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ export default function DebugPanel() {
runningCode();
});

useHotKey("s", () => {
runningCode();
});

const runningCode = async () => {
if (isLoading || !currentFunction?.id) return;
setIsLoading(true);
Expand Down
98 changes: 98 additions & 0 deletions web/src/pages/app/functions/mods/DeployButton/index.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<>
<Button
size="sm"
borderRadius={4}
disabled={store.getFunctionUrl() === ""}
colorScheme="blue"
padding="0 12px"
onClick={() => {
onOpen();
}}
>
{t("FunctionPanel.Deploy")} (⌘ + P)
</Button>

<Modal isOpen={isOpen} onClose={onClose} size="6xl" isCentered>
<ModalOverlay />
<ModalContent maxW={"80%"}>
<ModalHeader>Code Diff</ModalHeader>
<ModalCloseButton />
<ModalBody borderBottom={"1px"} borderBottomColor="gray.200">
<CommonDiffEditor
original={store.currentFunction.source?.code}
modified={functionCache.getCache(store.currentFunction.id)}
/>
</ModalBody>

<ModalFooter>
<Button mr={3} onClick={onClose}>
{t("Cancel")}
</Button>
<Button
colorScheme={"blue"}
onClick={() => {
deploy();
}}
>
{t("Common.Dialog.ConfirmDeploy")}
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
);
}
14 changes: 14 additions & 0 deletions web/src/pages/globalStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand Down Expand Up @@ -92,6 +93,19 @@ const useGlobalStore = create<State>()(
},
});
},

showInfo: (text: string | React.ReactNode) => {
toast({
position: "top",
title: text,
variant: "subtle",
duration: 1000,
containerStyle: {
maxWidth: "100%",
minWidth: "100px",
},
});
},
})),
),
);
Expand Down

0 comments on commit 682dcc5

Please sign in to comment.