Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web): complete function compile #545

Merged
merged 1 commit into from
Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions web/public/locales/zh-CN/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@
"Cancel": "取消",
"Edit": "编辑",
"Delete": "删除",
"DeleteConfirm": "确认要删除函数吗?",
"SearchPlacehoder": "输入函数名搜索",
"CreateTime": "创建时间",
"Editting...": "编辑中...",
"FunctionPanel": {
"Debug": "调试",
"Deploy": "发布",
"EmptyText": "请先选择函数"
},
"Common": {
"Dialog": {
"Confirm": "确定",
Expand Down
23 changes: 23 additions & 0 deletions web/src/apis/typing.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,3 +326,26 @@ export interface IdIndex {
export interface Key {
_id: number;
}

export interface TFunction {
id: string;
appid: string;
name: string;
source: Source;
desc: string;
tags: any[];
websocket: boolean;
methods: string[];
createdAt: string;
updatedAt: string;
createdBy: string;
}

export interface Source {
code: string;
compiled: string;
uri: any;
version: number;
hash: any;
lang: any;
}
14 changes: 13 additions & 1 deletion web/src/apis/v1/api-auto.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ declare namespace Definitions {
code?: string /* The source code of the function */;
};

export type CompileFunctionDto = {
code?: string /* The source code of the function */;
};

export type CreateApplicationDto = {
name?: string;
state?: string;
Expand Down Expand Up @@ -124,7 +128,7 @@ declare namespace Paths {
namespace FunctionControllerCompile {
export type QueryParameters = any;

export type BodyParameters = any;
export type BodyParameters = Definitions.CompileFunctionDto;

export type Responses = any;
}
Expand Down Expand Up @@ -368,4 +372,12 @@ declare namespace Paths {

export type Responses = any;
}

namespace LogControllerGetLogs {
export type QueryParameters = any;

export type BodyParameters = any;

export type Responses = any;
}
}
19 changes: 18 additions & 1 deletion web/src/apis/v1/apps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export async function FunctionControllerRemove(
* Compile a function
*/
export async function FunctionControllerCompile(
params: Paths.FunctionControllerCompile.BodyParameters | any,
params: Definitions.CompileFunctionDto,
): Promise<Paths.FunctionControllerCompile.Responses> {
// /v1/apps/{appid}/functions/{name}/compile
let _params: { [key: string]: any } = {
Expand Down Expand Up @@ -467,3 +467,20 @@ export async function BucketControllerRemove(
data: params,
});
}

/**
* Get function logs
*/
export async function LogControllerGetLogs(
params: Paths.LogControllerGetLogs.BodyParameters | any,
): Promise<Paths.LogControllerGetLogs.Responses> {
// /v1/apps/{appid}/logs/functions
let _params: { [key: string]: any } = {
appid: localStorage.getItem("app"),
...params,
};
return request(`/v1/apps/${_params.appid}/logs/functions`, {
method: "GET",
params: params,
});
}
4 changes: 2 additions & 2 deletions web/src/components/Editor/JsonEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Editor from "@monaco-editor/react";

export default function JsonEditor(props: {
value: string | object;
value: string;
height?: string;
onChange?: (value: string | undefined) => void;
}) {
Expand All @@ -26,7 +26,7 @@ export default function JsonEditor(props: {
return (
<Editor
defaultLanguage="json"
value={JSON.stringify(value, null, 2)}
value={JSON.stringify(JSON.parse(value), null, 2) || ""}
height={props.height || "100%"}
onChange={(value, event) => {
props.onChange && props.onChange(value);
Expand Down
29 changes: 29 additions & 0 deletions web/src/hooks/useFuncitonCache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import useFunctionStore from "@/pages/app/functions/store";

function useFunctionCache() {
const CACHE_KEY_PREFIX = "$cached_function@";

const currentFunction = useFunctionStore((state) => state.currentFunction);

function getCache(functionId: string): string {
return (
localStorage.getItem(CACHE_KEY_PREFIX + functionId) || currentFunction?.source?.code || ""
);
}

function setCache(functionId: string, value: string) {
localStorage.setItem(CACHE_KEY_PREFIX + functionId, value);
}

function removeCache(functionId: string) {
localStorage.removeItem(CACHE_KEY_PREFIX + functionId);
}

return {
getCache,
setCache,
removeCache,
};
}

export default useFunctionCache;
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function ColPannel() {
</Button>
</div>
<div className="border p-2 rounded absolute top-12 bottom-0 left-0 right-0">
<JsonEditor value={{ name: "hello" }} />
<JsonEditor value={JSON.stringify({ name: "hello" })} />
</div>
</div>
);
Expand Down
116 changes: 64 additions & 52 deletions web/src/pages/app/functions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,42 @@ 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, functionCodes } = store;
const { currentFunction, updateFunctionCode } = store;

const functionCache = useFunctionCache();

const { showSuccess } = useGlobalStore((state) => state);

const updateFunctionMutation = useUpdateFunctionMutation();

useHotKey("s", async () => {
const deploy = async () => {
const res = await updateFunctionMutation.mutateAsync({
description: currentFunction?.desc,
code: functionCodes[currentFunction?.id || ""],
code: functionCache.getCache(currentFunction!.id),
methods: currentFunction?.methods,
websocket: currentFunction?.websocket,
name: currentFunction?.name,
});
if (!res.error) {
store.setCurrentFunction(res.data);
store.updateFunctionCode(res.data, res.data.source.code);
showSuccess("saved successfully");
// delete cache after deploy
functionCache.removeCache(currentFunction!.id);
showSuccess("deployed successfully");
}
};

useHotKey("p", async () => {
deploy();
});

useHotKey("s", async () => {
// functionCache.setCache(currentFunction!.id, functionCodes[currentFunction!.id]);
});

return (
Expand All @@ -53,62 +65,62 @@ function FunctionPage() {
<DependecyPanel />
</LeftPanel>
<RightPanel>
<div className="border-b" style={{ height: 36 }}>
<PanelHeader>
<div className="flex items-center">
<FileTypeIcon type={FileType.js} />
<span className="font-bold text-base ml-2">
{currentFunction?.name}
<span className="ml-2 text-slate-400 font-normal">
{currentFunction?.desc ? currentFunction?.desc : ""}
</span>
</span>
<span className="ml-4 ">
{functionCodes[currentFunction?.id || ""] &&
functionCodes[currentFunction?.id || ""] !== currentFunction?.source.code && (
<Badge colorScheme="purple">{t("Editting...")}</Badge>
)}
{/* <FileStatusIcon status={FileStatus.deleted} /> */}
</span>
</div>

<HStack spacing="4">
{store.getFunctionUrl() !== "" && (
<span>
<span className=" text-slate-500">调用地址:</span>
<span className="mr-2">{store.getFunctionUrl()}</span>
<CopyText text={store.getFunctionUrl()} />
</span>
)}

<Button
size="sm"
borderRadius={2}
disabled={store.getFunctionUrl() === ""}
colorScheme="primary"
padding="0 12px"
onClick={() => {
console.log("发布");
console.log(currentFunction?.source.code);
}}
>
发布 (⌘ + S)
</Button>
</HStack>
</PanelHeader>
</div>
<div className="flex flex-row h-full w-full">
<div className="flex-1 border-r border-r-slate-200 overflow-hidden ">
<div className="border-b" style={{ height: 36 }}>
<PanelHeader>
<div className="flex items-center">
<FileTypeIcon type={FileType.js} />
<span className="font-bold text-base ml-2">
{currentFunction?.name}
<span className="ml-2 text-slate-400 font-normal">
{currentFunction?.desc ? currentFunction?.desc : ""}
</span>
</span>
<span className="ml-4 ">
{currentFunction?.id &&
functionCache.getCache(currentFunction?.id) !==
currentFunction?.source?.code && (
<Badge colorScheme="purple">{t("Editting...")}</Badge>
)}
{/* <FileStatusIcon status={FileStatus.deleted} /> */}
</span>
</div>

<HStack spacing="4">
{store.getFunctionUrl() !== "" && (
<span>
<span className=" text-slate-500">调用地址:{store.getFunctionUrl()}</span>
<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>
</HStack>
</PanelHeader>
</div>
{currentFunction?.name ? (
<FunctionEditor
path={currentFunction?.name || ""}
value={functionCodes[currentFunction.id] || currentFunction.source.code}
value={functionCache.getCache(currentFunction!.id)}
onChange={(value) => {
store.updateFunctionCode(currentFunction, value || "");
updateFunctionCode(currentFunction, value || "");
functionCache.setCache(currentFunction!.id, value || "");
}}
/>
) : (
<Center className="h-full">请创建函数</Center>
<Center className="h-full">{t("FunctionPanel.EmptyText")}</Center>
)}
</div>
<div style={{ width: "30%" }}>
Expand Down
Loading