mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-08 05:29:51 +00:00
refactor(ui): refactor accesses state using zustand store
This commit is contained in:
parent
b744363736
commit
bb3009a124
@ -1,3 +1,4 @@
|
||||
import { Statistics } from "@/domain/statistics";
|
||||
import { getPocketBase } from "@/repository/pocketbase";
|
||||
|
||||
export const get = async () => {
|
||||
@ -7,9 +8,9 @@ export const get = async () => {
|
||||
method: "GET",
|
||||
});
|
||||
|
||||
if (resp.code != 0) {
|
||||
if (resp.code !== 0) {
|
||||
throw new Error(resp.msg);
|
||||
}
|
||||
|
||||
return resp.data;
|
||||
return resp.data as Statistics;
|
||||
};
|
||||
|
@ -3,11 +3,11 @@ import { Button, Dropdown, Form, Input, message, Space, Tooltip } from "antd";
|
||||
import { CopyToClipboard } from "react-copy-to-clipboard";
|
||||
import { ChevronDown as ChevronDownIcon, Clipboard as ClipboardIcon, ThumbsUp as ThumbsUpIcon } from "lucide-react";
|
||||
|
||||
import { type Certificate } from "@/domain/certificate";
|
||||
import { type CertificateModel } from "@/domain/certificate";
|
||||
import { saveFiles2Zip } from "@/utils/file";
|
||||
|
||||
type CertificateDetailProps = {
|
||||
data: Certificate;
|
||||
data: CertificateModel;
|
||||
};
|
||||
|
||||
const CertificateDetail = ({ data }: CertificateDetailProps) => {
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { Drawer } from "antd";
|
||||
|
||||
import { type Certificate } from "@/domain/certificate";
|
||||
import { type CertificateModel } from "@/domain/certificate";
|
||||
import CertificateDetail from "./CertificateDetail";
|
||||
|
||||
type CertificateDetailDrawerProps = {
|
||||
data?: Certificate;
|
||||
data?: CertificateModel;
|
||||
open?: boolean;
|
||||
onClose?: () => void;
|
||||
};
|
||||
|
@ -8,19 +8,21 @@ import { Button } from "@/components/ui/button";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access, type AliyunConfig } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type AliyunConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessAliyunFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessAliyunForm = ({ data, op, onAfterReq }: AccessAliyunFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
|
||||
const formSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
name: z
|
||||
@ -56,7 +58,7 @@ const AccessAliyunForm = ({ data, op, onAfterReq }: AccessAliyunFormProps) => {
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -81,7 +83,7 @@ const AccessAliyunForm = ({ data, op, onAfterReq }: AccessAliyunFormProps) => {
|
||||
return;
|
||||
}
|
||||
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
|
@ -8,19 +8,21 @@ import { Input } from "@/components/ui/input";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { Access, accessProvidersMap, accessTypeFormSchema, type AwsConfig } from "@/domain/access";
|
||||
import { AccessModel, accessProvidersMap, accessTypeFormSchema, type AwsConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessAwsFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessAwsForm = ({ data, op, onAfterReq }: AccessAwsFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
|
||||
const formSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
name: z
|
||||
@ -68,7 +70,7 @@ const AccessAwsForm = ({ data, op, onAfterReq }: AccessAwsFormProps) => {
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -94,7 +96,8 @@ const AccessAwsForm = ({ data, op, onAfterReq }: AccessAwsFormProps) => {
|
||||
updateAccess(req);
|
||||
return;
|
||||
}
|
||||
addAccess(req);
|
||||
|
||||
createAccess(req);
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
|
@ -8,19 +8,21 @@ import { Input } from "@/components/ui/input";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access, type BaiduCloudConfig } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type BaiduCloudConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessBaiduCloudFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessBaiduCloudForm = ({ data, op, onAfterReq }: AccessBaiduCloudFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
|
||||
const formSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
name: z
|
||||
@ -56,7 +58,7 @@ const AccessBaiduCloudForm = ({ data, op, onAfterReq }: AccessBaiduCloudFormProp
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -80,7 +82,8 @@ const AccessBaiduCloudForm = ({ data, op, onAfterReq }: AccessBaiduCloudFormProp
|
||||
updateAccess(req);
|
||||
return;
|
||||
}
|
||||
addAccess(req);
|
||||
|
||||
createAccess(req);
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
|
@ -8,18 +8,18 @@ import { Input } from "@/components/ui/input";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access, type ByteplusConfig } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type ByteplusConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessByteplusFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessByteplusForm = ({ data, op, onAfterReq }: AccessByteplusFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
const { t } = useTranslation();
|
||||
const formSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
@ -56,7 +56,7 @@ const AccessByteplusForm = ({ data, op, onAfterReq }: AccessByteplusFormProps) =
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -80,7 +80,7 @@ const AccessByteplusForm = ({ data, op, onAfterReq }: AccessByteplusFormProps) =
|
||||
updateAccess(req);
|
||||
return;
|
||||
}
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
|
@ -8,18 +8,18 @@ import { Button } from "@/components/ui/button";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access, type CloudflareConfig } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type CloudflareConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessCloudflareFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessCloudflareForm = ({ data, op, onAfterReq }: AccessCloudflareFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
const { t } = useTranslation();
|
||||
const formSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
@ -50,7 +50,7 @@ const AccessCloudflareForm = ({ data, op, onAfterReq }: AccessCloudflareFormProp
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -73,7 +73,7 @@ const AccessCloudflareForm = ({ data, op, onAfterReq }: AccessCloudflareFormProp
|
||||
updateAccess(req);
|
||||
return;
|
||||
}
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
|
@ -8,18 +8,18 @@ import { Button } from "@/components/ui/button";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access, type DogeCloudConfig } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type DogeCloudConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessDogeCloudFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessDogeCloudForm = ({ data, op, onAfterReq }: AccessDogeCloudFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
const { t } = useTranslation();
|
||||
const formSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
@ -50,7 +50,7 @@ const AccessDogeCloudForm = ({ data, op, onAfterReq }: AccessDogeCloudFormProps)
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -74,7 +74,7 @@ const AccessDogeCloudForm = ({ data, op, onAfterReq }: AccessDogeCloudFormProps)
|
||||
updateAccess(req);
|
||||
return;
|
||||
}
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
|
@ -23,14 +23,14 @@ import AccessWebhookForm from "./AccessWebhookForm";
|
||||
import AccessKubernetesForm from "./AccessKubernetesForm";
|
||||
import AccessVolcengineForm from "./AccessVolcengineForm";
|
||||
import AccessByteplusForm from "./AccessByteplusForm";
|
||||
import { Access } from "@/domain/access";
|
||||
import { AccessModel } from "@/domain/access";
|
||||
import { AccessTypeSelect } from "./AccessTypeSelect";
|
||||
|
||||
type AccessEditProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
className?: string;
|
||||
trigger: React.ReactNode;
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
outConfigType?: string;
|
||||
};
|
||||
|
||||
|
@ -8,18 +8,18 @@ import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access, type GodaddyConfig } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type GodaddyConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessGodaddyFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessGodaddyForm = ({ data, op, onAfterReq }: AccessGodaddyFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
const { t } = useTranslation();
|
||||
const formSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
@ -56,7 +56,7 @@ const AccessGodaddyForm = ({ data, op, onAfterReq }: AccessGodaddyFormProps) =>
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -80,7 +80,7 @@ const AccessGodaddyForm = ({ data, op, onAfterReq }: AccessGodaddyFormProps) =>
|
||||
updateAccess(req);
|
||||
return;
|
||||
}
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
|
@ -8,18 +8,18 @@ import { Button } from "@/components/ui/button";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access, type HttpreqConfig } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type HttpreqConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessHttpreqFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessHttpreqForm = ({ data, op, onAfterReq }: AccessHttpreqFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
const { t } = useTranslation();
|
||||
const formSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
@ -62,7 +62,7 @@ const AccessHttpreqForm = ({ data, op, onAfterReq }: AccessHttpreqFormProps) =>
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -89,7 +89,7 @@ const AccessHttpreqForm = ({ data, op, onAfterReq }: AccessHttpreqFormProps) =>
|
||||
return;
|
||||
}
|
||||
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
|
@ -8,18 +8,18 @@ import { Input } from "@/components/ui/input";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access, type HuaweiCloudConfig } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type HuaweiCloudConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessHuaweiCloudFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessHuaweiCloudForm = ({ data, op, onAfterReq }: AccessHuaweiCloudFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
const { t } = useTranslation();
|
||||
const formSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
@ -62,7 +62,7 @@ const AccessHuaweiCloudForm = ({ data, op, onAfterReq }: AccessHuaweiCloudFormPr
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -87,7 +87,7 @@ const AccessHuaweiCloudForm = ({ data, op, onAfterReq }: AccessHuaweiCloudFormPr
|
||||
updateAccess(req);
|
||||
return;
|
||||
}
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
|
@ -10,18 +10,18 @@ import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { readFileContent } from "@/utils/file";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access, type KubernetesConfig } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type KubernetesConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessKubernetesFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessKubernetesForm = ({ data, op, onAfterReq }: AccessKubernetesFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
|
||||
const fileInputRef = useRef<HTMLInputElement | null>(null);
|
||||
const [fileName, setFileName] = useState("");
|
||||
@ -60,7 +60,7 @@ const AccessKubernetesForm = ({ data, op, onAfterReq }: AccessKubernetesFormProp
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -82,7 +82,7 @@ const AccessKubernetesForm = ({ data, op, onAfterReq }: AccessKubernetesFormProp
|
||||
if (data.id && op == "edit") {
|
||||
updateAccess(req);
|
||||
} else {
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
}
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
@ -8,18 +8,18 @@ import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessLocalFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessLocalForm = ({ data, op, onAfterReq }: AccessLocalFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const formSchema = z.object({
|
||||
@ -41,7 +41,7 @@ const AccessLocalForm = ({ data, op, onAfterReq }: AccessLocalFormProps) => {
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -62,7 +62,7 @@ const AccessLocalForm = ({ data, op, onAfterReq }: AccessLocalFormProps) => {
|
||||
if (data.id && op == "edit") {
|
||||
updateAccess(req);
|
||||
} else {
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
}
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
@ -8,18 +8,18 @@ import { Button } from "@/components/ui/button";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access, type NamesiloConfig } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type NamesiloConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessNamesiloFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessNamesiloForm = ({ data, op, onAfterReq }: AccessNamesiloFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
const { t } = useTranslation();
|
||||
const formSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
@ -50,7 +50,7 @@ const AccessNamesiloForm = ({ data, op, onAfterReq }: AccessNamesiloFormProps) =
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -73,7 +73,7 @@ const AccessNamesiloForm = ({ data, op, onAfterReq }: AccessNamesiloFormProps) =
|
||||
updateAccess(req);
|
||||
return;
|
||||
}
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
|
@ -8,18 +8,18 @@ import { Button } from "@/components/ui/button";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access, type PdnsConfig } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type PdnsConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessPdnsFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessPdnsForm = ({ data, op, onAfterReq }: AccessPdnsFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
const { t } = useTranslation();
|
||||
const formSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
@ -53,7 +53,7 @@ const AccessPdnsForm = ({ data, op, onAfterReq }: AccessPdnsFormProps) => {
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -78,7 +78,7 @@ const AccessPdnsForm = ({ data, op, onAfterReq }: AccessPdnsFormProps) => {
|
||||
return;
|
||||
}
|
||||
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
|
@ -8,18 +8,18 @@ import { Button } from "@/components/ui/button";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access, type QiniuConfig } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type QiniuConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessQiniuFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessQiniuForm = ({ data, op, onAfterReq }: AccessQiniuFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
const { t } = useTranslation();
|
||||
const formSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
@ -50,7 +50,7 @@ const AccessQiniuForm = ({ data, op, onAfterReq }: AccessQiniuFormProps) => {
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -74,7 +74,7 @@ const AccessQiniuForm = ({ data, op, onAfterReq }: AccessQiniuFormProps) => {
|
||||
updateAccess(req);
|
||||
return;
|
||||
}
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
|
@ -10,18 +10,18 @@ import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { readFileContent } from "@/utils/file";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access, type SSHConfig } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type SSHConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessSSHFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessSSHForm = ({ data, op, onAfterReq }: AccessSSHFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
|
||||
const fileInputRef = useRef<HTMLInputElement | null>(null);
|
||||
|
||||
@ -103,7 +103,7 @@ const AccessSSHForm = ({ data, op, onAfterReq }: AccessSSHFormProps) => {
|
||||
let group = data.group;
|
||||
if (group == "emptyId") group = "";
|
||||
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -131,7 +131,7 @@ const AccessSSHForm = ({ data, op, onAfterReq }: AccessSSHFormProps) => {
|
||||
if (data.id && op == "edit") {
|
||||
updateAccess(req);
|
||||
} else {
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
}
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
@ -8,18 +8,18 @@ import { Button } from "@/components/ui/button";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access, type TencentConfig } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type TencentConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessTencentFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessTencentForm = ({ data, op, onAfterReq }: AccessTencentFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
const { t } = useTranslation();
|
||||
const formSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
@ -56,7 +56,7 @@ const AccessTencentForm = ({ data, op, onAfterReq }: AccessTencentFormProps) =>
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -80,7 +80,7 @@ const AccessTencentForm = ({ data, op, onAfterReq }: AccessTencentFormProps) =>
|
||||
updateAccess(req);
|
||||
return;
|
||||
}
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
|
@ -8,18 +8,18 @@ import { Input } from "@/components/ui/input";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type Access, type VolcengineConfig } from "@/domain/access";
|
||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type VolcengineConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessVolcengineFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessVolcengineForm = ({ data, op, onAfterReq }: AccessVolcengineFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
const { t } = useTranslation();
|
||||
const formSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
@ -56,7 +56,7 @@ const AccessVolcengineForm = ({ data, op, onAfterReq }: AccessVolcengineFormProp
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -80,7 +80,7 @@ const AccessVolcengineForm = ({ data, op, onAfterReq }: AccessVolcengineFormProp
|
||||
updateAccess(req);
|
||||
return;
|
||||
}
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
|
@ -8,18 +8,18 @@ import { Button } from "@/components/ui/button";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { Access, accessProvidersMap, accessTypeFormSchema, WebhookConfig } from "@/domain/access";
|
||||
import { AccessModel, accessProvidersMap, accessTypeFormSchema, WebhookConfig } from "@/domain/access";
|
||||
import { save } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
type AccessWebhookFormProps = {
|
||||
op: "add" | "edit" | "copy";
|
||||
data?: Access;
|
||||
data?: AccessModel;
|
||||
onAfterReq: () => void;
|
||||
};
|
||||
|
||||
const AccessWebhookForm = ({ data, op, onAfterReq }: AccessWebhookFormProps) => {
|
||||
const { addAccess, updateAccess } = useConfigContext();
|
||||
const { createAccess, updateAccess } = useAccessStore();
|
||||
const { t } = useTranslation();
|
||||
const formSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
@ -47,7 +47,7 @@ const AccessWebhookForm = ({ data, op, onAfterReq }: AccessWebhookFormProps) =>
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
const req: Access = {
|
||||
const req: AccessModel = {
|
||||
id: data.id as string,
|
||||
name: data.name,
|
||||
configType: data.configType,
|
||||
@ -70,7 +70,7 @@ const AccessWebhookForm = ({ data, op, onAfterReq }: AccessWebhookFormProps) =>
|
||||
updateAccess(req);
|
||||
return;
|
||||
}
|
||||
addAccess(req);
|
||||
createAccess(req);
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
|
@ -2,7 +2,7 @@ import React, { useEffect } from "react";
|
||||
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "../ui/select";
|
||||
import { accessProvidersMap } from "@/domain/access";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
import { deployTargetsMap } from "@/domain/domain";
|
||||
|
||||
type AccessSelectProps = {
|
||||
@ -13,9 +13,7 @@ type AccessSelectProps = {
|
||||
const AccessSelect = ({ value, onValueChange, providerType }: AccessSelectProps) => {
|
||||
const [localValue, setLocalValue] = React.useState<string>("");
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
config: { accesses },
|
||||
} = useConfigContext();
|
||||
const { accesses } = useAccessStore();
|
||||
|
||||
useEffect(() => {
|
||||
setLocalValue(value);
|
||||
|
@ -15,8 +15,8 @@ import EmailsEdit from "@/components/certimate/EmailsEdit";
|
||||
import StringList from "@/components/certimate/StringList";
|
||||
|
||||
import { accessProvidersMap } from "@/domain/access";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
import { useContactStore } from "@/stores/contact";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { TooltipFast } from "@/components/ui/tooltip";
|
||||
import { WorkflowNode, WorkflowNodeConfig } from "@/domain/workflow";
|
||||
@ -33,9 +33,7 @@ const selectState = (state: WorkflowState) => ({
|
||||
const ApplyForm = ({ data }: ApplyFormProps) => {
|
||||
const { updateNode } = useWorkflowStore(useShallow(selectState));
|
||||
|
||||
const {
|
||||
config: { accesses },
|
||||
} = useConfigContext();
|
||||
const { accesses } = useAccessStore();
|
||||
const { emails, fetchEmails } = useContactStore();
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -1,15 +1,13 @@
|
||||
import { ConfigProvider } from "@/providers/config";
|
||||
import React from "react";
|
||||
import { PanelProvider } from "./PanelProvider";
|
||||
|
||||
import { NotifyProvider } from "@/providers/notify";
|
||||
import { PanelProvider } from "./PanelProvider";
|
||||
|
||||
const WorkflowProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<ConfigProvider>
|
||||
<NotifyProvider>
|
||||
<PanelProvider>{children}</PanelProvider>
|
||||
</NotifyProvider>
|
||||
</ConfigProvider>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { z } from "zod";
|
||||
import { type BaseModel } from "pocketbase";
|
||||
|
||||
type AccessUsages = "apply" | "deploy" | "all";
|
||||
|
||||
@ -59,8 +60,7 @@ export const accessTypeFormSchema = z.union(
|
||||
{ message: "access.authorization.form.type.placeholder" }
|
||||
);
|
||||
|
||||
export type Access = {
|
||||
id: string;
|
||||
export interface AccessModel extends BaseModel {
|
||||
name: string;
|
||||
configType: string;
|
||||
usage: AccessUsages;
|
||||
@ -83,10 +83,7 @@ export type Access = {
|
||||
| KubernetesConfig
|
||||
| VolcengineConfig
|
||||
| ByteplusConfig;
|
||||
deleted?: string;
|
||||
created?: string;
|
||||
updated?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type AliyunConfig = {
|
||||
accessKeyId: string;
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Workflow } from "./workflow";
|
||||
import { type BaseModel } from "pocketbase";
|
||||
|
||||
export type Certificate = {
|
||||
id: string;
|
||||
import { WorkflowModel } from "./workflow";
|
||||
|
||||
export interface CertificateModel extends BaseModel {
|
||||
san: string;
|
||||
certificate: string;
|
||||
privateKey: string;
|
||||
@ -12,10 +13,7 @@ export type Certificate = {
|
||||
expireAt: string;
|
||||
workflow: string;
|
||||
nodeId: string;
|
||||
created: string;
|
||||
updated: string;
|
||||
|
||||
expand: {
|
||||
workflow?: Workflow;
|
||||
};
|
||||
workflow?: WorkflowModel;
|
||||
};
|
||||
}
|
||||
|
@ -56,16 +56,6 @@ export type ApplyConfig = {
|
||||
disableFollowCNAME?: boolean;
|
||||
};
|
||||
|
||||
export type Statistic = {
|
||||
certificateTotal: number;
|
||||
certificateExpired: number;
|
||||
certificateExpireSoon: number;
|
||||
|
||||
workflowTotal: number;
|
||||
workflowEnabled: number;
|
||||
workflowDisabled: number;
|
||||
};
|
||||
|
||||
export type DeployTarget = {
|
||||
type: string;
|
||||
provider: string;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { type BaseModel } from "pocketbase";
|
||||
|
||||
export interface Settings<T> extends BaseModel {
|
||||
export interface SettingsModel<T> extends BaseModel {
|
||||
name: string;
|
||||
content: T;
|
||||
}
|
||||
|
8
ui/src/domain/statistics.ts
Normal file
8
ui/src/domain/statistics.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export type Statistics = {
|
||||
certificateTotal: number;
|
||||
certificateExpired: number;
|
||||
certificateExpireSoon: number;
|
||||
workflowTotal: number;
|
||||
workflowEnabled: number;
|
||||
workflowDisabled: number;
|
||||
};
|
@ -1,5 +1,6 @@
|
||||
import { produce } from "immer";
|
||||
import { nanoid } from "nanoid";
|
||||
import { type BaseModel } from "pocketbase";
|
||||
|
||||
import i18n from "@/i18n";
|
||||
import { deployTargets, KVType } from "./domain";
|
||||
@ -27,8 +28,7 @@ export type WorkflowOutput = {
|
||||
error: string;
|
||||
};
|
||||
|
||||
export type Workflow = {
|
||||
id: string;
|
||||
export interface WorkflowModel extends BaseModel {
|
||||
name: string;
|
||||
description?: string;
|
||||
type: string;
|
||||
@ -37,9 +37,7 @@ export type Workflow = {
|
||||
draft?: WorkflowNode;
|
||||
enabled?: boolean;
|
||||
hasDraft?: boolean;
|
||||
created?: string;
|
||||
updated?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export enum WorkflowNodeType {
|
||||
Start = "start",
|
||||
@ -131,7 +129,7 @@ type NewWorkflowNodeOptions = {
|
||||
providerType?: string;
|
||||
};
|
||||
|
||||
export const initWorkflow = (): Workflow => {
|
||||
export const initWorkflow = (): WorkflowModel => {
|
||||
// 开始节点
|
||||
const rs = newWorkflowNode(WorkflowNodeType.Start, {});
|
||||
let root = rs;
|
||||
|
@ -18,7 +18,6 @@ import {
|
||||
import Version from "@/components/certimate/Version";
|
||||
import { useTheme } from "@/hooks";
|
||||
import { getPocketBase } from "@/repository/pocketbase";
|
||||
import { ConfigProvider } from "@/providers/config";
|
||||
|
||||
const ConsoleLayout = () => {
|
||||
const navigate = useNavigate();
|
||||
@ -52,8 +51,6 @@ const ConsoleLayout = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<ConfigProvider>
|
||||
<Layout className="w-full min-h-screen">
|
||||
<Layout.Sider className="max-md:hidden" theme="light" width={256}>
|
||||
<div className="flex flex-col items-center justify-between w-full h-full overflow-hidden">
|
||||
@ -109,8 +106,6 @@ const ConsoleLayout = () => {
|
||||
</Layout.Content>
|
||||
</Layout>
|
||||
</Layout>
|
||||
</ConfigProvider>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -7,9 +7,8 @@ import dayjs from "dayjs";
|
||||
import { ClientResponseError } from "pocketbase";
|
||||
|
||||
import AccessEditDialog from "@/components/certimate/AccessEditDialog";
|
||||
import { accessProvidersMap, type Access as AccessType } from "@/domain/access";
|
||||
import { remove as removeAccess } from "@/repository/access";
|
||||
import { useConfigContext } from "@/providers/config";
|
||||
import { accessProvidersMap, type AccessModel } from "@/domain/access";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
|
||||
const AccessList = () => {
|
||||
const { t } = useTranslation();
|
||||
@ -17,9 +16,11 @@ const AccessList = () => {
|
||||
const [modalApi, ModelContextHolder] = Modal.useModal();
|
||||
const [notificationApi, NotificationContextHolder] = notification.useNotification();
|
||||
|
||||
const { accesses, fetchAccesses, deleteAccess } = useAccessStore();
|
||||
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
|
||||
const tableColumns: TableProps<AccessType>["columns"] = [
|
||||
const tableColumns: TableProps<AccessModel>["columns"] = [
|
||||
{
|
||||
key: "$index",
|
||||
align: "center",
|
||||
@ -105,13 +106,15 @@ const AccessList = () => {
|
||||
),
|
||||
},
|
||||
];
|
||||
const [tableData, setTableData] = useState<AccessType[]>([]);
|
||||
const [tableData, setTableData] = useState<AccessModel[]>([]);
|
||||
const [tableTotal, setTableTotal] = useState<number>(0);
|
||||
|
||||
const [page, setPage] = useState<number>(1);
|
||||
const [pageSize, setPageSize] = useState<number>(10);
|
||||
|
||||
const configContext = useConfigContext();
|
||||
useEffect(() => {
|
||||
fetchAccesses();
|
||||
}, []);
|
||||
|
||||
const fetchTableData = useCallback(async () => {
|
||||
if (loading) return;
|
||||
@ -120,10 +123,10 @@ const AccessList = () => {
|
||||
try {
|
||||
const startIndex = (page - 1) * pageSize;
|
||||
const endIndex = startIndex + pageSize;
|
||||
const items = configContext.config?.accesses?.slice(startIndex, endIndex) ?? [];
|
||||
const items = accesses.slice(startIndex, endIndex);
|
||||
|
||||
setTableData(items);
|
||||
setTableTotal(configContext.config?.accesses?.length ?? 0);
|
||||
setTableTotal(accesses.length);
|
||||
} catch (err) {
|
||||
if (err instanceof ClientResponseError && err.isAbort) {
|
||||
return;
|
||||
@ -134,21 +137,20 @@ const AccessList = () => {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [page, pageSize, configContext.config.accesses]);
|
||||
}, [page, pageSize, accesses]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchTableData();
|
||||
}, [fetchTableData]);
|
||||
|
||||
const handleDeleteClick = async (data: AccessType) => {
|
||||
const handleDeleteClick = async (data: AccessModel) => {
|
||||
modalApi.confirm({
|
||||
title: t("access.action.delete"),
|
||||
content: t("access.action.delete.confirm"),
|
||||
onOk: async () => {
|
||||
// TODO: 有关联数据的不允许被删除
|
||||
try {
|
||||
const res = await removeAccess(data);
|
||||
configContext.deleteAccess(res.id);
|
||||
await deleteAccess(data);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
notificationApi.error({ message: t("common.text.request_error"), description: <>{String(err)}</> });
|
||||
@ -177,7 +179,7 @@ const AccessList = () => {
|
||||
]}
|
||||
/>
|
||||
|
||||
<Table<AccessType>
|
||||
<Table<AccessModel>
|
||||
columns={tableColumns}
|
||||
dataSource={tableData}
|
||||
loading={loading}
|
||||
|
@ -8,7 +8,7 @@ import dayjs from "dayjs";
|
||||
import { ClientResponseError } from "pocketbase";
|
||||
|
||||
import CertificateDetailDrawer from "@/components/certificate/CertificateDetailDrawer";
|
||||
import { Certificate as CertificateType } from "@/domain/certificate";
|
||||
import { CertificateModel } from "@/domain/certificate";
|
||||
import { list as listCertificate, type CertificateListReq } from "@/repository/certificate";
|
||||
|
||||
const CertificateList = () => {
|
||||
@ -23,7 +23,7 @@ const CertificateList = () => {
|
||||
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
|
||||
const tableColumns: TableProps<CertificateType>["columns"] = [
|
||||
const tableColumns: TableProps<CertificateModel>["columns"] = [
|
||||
{
|
||||
key: "$index",
|
||||
align: "center",
|
||||
@ -165,7 +165,7 @@ const CertificateList = () => {
|
||||
),
|
||||
},
|
||||
];
|
||||
const [tableData, setTableData] = useState<CertificateType[]>([]);
|
||||
const [tableData, setTableData] = useState<CertificateModel[]>([]);
|
||||
const [tableTotal, setTableTotal] = useState<number>(0);
|
||||
|
||||
const [filters, setFilters] = useState<Record<string, unknown>>(() => {
|
||||
@ -177,7 +177,7 @@ const CertificateList = () => {
|
||||
const [page, setPage] = useState<number>(() => parseInt(+searchParams.get("page")! + "") || 1);
|
||||
const [pageSize, setPageSize] = useState<number>(() => parseInt(+searchParams.get("perPage")! + "") || 10);
|
||||
|
||||
const [currentRecord, setCurrentRecord] = useState<CertificateType>();
|
||||
const [currentRecord, setCurrentRecord] = useState<CertificateModel>();
|
||||
|
||||
const [drawerOpen, setDrawerOpen] = useState(false);
|
||||
|
||||
@ -210,7 +210,7 @@ const CertificateList = () => {
|
||||
fetchTableData();
|
||||
}, [fetchTableData]);
|
||||
|
||||
const handleViewClick = (certificate: CertificateType) => {
|
||||
const handleViewClick = (certificate: CertificateModel) => {
|
||||
setDrawerOpen(true);
|
||||
setCurrentRecord(certificate);
|
||||
};
|
||||
@ -221,7 +221,7 @@ const CertificateList = () => {
|
||||
|
||||
<PageHeader title={t("certificate.page.title")} />
|
||||
|
||||
<Table<CertificateType>
|
||||
<Table<CertificateModel>
|
||||
columns={tableColumns}
|
||||
dataSource={tableData}
|
||||
loading={loading}
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
} from "lucide-react";
|
||||
import { ClientResponseError } from "pocketbase";
|
||||
|
||||
import { type Statistic as StatisticType } from "@/domain/domain";
|
||||
import { type Statistics } from "@/domain/statistics";
|
||||
import { get as getStatistics } from "@/api/statistics";
|
||||
|
||||
const Dashboard = () => {
|
||||
@ -26,7 +26,7 @@ const Dashboard = () => {
|
||||
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
|
||||
const statisticGridSpans = {
|
||||
const statisticsGridSpans = {
|
||||
xs: { flex: "50%" },
|
||||
md: { flex: "50%" },
|
||||
lg: { flex: "33.3333%" },
|
||||
@ -34,15 +34,15 @@ const Dashboard = () => {
|
||||
xxl: { flex: "20%" },
|
||||
};
|
||||
|
||||
const [statistic, setStatistic] = useState<StatisticType>();
|
||||
const [statistics, setStatistics] = useState<Statistics>();
|
||||
|
||||
const fetchStatistic = useCallback(async () => {
|
||||
const fetchStatistics = useCallback(async () => {
|
||||
if (loading) return;
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
const data = await getStatistics();
|
||||
setStatistic(data);
|
||||
setStatistics(data);
|
||||
} catch (err) {
|
||||
if (err instanceof ClientResponseError && err.isAbort) {
|
||||
return;
|
||||
@ -56,7 +56,7 @@ const Dashboard = () => {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
fetchStatistic();
|
||||
fetchStatistics();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
@ -66,47 +66,47 @@ const Dashboard = () => {
|
||||
<PageHeader title={t("dashboard.page.title")} />
|
||||
|
||||
<Row className="justify-stretch" gutter={[16, 16]}>
|
||||
<Col {...statisticGridSpans}>
|
||||
<Col {...statisticsGridSpans}>
|
||||
<StatisticCard
|
||||
icon={<SquareSigmaIcon size={48} strokeWidth={1} color={themeToken.colorInfo} />}
|
||||
label={t("dashboard.statistics.all_certificates")}
|
||||
value={statistic?.certificateTotal ?? "-"}
|
||||
value={statistics?.certificateTotal ?? "-"}
|
||||
suffix={t("dashboard.statistics.unit")}
|
||||
onClick={() => navigate("/certificates")}
|
||||
/>
|
||||
</Col>
|
||||
<Col {...statisticGridSpans}>
|
||||
<Col {...statisticsGridSpans}>
|
||||
<StatisticCard
|
||||
icon={<CalendarClockIcon size={48} strokeWidth={1} color={themeToken.colorWarning} />}
|
||||
label={t("dashboard.statistics.expire_soon_certificates")}
|
||||
value={statistic?.certificateExpireSoon ?? "-"}
|
||||
value={statistics?.certificateExpireSoon ?? "-"}
|
||||
suffix={t("dashboard.statistics.unit")}
|
||||
onClick={() => navigate("/certificates?state=expireSoon")}
|
||||
/>
|
||||
</Col>
|
||||
<Col {...statisticGridSpans}>
|
||||
<Col {...statisticsGridSpans}>
|
||||
<StatisticCard
|
||||
icon={<CalendarX2Icon size={48} strokeWidth={1} color={themeToken.colorError} />}
|
||||
label={t("dashboard.statistics.expired_certificates")}
|
||||
value={statistic?.certificateExpired ?? "-"}
|
||||
value={statistics?.certificateExpired ?? "-"}
|
||||
suffix={t("dashboard.statistics.unit")}
|
||||
onClick={() => navigate("/certificates?state=expired")}
|
||||
/>
|
||||
</Col>
|
||||
<Col {...statisticGridSpans}>
|
||||
<Col {...statisticsGridSpans}>
|
||||
<StatisticCard
|
||||
icon={<WorkflowIcon size={48} strokeWidth={1} color={themeToken.colorInfo} />}
|
||||
label={t("dashboard.statistics.all_workflows")}
|
||||
value={statistic?.workflowTotal ?? "-"}
|
||||
value={statistics?.workflowTotal ?? "-"}
|
||||
suffix={t("dashboard.statistics.unit")}
|
||||
onClick={() => navigate("/workflows")}
|
||||
/>
|
||||
</Col>
|
||||
<Col {...statisticGridSpans}>
|
||||
<Col {...statisticsGridSpans}>
|
||||
<StatisticCard
|
||||
icon={<FolderCheckIcon size={48} strokeWidth={1} color={themeToken.colorSuccess} />}
|
||||
label={t("dashboard.statistics.enabled_workflows")}
|
||||
value={statistic?.workflowEnabled ?? "-"}
|
||||
value={statistics?.workflowEnabled ?? "-"}
|
||||
suffix={t("dashboard.statistics.unit")}
|
||||
onClick={() => navigate("/workflows?state=enabled")}
|
||||
/>
|
||||
|
@ -12,14 +12,14 @@ import { Label } from "@/components/ui/label";
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||
import { useToast } from "@/components/ui/use-toast";
|
||||
import { getErrMsg } from "@/utils/error";
|
||||
import { SSLProvider as SSLProviderType, SSLProviderSetting, Settings } from "@/domain/settings";
|
||||
import { SSLProvider as SSLProviderType, SSLProviderSetting, SettingsModel } from "@/domain/settings";
|
||||
import { get, save } from "@/repository/settings";
|
||||
import { produce } from "immer";
|
||||
|
||||
type SSLProviderContext = {
|
||||
setting: Settings<SSLProviderSetting>;
|
||||
onSubmit: (data: Settings<SSLProviderSetting>) => void;
|
||||
setConfig: (config: Settings<SSLProviderSetting>) => void;
|
||||
setting: SettingsModel<SSLProviderSetting>;
|
||||
onSubmit: (data: SettingsModel<SSLProviderSetting>) => void;
|
||||
setConfig: (config: SettingsModel<SSLProviderSetting>) => void;
|
||||
};
|
||||
|
||||
const Context = createContext({} as SSLProviderContext);
|
||||
@ -31,12 +31,12 @@ export const useSSLProviderContext = () => {
|
||||
const SSLProvider = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [config, setConfig] = useState<Settings<SSLProviderSetting>>({
|
||||
const [config, setConfig] = useState<SettingsModel<SSLProviderSetting>>({
|
||||
content: {
|
||||
provider: "letsencrypt",
|
||||
config: {},
|
||||
},
|
||||
} as Settings<SSLProviderSetting>);
|
||||
} as SettingsModel<SSLProviderSetting>);
|
||||
|
||||
const { toast } = useToast();
|
||||
|
||||
@ -73,7 +73,7 @@ const SSLProvider = () => {
|
||||
return "";
|
||||
};
|
||||
|
||||
const onSubmit = async (data: Settings<SSLProviderSetting>) => {
|
||||
const onSubmit = async (data: SettingsModel<SSLProviderSetting>) => {
|
||||
try {
|
||||
console.log(data);
|
||||
const resp = await save({ ...data });
|
||||
|
@ -23,7 +23,7 @@ import { Filter as FilterIcon, Pencil as PencilIcon, Plus as PlusIcon, Trash2 as
|
||||
import dayjs from "dayjs";
|
||||
import { ClientResponseError } from "pocketbase";
|
||||
|
||||
import { Workflow as WorkflowType } from "@/domain/workflow";
|
||||
import { WorkflowModel } from "@/domain/workflow";
|
||||
import { list as listWorkflow, remove as removeWorkflow, save as saveWorkflow } from "@/repository/workflow";
|
||||
|
||||
const WorkflowList = () => {
|
||||
@ -39,7 +39,7 @@ const WorkflowList = () => {
|
||||
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
|
||||
const tableColumns: TableProps<WorkflowType>["columns"] = [
|
||||
const tableColumns: TableProps<WorkflowModel>["columns"] = [
|
||||
{
|
||||
key: "$index",
|
||||
align: "center",
|
||||
@ -196,7 +196,7 @@ const WorkflowList = () => {
|
||||
),
|
||||
},
|
||||
];
|
||||
const [tableData, setTableData] = useState<WorkflowType[]>([]);
|
||||
const [tableData, setTableData] = useState<WorkflowModel[]>([]);
|
||||
const [tableTotal, setTableTotal] = useState<number>(0);
|
||||
|
||||
const [filters, setFilters] = useState<Record<string, unknown>>(() => {
|
||||
@ -237,7 +237,7 @@ const WorkflowList = () => {
|
||||
fetchTableData();
|
||||
}, [fetchTableData]);
|
||||
|
||||
const handleEnabledChange = async (workflow: WorkflowType) => {
|
||||
const handleEnabledChange = async (workflow: WorkflowModel) => {
|
||||
try {
|
||||
const resp = await saveWorkflow({
|
||||
id: workflow.id,
|
||||
@ -259,7 +259,7 @@ const WorkflowList = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteClick = (workflow: WorkflowType) => {
|
||||
const handleDeleteClick = (workflow: WorkflowModel) => {
|
||||
modalApi.confirm({
|
||||
title: t("workflow.action.delete"),
|
||||
content: t("workflow.action.delete.confirm"),
|
||||
@ -302,7 +302,7 @@ const WorkflowList = () => {
|
||||
]}
|
||||
/>
|
||||
|
||||
<Table<WorkflowType>
|
||||
<Table<WorkflowModel>
|
||||
columns={tableColumns}
|
||||
dataSource={tableData}
|
||||
loading={loading}
|
||||
|
@ -1,61 +0,0 @@
|
||||
import { createContext, useCallback, useContext, useEffect, useReducer, type ReactNode } from "react";
|
||||
|
||||
import { type Access as AccessType } from "@/domain/access";
|
||||
import { list as listAccess } from "@/repository/access";
|
||||
import { configReducer } from "./reducer";
|
||||
|
||||
export type ConfigData = {
|
||||
accesses: AccessType[];
|
||||
};
|
||||
|
||||
export type ConfigContext = {
|
||||
config: ConfigData;
|
||||
addAccess: (access: AccessType) => void;
|
||||
updateAccess: (access: AccessType) => void;
|
||||
deleteAccess: (id: string) => void;
|
||||
};
|
||||
|
||||
const Context = createContext({} as ConfigContext);
|
||||
|
||||
export const useConfigContext = () => useContext(Context);
|
||||
|
||||
export const ConfigProvider = ({ children }: { children: ReactNode }) => {
|
||||
const [config, dispatchConfig] = useReducer(configReducer, {
|
||||
accesses: [],
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const featchData = async () => {
|
||||
const data = await listAccess();
|
||||
dispatchConfig({ type: "SET_ACCESSES", payload: data });
|
||||
};
|
||||
featchData();
|
||||
}, []);
|
||||
|
||||
const deleteAccess = useCallback((id: string) => {
|
||||
dispatchConfig({ type: "DELETE_ACCESS", payload: id });
|
||||
}, []);
|
||||
|
||||
const addAccess = useCallback((access: AccessType) => {
|
||||
dispatchConfig({ type: "ADD_ACCESS", payload: access });
|
||||
}, []);
|
||||
|
||||
const updateAccess = useCallback((access: AccessType) => {
|
||||
dispatchConfig({ type: "UPDATE_ACCESS", payload: access });
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Context.Provider
|
||||
value={{
|
||||
config: {
|
||||
accesses: config.accesses,
|
||||
},
|
||||
addAccess,
|
||||
updateAccess,
|
||||
deleteAccess,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Context.Provider>
|
||||
);
|
||||
};
|
@ -1,39 +0,0 @@
|
||||
import { Access } from "@/domain/access";
|
||||
import { ConfigData } from "./";
|
||||
|
||||
type Action =
|
||||
| { type: "ADD_ACCESS"; payload: Access }
|
||||
| { type: "DELETE_ACCESS"; payload: string }
|
||||
| { type: "UPDATE_ACCESS"; payload: Access }
|
||||
| { type: "SET_ACCESSES"; payload: Access[] };
|
||||
|
||||
export const configReducer = (state: ConfigData, action: Action): ConfigData => {
|
||||
switch (action.type) {
|
||||
case "SET_ACCESSES": {
|
||||
return {
|
||||
...state,
|
||||
accesses: action.payload,
|
||||
};
|
||||
}
|
||||
case "ADD_ACCESS": {
|
||||
return {
|
||||
...state,
|
||||
accesses: [action.payload, ...state.accesses],
|
||||
};
|
||||
}
|
||||
case "DELETE_ACCESS": {
|
||||
return {
|
||||
...state,
|
||||
accesses: state.accesses.filter((access) => access.id !== action.payload),
|
||||
};
|
||||
}
|
||||
case "UPDATE_ACCESS": {
|
||||
return {
|
||||
...state,
|
||||
accesses: state.accesses.map((access) => (access.id === action.payload.id ? action.payload : access)),
|
||||
};
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
@ -1,13 +1,13 @@
|
||||
import { ReactNode, useContext, createContext, useEffect, useReducer, useCallback } from "react";
|
||||
|
||||
import { NotifyChannel, NotifyChannels, Settings } from "@/domain/settings";
|
||||
import { NotifyChannel, NotifyChannels, SettingsModel } from "@/domain/settings";
|
||||
import { get } from "@/repository/settings";
|
||||
import { notifyReducer } from "./reducer";
|
||||
|
||||
export type NotifyContext = {
|
||||
config: Settings<NotifyChannels>;
|
||||
config: SettingsModel<NotifyChannels>;
|
||||
setChannel: (data: { channel: string; data: NotifyChannel }) => void;
|
||||
setChannels: (data: Settings<NotifyChannels>) => void;
|
||||
setChannels: (data: SettingsModel<NotifyChannels>) => void;
|
||||
initChannels: () => void;
|
||||
};
|
||||
|
||||
@ -45,7 +45,7 @@ export const NotifyProvider = ({ children }: NotifyProviderProps) => {
|
||||
});
|
||||
}, []);
|
||||
|
||||
const setChannels = useCallback((setting: Settings<NotifyChannels>) => {
|
||||
const setChannels = useCallback((setting: SettingsModel<NotifyChannels>) => {
|
||||
dispatchNotify({
|
||||
type: "SET_CHANNELS",
|
||||
payload: setting,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { NotifyChannel, NotifyChannels, Settings } from "@/domain/settings";
|
||||
import { NotifyChannel, NotifyChannels, SettingsModel } from "@/domain/settings";
|
||||
|
||||
type Action =
|
||||
| {
|
||||
@ -10,10 +10,10 @@ type Action =
|
||||
}
|
||||
| {
|
||||
type: "SET_CHANNELS";
|
||||
payload: Settings<NotifyChannels>;
|
||||
payload: SettingsModel<NotifyChannels>;
|
||||
};
|
||||
|
||||
export const notifyReducer = (state: Settings<NotifyChannels>, action: Action) => {
|
||||
export const notifyReducer = (state: SettingsModel<NotifyChannels>, action: Action) => {
|
||||
switch (action.type) {
|
||||
case "SET_CHANNEL": {
|
||||
const channel = action.payload.channel;
|
||||
|
@ -1,24 +1,26 @@
|
||||
import dayjs from "dayjs";
|
||||
|
||||
import { type Access } from "@/domain/access";
|
||||
import { type AccessModel } from "@/domain/access";
|
||||
import { getPocketBase } from "./pocketbase";
|
||||
|
||||
const COLLECTION_NAME = "access";
|
||||
|
||||
export const list = async () => {
|
||||
return await getPocketBase().collection("access").getFullList<Access>({
|
||||
return await getPocketBase().collection(COLLECTION_NAME).getFullList<AccessModel>({
|
||||
sort: "-created",
|
||||
filter: "deleted=null",
|
||||
});
|
||||
};
|
||||
|
||||
export const save = async (record: Access) => {
|
||||
export const save = async (record: AccessModel) => {
|
||||
if (record.id) {
|
||||
return await getPocketBase().collection("access").update(record.id, record);
|
||||
return await getPocketBase().collection(COLLECTION_NAME).update<AccessModel>(record.id, record);
|
||||
}
|
||||
|
||||
return await getPocketBase().collection("access").create(record);
|
||||
return await getPocketBase().collection(COLLECTION_NAME).create<AccessModel>(record);
|
||||
};
|
||||
|
||||
export const remove = async (record: Access) => {
|
||||
record.deleted = dayjs.utc().format("YYYY-MM-DD HH:mm:ss");
|
||||
return await getPocketBase().collection("access").update(record.id, record);
|
||||
export const remove = async (record: AccessModel) => {
|
||||
record = { ...record, deleted: dayjs.utc().format("YYYY-MM-DD HH:mm:ss") };
|
||||
await getPocketBase().collection(COLLECTION_NAME).update<AccessModel>(record.id, record);
|
||||
};
|
||||
|
@ -1,9 +1,11 @@
|
||||
import dayjs from "dayjs";
|
||||
import { type RecordListOptions } from "pocketbase";
|
||||
|
||||
import { type Certificate } from "@/domain/certificate";
|
||||
import { type CertificateModel } from "@/domain/certificate";
|
||||
import { getPocketBase } from "./pocketbase";
|
||||
|
||||
const COLLECTION_NAME = "certificate";
|
||||
|
||||
export type CertificateListReq = {
|
||||
page?: number;
|
||||
perPage?: number;
|
||||
@ -31,5 +33,5 @@ export const list = async (req: CertificateListReq) => {
|
||||
});
|
||||
}
|
||||
|
||||
return pb.collection("certificate").getList<Certificate>(page, perPage, options);
|
||||
return pb.collection(COLLECTION_NAME).getList<CertificateModel>(page, perPage, options);
|
||||
};
|
||||
|
@ -1,22 +1,22 @@
|
||||
import { Settings } from "@/domain/settings";
|
||||
import { SettingsModel } from "@/domain/settings";
|
||||
import { getPocketBase } from "./pocketbase";
|
||||
|
||||
export const get = async <T>(name: string) => {
|
||||
try {
|
||||
const resp = await getPocketBase().collection("settings").getFirstListItem<Settings<T>>(`name='${name}'`);
|
||||
const resp = await getPocketBase().collection("settings").getFirstListItem<SettingsModel<T>>(`name='${name}'`);
|
||||
return resp;
|
||||
} catch {
|
||||
return {
|
||||
name: name,
|
||||
content: {} as T,
|
||||
} as Settings<T>;
|
||||
} as SettingsModel<T>;
|
||||
}
|
||||
};
|
||||
|
||||
export const save = async <T>(record: Settings<T>) => {
|
||||
export const save = async <T>(record: SettingsModel<T>) => {
|
||||
if (record.id) {
|
||||
return await getPocketBase().collection("settings").update<Settings<T>>(record.id, record);
|
||||
return await getPocketBase().collection("settings").update<SettingsModel<T>>(record.id, record);
|
||||
}
|
||||
|
||||
return await getPocketBase().collection("settings").create<Settings<T>>(record);
|
||||
return await getPocketBase().collection("settings").create<SettingsModel<T>>(record);
|
||||
};
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { type RecordListOptions } from "pocketbase";
|
||||
|
||||
import { type Workflow, type WorkflowNode, type WorkflowRunLog } from "@/domain/workflow";
|
||||
import { type WorkflowModel, type WorkflowNode, type WorkflowRunLog } from "@/domain/workflow";
|
||||
import { getPocketBase } from "./pocketbase";
|
||||
|
||||
const COLLECTION_NAME = "workflow";
|
||||
|
||||
export type WorkflowListReq = {
|
||||
page?: number;
|
||||
perPage?: number;
|
||||
@ -20,25 +22,25 @@ export const list = async (req: WorkflowListReq) => {
|
||||
options.filter = pb.filter("enabled={:enabled}", { enabled: req.enabled });
|
||||
}
|
||||
|
||||
return await pb.collection("workflow").getList<Workflow>(page, perPage, options);
|
||||
return await pb.collection(COLLECTION_NAME).getList<WorkflowModel>(page, perPage, options);
|
||||
};
|
||||
|
||||
export const get = async (id: string) => {
|
||||
return await getPocketBase().collection("workflow").getOne<Workflow>(id);
|
||||
return await getPocketBase().collection(COLLECTION_NAME).getOne<WorkflowModel>(id);
|
||||
};
|
||||
|
||||
export const save = async (record: Record<string, string | boolean | WorkflowNode>) => {
|
||||
if (record.id) {
|
||||
return await getPocketBase()
|
||||
.collection("workflow")
|
||||
.update<Workflow>(record.id as string, record);
|
||||
.collection(COLLECTION_NAME)
|
||||
.update<WorkflowModel>(record.id as string, record);
|
||||
}
|
||||
|
||||
return await getPocketBase().collection("workflow").create<Workflow>(record);
|
||||
return await getPocketBase().collection(COLLECTION_NAME).create<WorkflowModel>(record);
|
||||
};
|
||||
|
||||
export const remove = async (record: Workflow) => {
|
||||
return await getPocketBase().collection("workflow").delete(record.id);
|
||||
export const remove = async (record: WorkflowModel) => {
|
||||
await getPocketBase().collection(COLLECTION_NAME).delete(record.id);
|
||||
};
|
||||
|
||||
type WorkflowLogsReq = {
|
||||
|
58
ui/src/stores/access/index.ts
Normal file
58
ui/src/stores/access/index.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import { create } from "zustand";
|
||||
import { produce } from "immer";
|
||||
|
||||
import { type AccessModel } from "@/domain/access";
|
||||
import { list as listAccess, save as saveAccess, remove as removeAccess } from "@/repository/access";
|
||||
|
||||
export interface AccessState {
|
||||
accesses: AccessModel[];
|
||||
createAccess: (access: AccessModel) => void;
|
||||
updateAccess: (access: AccessModel) => void;
|
||||
deleteAccess: (access: AccessModel) => void;
|
||||
fetchAccesses: () => Promise<void>;
|
||||
}
|
||||
|
||||
export const useAccessStore = create<AccessState>((set) => {
|
||||
return {
|
||||
accesses: [],
|
||||
|
||||
createAccess: async (access) => {
|
||||
access = await saveAccess(access);
|
||||
|
||||
set(
|
||||
produce((state: AccessState) => {
|
||||
state.accesses.unshift(access);
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
updateAccess: async (access) => {
|
||||
access = await saveAccess(access);
|
||||
|
||||
set(
|
||||
produce((state: AccessState) => {
|
||||
const index = state.accesses.findIndex((e) => e.id === access.id);
|
||||
state.accesses[index] = access;
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
deleteAccess: async (access) => {
|
||||
await removeAccess(access);
|
||||
|
||||
set(
|
||||
produce((state: AccessState) => {
|
||||
state.accesses = state.accesses.filter((a) => a.id !== access.id);
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
fetchAccesses: async () => {
|
||||
const accesses = await listAccess();
|
||||
|
||||
set({
|
||||
accesses: accesses ?? [],
|
||||
});
|
||||
},
|
||||
};
|
||||
});
|
@ -1,7 +1,7 @@
|
||||
import { create } from "zustand";
|
||||
import { produce } from "immer";
|
||||
|
||||
import { type EmailsSettingsContent, type Settings } from "@/domain/settings";
|
||||
import { type EmailsSettingsContent, type SettingsModel } from "@/domain/settings";
|
||||
import { get as getSettings, save as saveSettings } from "@/repository/settings";
|
||||
|
||||
export interface ContactState {
|
||||
@ -11,7 +11,7 @@ export interface ContactState {
|
||||
}
|
||||
|
||||
export const useContactStore = create<ContactState>((set) => {
|
||||
let settings: Settings<EmailsSettingsContent>;
|
||||
let settings: SettingsModel<EmailsSettingsContent>;
|
||||
|
||||
return {
|
||||
emails: [],
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
removeBranch,
|
||||
removeNode,
|
||||
updateNode,
|
||||
Workflow,
|
||||
WorkflowModel,
|
||||
WorkflowBranchNode,
|
||||
WorkflowNode,
|
||||
WorkflowNodeType,
|
||||
@ -17,7 +17,7 @@ import {
|
||||
import { get as getWorkflow, save as saveWorkflow } from "@/repository/workflow";
|
||||
|
||||
export type WorkflowState = {
|
||||
workflow: Workflow;
|
||||
workflow: WorkflowModel;
|
||||
initialized: boolean;
|
||||
updateNode: (node: WorkflowNode) => void;
|
||||
addNode: (node: WorkflowNode, preId: string) => void;
|
||||
|
Loading…
x
Reference in New Issue
Block a user