From d0d61f549a3c245933050f1bdb5d07af68cf57c7 Mon Sep 17 00:00:00 2001
From: kongwy229 <1419906205@qq.com>
Date: Mon, 16 Jan 2023 20:42:07 +0800
Subject: [PATCH] feat(web): add trigger panel
---
web/public/locales/zh-CN/translation.json | 6 +-
web/src/components/CommonIcon/index.ts | 7 +
web/src/constants/index.ts | 1 +
.../app/database/CollectionDataList/index.tsx | 12 +-
web/src/pages/app/database/index.tsx | 15 +-
.../functions/mods/FunctionPanel/index.tsx | 7 +
web/src/pages/app/index.tsx | 5 +
web/src/pages/app/mods/SideBar/index.tsx | 9 ++
web/src/pages/app/storages/index.tsx | 20 +--
.../storages/mods/CreateBucketModal/index.tsx | 7 +-
.../app/trigger/AddTriggerModal/index.tsx | 143 ++++++++++++++++++
web/src/pages/app/trigger/index.tsx | 123 +++++++++++++++
web/src/pages/app/trigger/service.ts | 65 ++++++++
web/src/utils/request.ts | 2 +-
14 files changed, 392 insertions(+), 30 deletions(-)
create mode 100644 web/src/pages/app/trigger/AddTriggerModal/index.tsx
create mode 100644 web/src/pages/app/trigger/index.tsx
create mode 100644 web/src/pages/app/trigger/service.ts
diff --git a/web/public/locales/zh-CN/translation.json b/web/public/locales/zh-CN/translation.json
index 9fd4b0cbf3..6f785ebfba 100644
--- a/web/public/locales/zh-CN/translation.json
+++ b/web/public/locales/zh-CN/translation.json
@@ -20,7 +20,9 @@
"EmptyText": "暂无函数信息,"
},
"CollectionPanel": {
- "CollectionAdd": "新建集合"
+ "CollectionAdd": "新建集合",
+ "EmptyCollectionText": "暂无集合信息,",
+ "EmptyPolicyText": "暂无策略信息,"
},
"StoragePanel": {
"Upload": "上传",
@@ -45,4 +47,4 @@
},
"SearchPlaceholder": "请输入函数名查询",
"noData": "暂无数据"
-}
+}
\ No newline at end of file
diff --git a/web/src/components/CommonIcon/index.ts b/web/src/components/CommonIcon/index.ts
index 4edf975271..e8511a1fe5 100644
--- a/web/src/components/CommonIcon/index.ts
+++ b/web/src/components/CommonIcon/index.ts
@@ -1,6 +1,13 @@
import { createIcon } from "@chakra-ui/react";
+
export const MoreIcon = createIcon({
displayName: "MoreIcon",
viewBox: "0 0 4 16",
d: "M2 16C1.45 16 0.979334 15.8043 0.588 15.413C0.196 15.021 0 14.55 0 14C0 13.45 0.196 12.979 0.588 12.587C0.979334 12.1957 1.45 12 2 12C2.55 12 3.021 12.1957 3.413 12.587C3.80433 12.979 4 13.45 4 14C4 14.55 3.80433 15.021 3.413 15.413C3.021 15.8043 2.55 16 2 16ZM2 10C1.45 10 0.979334 9.804 0.588 9.412C0.196 9.02067 0 8.55 0 8C0 7.45 0.196 6.979 0.588 6.587C0.979334 6.19567 1.45 6 2 6C2.55 6 3.021 6.19567 3.413 6.587C3.80433 6.979 4 7.45 4 8C4 8.55 3.80433 9.02067 3.413 9.412C3.021 9.804 2.55 10 2 10ZM2 4C1.45 4 0.979334 3.804 0.588 3.412C0.196 3.02067 0 2.55 0 2C0 1.45 0.196 0.979333 0.588 0.588C0.979334 0.196 1.45 0 2 0C2.55 0 3.021 0.196 3.413 0.588C3.80433 0.979333 4 1.45 4 2C4 2.55 3.80433 3.02067 3.413 3.412C3.021 3.804 2.55 4 2 4Z",
});
+
+export const TriggerIcon = createIcon({
+ displayName: "TriggerIcon",
+ viewBox: "0 0 16 16",
+ d: "M4.33333 14.6667C3.41111 14.6667 2.62511 14.3418 1.97533 13.692C1.32511 13.0418 1 12.2556 1 11.3333C1 10.5222 1.25289 9.81378 1.75867 9.208C2.264 8.60267 2.9 8.22222 3.66667 8.06667V9.45C3.27778 9.58333 2.95822 9.82222 2.708 10.1667C2.45822 10.5111 2.33333 10.9 2.33333 11.3333C2.33333 11.8889 2.52778 12.3611 2.91667 12.75C3.30556 13.1389 3.77778 13.3333 4.33333 13.3333C4.88889 13.3333 5.36111 13.1389 5.75 12.75C6.13889 12.3611 6.33333 11.8889 6.33333 11.3333V10.6667H10.25C10.3389 10.5667 10.4473 10.486 10.5753 10.4247C10.7029 10.3638 10.8444 10.3333 11 10.3333C11.2778 10.3333 11.5138 10.4307 11.708 10.6253C11.9027 10.8196 12 11.0556 12 11.3333C12 11.6111 11.9027 11.8471 11.708 12.0413C11.5138 12.236 11.2778 12.3333 11 12.3333C10.8444 12.3333 10.7029 12.3029 10.5753 12.242C10.4473 12.1807 10.3389 12.1 10.25 12H7.6C7.44444 12.7667 7.064 13.4029 6.45867 13.9087C5.85289 14.414 5.14444 14.6667 4.33333 14.6667ZM11 14.6667C10.3778 14.6667 9.814 14.5138 9.30867 14.208C8.80289 13.9027 8.40556 13.5 8.11667 13H9.9C10.0556 13.1111 10.2278 13.1944 10.4167 13.25C10.6056 13.3056 10.8 13.3333 11 13.3333C11.5556 13.3333 12.0278 13.1389 12.4167 12.75C12.8056 12.3611 13 11.8889 13 11.3333C13 10.7778 12.8056 10.3056 12.4167 9.91667C12.0278 9.52778 11.5556 9.33333 11 9.33333C10.7778 9.33333 10.5722 9.36378 10.3833 9.42467C10.1944 9.486 10.0167 9.57778 9.85 9.7L7.81667 6.31667C7.58333 6.27222 7.38889 6.16111 7.23333 5.98333C7.07778 5.80556 7 5.58889 7 5.33333C7 5.05556 7.09733 4.81956 7.292 4.62533C7.48622 4.43067 7.72222 4.33333 8 4.33333C8.27778 4.33333 8.51378 4.43067 8.708 4.62533C8.90267 4.81956 9 5.05556 9 5.33333V5.47533C9 5.514 8.98889 5.56111 8.96667 5.61667L10.4167 8.05C10.5056 8.02778 10.6 8.01378 10.7 8.008C10.8 8.00267 10.9 8 11 8C11.9222 8 12.7084 8.32489 13.3587 8.97467C14.0084 9.62489 14.3333 10.4111 14.3333 11.3333C14.3333 12.2556 14.0084 13.0418 13.3587 13.692C12.7084 14.3418 11.9222 14.6667 11 14.6667ZM4.33333 12.3333C4.05556 12.3333 3.81956 12.236 3.62533 12.0413C3.43067 11.8471 3.33333 11.6111 3.33333 11.3333C3.33333 11.0889 3.41111 10.8778 3.56667 10.7C3.72222 10.5222 3.91111 10.4056 4.13333 10.35L5.7 7.75C5.37778 7.45 5.12511 7.09156 4.942 6.67467C4.75844 6.25822 4.66667 5.81111 4.66667 5.33333C4.66667 4.41111 4.99178 3.62511 5.642 2.97533C6.29178 2.32511 7.07778 2 8 2C8.92222 2 9.70844 2.32511 10.3587 2.97533C11.0084 3.62511 11.3333 4.41111 11.3333 5.33333H10C10 4.77778 9.80556 4.30556 9.41667 3.91667C9.02778 3.52778 8.55555 3.33333 8 3.33333C7.44444 3.33333 6.97222 3.52778 6.58333 3.91667C6.19444 4.30556 6 4.77778 6 5.33333C6 5.81111 6.14444 6.23044 6.43333 6.59133C6.72222 6.95267 7.08889 7.18333 7.53333 7.28333L5.28333 11.0333C5.30556 11.0889 5.31956 11.1389 5.32533 11.1833C5.33067 11.2278 5.33333 11.2778 5.33333 11.3333C5.33333 11.6111 5.236 11.8471 5.04133 12.0413C4.84711 12.236 4.61111 12.3333 4.33333 12.3333Z",
+});
diff --git a/web/src/constants/index.ts b/web/src/constants/index.ts
index 1cf7f55894..57b46909e0 100644
--- a/web/src/constants/index.ts
+++ b/web/src/constants/index.ts
@@ -4,6 +4,7 @@ export const SmallNavHeight = 42;
export const Pages = {
function: "function",
+ trigger: "trigger",
storage: "storage",
database: "database",
logs: "logs",
diff --git a/web/src/pages/app/database/CollectionDataList/index.tsx b/web/src/pages/app/database/CollectionDataList/index.tsx
index 0a2de11f62..14d922b2f9 100644
--- a/web/src/pages/app/database/CollectionDataList/index.tsx
+++ b/web/src/pages/app/database/CollectionDataList/index.tsx
@@ -1,6 +1,5 @@
import { useTranslation } from "react-i18next";
-import { AddIcon } from "@chakra-ui/icons";
-import { Button } from "@chakra-ui/react";
+import { Center } from "@chakra-ui/react";
import CreateCollectionModal from "../mods/CreateCollectionModal";
import useDBMStore from "../store";
@@ -13,13 +12,12 @@ export default function CollectionDataList() {
return (
<>
{store.currentDB === undefined ? (
-
+
+ {t("CollectionPanel.EmptyCollectionText")}
- }>
- {t("CollectionPanel.CollectionAdd")}
-
+ 立即创建
-
+
) : (
)}
diff --git a/web/src/pages/app/database/index.tsx b/web/src/pages/app/database/index.tsx
index c1ba71f5b5..c03b59aef3 100644
--- a/web/src/pages/app/database/index.tsx
+++ b/web/src/pages/app/database/index.tsx
@@ -1,8 +1,8 @@
/****************************
* cloud functions database page
***************************/
-import { AddIcon } from "@chakra-ui/icons";
-import { Button } from "@chakra-ui/react";
+import { Button, Center } from "@chakra-ui/react";
+import { t } from "i18next";
import Content from "@/components/Content";
import { Col, Row } from "@/components/Grid";
@@ -25,7 +25,7 @@ function DatabasePage() {
-
+
@@ -34,13 +34,12 @@ function DatabasePage() {
{store.currentShow === "DB" ? (
) : store.currentPolicy === undefined ? (
-
+
+ {t("CollectionPanel.EmptyPolicyText")}
- }>
- 添加策略
-
+ 立即添加
-
+
) : (
)}
diff --git a/web/src/pages/app/functions/mods/FunctionPanel/index.tsx b/web/src/pages/app/functions/mods/FunctionPanel/index.tsx
index 000cccd212..d4a20dc1e0 100644
--- a/web/src/pages/app/functions/mods/FunctionPanel/index.tsx
+++ b/web/src/pages/app/functions/mods/FunctionPanel/index.tsx
@@ -8,6 +8,7 @@ import { AddIcon, DeleteIcon, EditIcon } from "@chakra-ui/icons";
import { Input } from "@chakra-ui/react";
import { t } from "i18next";
+import { TriggerIcon } from "@/components/CommonIcon";
import ConfirmButton from "@/components/ConfirmButton";
import FileTypeIcon, { FileType } from "@/components/FileTypeIcon";
import IconWrap from "@/components/IconWrap";
@@ -21,6 +22,7 @@ import useFunctionStore from "../../store";
import CreateModal from "./CreateModal";
import { TFunction } from "@/apis/typing";
+import AddTriggerModal from "@/pages/app/trigger/AddTriggerModal";
import useGlobalStore from "@/pages/globalStore";
export default function FunctionList() {
@@ -100,6 +102,11 @@ export default function FunctionList() {
{func?.name}
+
+
+
+
+
diff --git a/web/src/pages/app/index.tsx b/web/src/pages/app/index.tsx
index 8c7f700412..095d85a1b3 100644
--- a/web/src/pages/app/index.tsx
+++ b/web/src/pages/app/index.tsx
@@ -7,6 +7,7 @@ import DatabasePage from "./database";
import FunctionPage from "./functions";
import LogsPage from "./logs";
import StoragePage from "./storages";
+import TriggerPage from "./trigger";
function AppDetail() {
const { visitedViews, currentPageId } = useGlobalStore();
@@ -20,6 +21,10 @@ function AppDetail() {
pageId: Pages.function,
component: FunctionPage,
},
+ {
+ pageId: Pages.trigger,
+ component: TriggerPage,
+ },
{
pageId: Pages.database,
component: DatabasePage,
diff --git a/web/src/pages/app/mods/SideBar/index.tsx b/web/src/pages/app/mods/SideBar/index.tsx
index 9b7dc2de5c..d1f0cf6e03 100644
--- a/web/src/pages/app/mods/SideBar/index.tsx
+++ b/web/src/pages/app/mods/SideBar/index.tsx
@@ -9,6 +9,7 @@ import { useNavigate, useParams } from "react-router-dom";
import { Center } from "@chakra-ui/react";
import clsx from "clsx";
+import { TriggerIcon } from "@/components/CommonIcon";
import IconWrap from "@/components/IconWrap";
import { Pages, SideBarWidth } from "@/constants/index";
@@ -37,6 +38,14 @@ export default function SideBar() {
),
},
+ {
+ pageId: Pages.trigger,
+ component: (
+
+
+
+ ),
+ },
{
pageId: Pages.database,
component: (
diff --git a/web/src/pages/app/storages/index.tsx b/web/src/pages/app/storages/index.tsx
index d178e2783b..f2fce98d0c 100644
--- a/web/src/pages/app/storages/index.tsx
+++ b/web/src/pages/app/storages/index.tsx
@@ -1,11 +1,10 @@
/****************************
* cloud functions storage page
***************************/
-
-import { AddIcon } from "@chakra-ui/icons";
-import { Button } from "@chakra-ui/react";
+import { Center } from "@chakra-ui/react";
import { Col, Row } from "@/components/Grid";
+import Panel from "@/components/Panel";
import CreateBucketModal from "./mods/CreateBucketModal";
import FileList from "./mods/FileList";
@@ -22,13 +21,14 @@ export default function StoragePage() {
{currentStorage === undefined ? (
-
-
- }>
- 创建 Bucket
-
-
-
+
+
+ 暂无Bucket数据
+
+ 立即创建
+
+
+
) : (
)}
diff --git a/web/src/pages/app/storages/mods/CreateBucketModal/index.tsx b/web/src/pages/app/storages/mods/CreateBucketModal/index.tsx
index 0b8b8d3353..fd40da034d 100644
--- a/web/src/pages/app/storages/mods/CreateBucketModal/index.tsx
+++ b/web/src/pages/app/storages/mods/CreateBucketModal/index.tsx
@@ -48,7 +48,7 @@ function CreateBucketModal(props: { storage?: TBucket; children: React.ReactElem
const isEdit = !!storage;
const onSubmit = async (values: any) => {
- debugger;
+ // debugger;
let res: any = {};
if (isEdit) {
res = await bucketUpdateMutation.mutateAsync(values);
@@ -59,7 +59,10 @@ function CreateBucketModal(props: { storage?: TBucket; children: React.ReactElem
onClose();
}
} else {
- res = await bucketCreateMutation.mutateAsync(values);
+ res = await bucketCreateMutation.mutateAsync({
+ shortName: values.name,
+ policy: values.policy,
+ });
if (!res.error) {
store.setCurrentStorage(res.data);
showSuccess("create success.");
diff --git a/web/src/pages/app/trigger/AddTriggerModal/index.tsx b/web/src/pages/app/trigger/AddTriggerModal/index.tsx
new file mode 100644
index 0000000000..6b1108a187
--- /dev/null
+++ b/web/src/pages/app/trigger/AddTriggerModal/index.tsx
@@ -0,0 +1,143 @@
+import React from "react";
+import { useForm } from "react-hook-form";
+import {
+ Button,
+ FormControl,
+ FormErrorMessage,
+ FormLabel,
+ Input,
+ Modal,
+ ModalBody,
+ ModalCloseButton,
+ ModalContent,
+ ModalFooter,
+ ModalHeader,
+ ModalOverlay,
+ Select,
+ useDisclosure,
+ VStack,
+} from "@chakra-ui/react";
+
+import { useCreateTriggerMutation } from "../service";
+import {} from "../service";
+
+import { useFunctionListQuery } from "@/pages/app/functions/service";
+
+const AddTriggerModal = (props: { children: React.ReactElement; targetFunc?: string }) => {
+ type FormData = {
+ desc: string;
+ target: string;
+ cron: string;
+ };
+ const {
+ register,
+ handleSubmit,
+ setFocus,
+ reset,
+ formState: { errors },
+ } = useForm();
+
+ const { targetFunc, children } = props;
+ const { isOpen, onOpen, onClose } = useDisclosure();
+ const functionListQuery = useFunctionListQuery({ onSuccess: (data: any) => {} });
+ const addTriggerMutation = useCreateTriggerMutation(() => {
+ onClose();
+ });
+ const onSubmit = (data: any) => {
+ addTriggerMutation.mutate(data);
+ onClose();
+ };
+ const initFormData = () => {
+ reset({
+ desc: "",
+ target: targetFunc ? targetFunc : functionListQuery?.data?.data[0]?.name,
+ cron: "",
+ });
+ };
+
+ return (
+ <>
+ {React.cloneElement(children, {
+ onClick: () => {
+ onOpen();
+ initFormData();
+ setTimeout(() => setFocus("desc"), 0);
+ },
+ })}
+
+
+
+
+ 添加触发器
+
+
+
+
+ 触发器名称
+
+ {errors.desc && errors.desc.message}
+
+
+ 关联函数
+
+
+
+ 类型
+
+
+
+ Cron表达式
+
+ {errors.cron && errors.cron.message}
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
+
+AddTriggerModal.displayName = "AddTriggerModal";
+
+export default AddTriggerModal;
diff --git a/web/src/pages/app/trigger/index.tsx b/web/src/pages/app/trigger/index.tsx
new file mode 100644
index 0000000000..a9b5353ddf
--- /dev/null
+++ b/web/src/pages/app/trigger/index.tsx
@@ -0,0 +1,123 @@
+import { useState } from "react";
+import { AddIcon, DeleteIcon, Search2Icon } from "@chakra-ui/icons";
+import {
+ Button,
+ Center,
+ Input,
+ InputGroup,
+ InputLeftElement,
+ Spinner,
+ Table,
+ TableContainer,
+ Tbody,
+ Td,
+ Th,
+ Thead,
+ Tr,
+} from "@chakra-ui/react";
+import { t } from "i18next";
+
+import ConfirmButton from "@/components/ConfirmButton";
+import Content from "@/components/Content";
+import IconWrap from "@/components/IconWrap";
+import Panel from "@/components/Panel";
+import { formatDate } from "@/utils/format";
+
+import AddTriggerModal from "./AddTriggerModal";
+import { useDeleteTriggerMutation, useTriggerListQuery } from "./service";
+
+export default function TriggerPage() {
+ const [searchKey, setSearchKey] = useState("");
+ const triggerListQuery = useTriggerListQuery(() => {});
+ const deleteTriggerMutation = useDeleteTriggerMutation(() => {
+ triggerListQuery.refetch();
+ });
+
+ return (
+
+
+
+
+
+ }>
+ 新建触发器
+
+
+
+ }
+ />
+ setSearchKey(e.target.value)}
+ />
+
+
+
+
+ {triggerListQuery.isFetching ? (
+
+
+
+ ) : null}
+
+
+
+
+
+ 触发器名称 |
+ 相关函数 |
+ 类型 |
+ 创建/更新时间 |
+ 操作 |
+
+
+
+ {(triggerListQuery.data?.data || [])
+ .filter((item: any) => {
+ return item.desc.indexOf(searchKey) > -1;
+ })
+ .map((item: any) => {
+ return (
+
+
+ {item.desc}
+ |
+
+ {item.target}
+ |
+
+ 定时任务
+ |
+
+ {formatDate(item.updatedAt, "YYYY-MM-DD HH:mm:ss")}
+ |
+
+ deleteTriggerMutation.mutate({ id: item.id })}
+ headerText={String(t("Delete"))}
+ bodyText={`确定删除该触发器吗?`}
+ >
+
+
+
+
+ |
+
+ );
+ })}
+
+
+
+
+
+
+
+ );
+}
diff --git a/web/src/pages/app/trigger/service.ts b/web/src/pages/app/trigger/service.ts
new file mode 100644
index 0000000000..d27790b133
--- /dev/null
+++ b/web/src/pages/app/trigger/service.ts
@@ -0,0 +1,65 @@
+import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
+
+import {
+ TriggerControllerCreate,
+ TriggerControllerFindAll,
+ TriggerControllerRemove,
+} from "@/apis/v1/apps";
+import useGlobalStore from "@/pages/globalStore";
+
+const queryKeys = {
+ useTriggerQuery: ["useTriggerQuery"],
+};
+
+export const useTriggerListQuery = (onSuccess: (data: any) => void) => {
+ return useQuery(
+ queryKeys.useTriggerQuery,
+ () => {
+ return TriggerControllerFindAll({});
+ },
+ {
+ onSuccess: onSuccess,
+ },
+ );
+};
+
+export const useCreateTriggerMutation = (onSuccess: (data: any) => void) => {
+ const globalStore = useGlobalStore();
+ const queryClient = useQueryClient();
+ return useMutation(
+ (values: any) => {
+ return TriggerControllerCreate(values);
+ },
+ {
+ onSuccess: async (data) => {
+ if (data.error) {
+ globalStore.showError(data.error);
+ } else {
+ await queryClient.invalidateQueries(queryKeys.useTriggerQuery);
+ onSuccess && onSuccess(data);
+ }
+ },
+ },
+ );
+};
+
+export const useDeleteTriggerMutation = (onSuccess: (data: any) => void) => {
+ const globalStore = useGlobalStore();
+ const queryClient = useQueryClient();
+ return useMutation(
+ (values: any) => {
+ return TriggerControllerRemove(values);
+ },
+ {
+ onSuccess(data) {
+ if (data.error) {
+ globalStore.showError(data.error);
+ } else {
+ queryClient.invalidateQueries(queryKeys.useTriggerQuery);
+ globalStore.showSuccess("delete success");
+ onSuccess && onSuccess(data);
+ }
+ },
+ },
+ );
+};
diff --git a/web/src/utils/request.ts b/web/src/utils/request.ts
index 0f7004b3b4..453e7344e3 100644
--- a/web/src/utils/request.ts
+++ b/web/src/utils/request.ts
@@ -50,7 +50,7 @@ request.interceptors.response.use(
const { data } = error.response;
if (data.statusCode === 401) {
// eslint-disable-next-line no-restricted-globals
- // (window as any).location.href = (import.meta.env.VITE_SERVER_URL + "/v1/login") as string;
+ (window as any).location.href = (import.meta.env.VITE_SERVER_URL + "/v1/login") as string;
return;
}
toast({