feat: rename access to providerAccessId
This commit is contained in:
@@ -7,7 +7,7 @@ import { z } from "zod";
|
||||
|
||||
import AccessProviderSelect from "@/components/provider/AccessProviderSelect";
|
||||
import { type AccessModel } from "@/domain/access";
|
||||
import { ACCESS_PROVIDERS, accessProvidersMap } from "@/domain/provider";
|
||||
import { ACCESS_PROVIDERS } from "@/domain/provider";
|
||||
import { useAntdForm } from "@/hooks";
|
||||
|
||||
import AccessEditFormACMEHttpReqConfig from "./AccessEditFormACMEHttpReqConfig";
|
||||
|
||||
@@ -50,7 +50,7 @@ const WorkflowRunDetailDrawer = ({ data, loading, trigger, ...props }: WorkflowR
|
||||
{item.outputs.map((output, j) => {
|
||||
return (
|
||||
<div key={j} className="flex space-x-2 text-sm">
|
||||
<div>[{dayjs(output.time).format("YYYY-MM-DD HH:mm:ss")}]</div>
|
||||
<div className="whitespace-nowrap">[{dayjs(output.time).format("YYYY-MM-DD HH:mm:ss")}]</div>
|
||||
{output.error ? <div className="text-red-500">{output.error}</div> : <div>{output.content}</div>}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -12,8 +12,9 @@ import MultipleInput from "@/components/MultipleInput";
|
||||
import AccessEditModal from "@/components/access/AccessEditModal";
|
||||
import AccessSelect from "@/components/access/AccessSelect";
|
||||
import { ACCESS_USAGES, accessProvidersMap } from "@/domain/provider";
|
||||
import { type WorkflowNode } from "@/domain/workflow";
|
||||
import { type WorkflowApplyNodeConfig, type WorkflowNode } from "@/domain/workflow";
|
||||
import { useAntdForm, useZustandShallowSelector } from "@/hooks";
|
||||
import { useAccessesStore } from "@/stores/access";
|
||||
import { useContactEmailsStore } from "@/stores/contact";
|
||||
import { useWorkflowStore } from "@/stores/workflow";
|
||||
import { validDomainName, validIPv4Address, validIPv6Address } from "@/utils/validators";
|
||||
@@ -25,12 +26,10 @@ export type ApplyNodeFormProps = {
|
||||
|
||||
const MULTIPLE_INPUT_DELIMITER = ";";
|
||||
|
||||
const initFormModel = () => {
|
||||
const initFormModel = (): Partial<WorkflowApplyNodeConfig> => {
|
||||
return {
|
||||
domain: "",
|
||||
keyAlgorithm: "RSA2048",
|
||||
nameservers: "",
|
||||
propagationTimeout: 60,
|
||||
propagationTimeout: 120,
|
||||
disableFollowCNAME: true,
|
||||
};
|
||||
};
|
||||
@@ -38,6 +37,7 @@ const initFormModel = () => {
|
||||
const ApplyNodeForm = ({ node }: ApplyNodeFormProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { accesses } = useAccessesStore(useZustandShallowSelector("accesses"));
|
||||
const { addEmail } = useContactEmailsStore(useZustandShallowSelector("addEmail"));
|
||||
const { updateNode } = useWorkflowStore(useZustandShallowSelector(["updateNode"]));
|
||||
const { hidePanel } = usePanel();
|
||||
@@ -49,7 +49,9 @@ const ApplyNodeForm = ({ node }: ApplyNodeFormProps) => {
|
||||
.every((e) => validDomainName(e, true));
|
||||
}, t("common.errmsg.domain_invalid")),
|
||||
email: z.string({ message: t("workflow_node.apply.form.email.placeholder") }).email("common.errmsg.email_invalid"),
|
||||
access: z.string({ message: t("workflow_node.apply.form.access.placeholder") }).min(1, t("workflow_node.apply.form.access.placeholder")),
|
||||
providerAccessId: z
|
||||
.string({ message: t("workflow_node.apply.form.provider_access.placeholder") })
|
||||
.min(1, t("workflow_node.apply.form.provider_access.placeholder")),
|
||||
keyAlgorithm: z.string().nullish(),
|
||||
nameservers: z
|
||||
.string()
|
||||
@@ -74,13 +76,16 @@ const ApplyNodeForm = ({ node }: ApplyNodeFormProps) => {
|
||||
formPending,
|
||||
formProps,
|
||||
} = useAntdForm<z.infer<typeof formSchema>>({
|
||||
initialValues: node?.config ?? initFormModel(),
|
||||
initialValues: (node?.config as WorkflowApplyNodeConfig) ?? initFormModel(),
|
||||
onSubmit: async (values) => {
|
||||
await formInst.validateFields();
|
||||
await addEmail(values.email);
|
||||
await updateNode(
|
||||
produce(node, (draft) => {
|
||||
draft.config = { ...values };
|
||||
draft.config = {
|
||||
provider: accesses.find((e) => e.id === values.providerAccessId)?.provider,
|
||||
...values,
|
||||
} as WorkflowApplyNodeConfig;
|
||||
draft.validated = true;
|
||||
})
|
||||
);
|
||||
@@ -146,8 +151,8 @@ const ApplyNodeForm = ({ node }: ApplyNodeFormProps) => {
|
||||
<label className="mb-1 block">
|
||||
<div className="flex w-full items-center justify-between gap-4">
|
||||
<div className="max-w-full grow truncate">
|
||||
<span>{t("workflow_node.apply.form.access.label")}</span>
|
||||
<Tooltip title={t("workflow_node.apply.form.access.tooltip")}>
|
||||
<span>{t("workflow_node.apply.form.provider_access.label")}</span>
|
||||
<Tooltip title={t("workflow_node.apply.form.provider_access.tooltip")}>
|
||||
<Typography.Text className="ms-1" type="secondary">
|
||||
<QuestionCircleOutlinedIcon />
|
||||
</Typography.Text>
|
||||
@@ -159,22 +164,22 @@ const ApplyNodeForm = ({ node }: ApplyNodeFormProps) => {
|
||||
trigger={
|
||||
<Button size="small" type="link">
|
||||
<PlusOutlinedIcon />
|
||||
{t("workflow_node.apply.form.access.button")}
|
||||
{t("workflow_node.apply.form.provider_access.button")}
|
||||
</Button>
|
||||
}
|
||||
onSubmit={(record) => {
|
||||
const provider = accessProvidersMap.get(record.provider);
|
||||
if (ACCESS_USAGES.ALL === provider?.usage || ACCESS_USAGES.APPLY === provider?.usage) {
|
||||
formInst.setFieldValue("access", record.id);
|
||||
formInst.setFieldValue("providerAccessId", record.id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
<Form.Item name="access" rules={[formRule]}>
|
||||
<Form.Item name="providerAccessId" rules={[formRule]}>
|
||||
<AccessSelect
|
||||
placeholder={t("workflow_node.apply.form.access.placeholder")}
|
||||
placeholder={t("workflow_node.apply.form.provider_access.placeholder")}
|
||||
filter={(record) => {
|
||||
const provider = accessProvidersMap.get(record.provider);
|
||||
return ACCESS_USAGES.ALL === provider?.usage || ACCESS_USAGES.APPLY === provider?.usage;
|
||||
|
||||
@@ -12,7 +12,7 @@ import AccessSelect from "@/components/access/AccessSelect";
|
||||
import DeployProviderPicker from "@/components/provider/DeployProviderPicker";
|
||||
import DeployProviderSelect from "@/components/provider/DeployProviderSelect";
|
||||
import { ACCESS_USAGES, DEPLOY_PROVIDERS, accessProvidersMap, deployProvidersMap } from "@/domain/provider";
|
||||
import { type WorkflowNode } from "@/domain/workflow";
|
||||
import { type WorkflowDeployNodeConfig, type WorkflowNode } from "@/domain/workflow";
|
||||
import { useAntdForm, useZustandShallowSelector } from "@/hooks";
|
||||
import { useWorkflowStore } from "@/stores/workflow";
|
||||
import { usePanel } from "../PanelProvider";
|
||||
@@ -44,7 +44,7 @@ export type DeployFormProps = {
|
||||
node: WorkflowNode;
|
||||
};
|
||||
|
||||
const initFormModel = () => {
|
||||
const initFormModel = (): Partial<WorkflowDeployNodeConfig> => {
|
||||
return {};
|
||||
};
|
||||
|
||||
@@ -56,7 +56,7 @@ const DeployNodeForm = ({ node }: DeployFormProps) => {
|
||||
|
||||
const formSchema = z.object({
|
||||
provider: z.string({ message: t("workflow_node.deploy.form.provider.placeholder") }).nonempty(t("workflow_node.deploy.form.provider.placeholder")),
|
||||
access: z
|
||||
providerAccessId: z
|
||||
.string({ message: t("workflow_node.deploy.form.provider_access.placeholder") })
|
||||
.nonempty(t("workflow_node.deploy.form.provider_access.placeholder")),
|
||||
certificate: z.string({ message: t("workflow_node.deploy.form.certificate.placeholder") }).nonempty(t("workflow_node.deploy.form.certificate.placeholder")),
|
||||
@@ -67,7 +67,7 @@ const DeployNodeForm = ({ node }: DeployFormProps) => {
|
||||
formPending,
|
||||
formProps,
|
||||
} = useAntdForm<z.infer<typeof formSchema>>({
|
||||
initialValues: node?.config ?? initFormModel(),
|
||||
initialValues: (node?.config as WorkflowDeployNodeConfig) ?? initFormModel(),
|
||||
onSubmit: async (values) => {
|
||||
await formInst.validateFields();
|
||||
await updateNode(
|
||||
@@ -160,7 +160,7 @@ const DeployNodeForm = ({ node }: DeployFormProps) => {
|
||||
const oldValues = formInst.getFieldsValue();
|
||||
const newValues: Record<string, unknown> = {};
|
||||
for (const key in oldValues) {
|
||||
if (key === "provider" || key === "access" || key === "certificate") {
|
||||
if (key === "provider" || key === "providerAccessId" || key === "certificate") {
|
||||
newValues[key] = oldValues[key];
|
||||
} else {
|
||||
newValues[key] = undefined;
|
||||
@@ -169,7 +169,7 @@ const DeployNodeForm = ({ node }: DeployFormProps) => {
|
||||
formInst.setFieldsValue(newValues);
|
||||
|
||||
if (deployProvidersMap.get(fieldProvider)?.provider !== deployProvidersMap.get(value)?.provider) {
|
||||
formInst.setFieldValue("access", undefined);
|
||||
formInst.setFieldValue("providerAccessId", undefined);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -205,14 +205,14 @@ const DeployNodeForm = ({ node }: DeployFormProps) => {
|
||||
onSubmit={(record) => {
|
||||
const provider = accessProvidersMap.get(record.provider);
|
||||
if (ACCESS_USAGES.ALL === provider?.usage || ACCESS_USAGES.DEPLOY === provider?.usage) {
|
||||
formInst.setFieldValue("access", record.id);
|
||||
formInst.setFieldValue("providerAccessId", record.id);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
<Form.Item name="access" rules={[formRule]}>
|
||||
<Form.Item name="providerAccessId" rules={[formRule]}>
|
||||
<AccessSelect
|
||||
placeholder={t("workflow_node.deploy.form.provider_access.placeholder")}
|
||||
filter={(record) => {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { produce } from "immer";
|
||||
import { z } from "zod";
|
||||
|
||||
import { notifyChannelsMap } from "@/domain/settings";
|
||||
import { type WorkflowNode } from "@/domain/workflow";
|
||||
import { type WorkflowNode, type WorkflowNotifyNodeConfig } from "@/domain/workflow";
|
||||
import { useAntdForm, useZustandShallowSelector } from "@/hooks";
|
||||
import { useNotifyChannelsStore } from "@/stores/notify";
|
||||
import { useWorkflowStore } from "@/stores/workflow";
|
||||
@@ -18,7 +18,7 @@ export type NotifyNodeFormProps = {
|
||||
node: WorkflowNode;
|
||||
};
|
||||
|
||||
const initFormModel = () => {
|
||||
const initFormModel = (): Partial<WorkflowNotifyNodeConfig> => {
|
||||
return {
|
||||
subject: "Completed!",
|
||||
message: "Your workflow has been completed on Certimate.",
|
||||
@@ -57,7 +57,7 @@ const NotifyNodeForm = ({ node }: NotifyNodeFormProps) => {
|
||||
formPending,
|
||||
formProps,
|
||||
} = useAntdForm<z.infer<typeof formSchema>>({
|
||||
initialValues: node?.config ?? initFormModel(),
|
||||
initialValues: (node?.config as WorkflowNotifyNodeConfig) ?? initFormModel(),
|
||||
onSubmit: async (values) => {
|
||||
await formInst.validateFields();
|
||||
await updateNode(
|
||||
|
||||
@@ -7,7 +7,7 @@ import { produce } from "immer";
|
||||
import { z } from "zod";
|
||||
|
||||
import Show from "@/components/Show";
|
||||
import { type WorkflowNode } from "@/domain/workflow";
|
||||
import { type WorkflowNode, type WorkflowStartNodeConfig } from "@/domain/workflow";
|
||||
import { useAntdForm, useZustandShallowSelector } from "@/hooks";
|
||||
import { useWorkflowStore } from "@/stores/workflow";
|
||||
import { getNextCronExecutions, validCronExpression } from "@/utils/cron";
|
||||
@@ -17,7 +17,7 @@ export type StartNodeFormProps = {
|
||||
node: WorkflowNode;
|
||||
};
|
||||
|
||||
const initFormModel = () => {
|
||||
const initFormModel = (): WorkflowStartNodeConfig => {
|
||||
return {
|
||||
executionMethod: "auto",
|
||||
crontab: "0 0 * * *",
|
||||
@@ -54,7 +54,7 @@ const StartNodeForm = ({ node }: StartNodeFormProps) => {
|
||||
formPending,
|
||||
formProps,
|
||||
} = useAntdForm<z.infer<typeof formSchema>>({
|
||||
initialValues: node?.config ?? initFormModel(),
|
||||
initialValues: (node?.config as WorkflowStartNodeConfig) ?? initFormModel(),
|
||||
onSubmit: async (values) => {
|
||||
await formInst.validateFields();
|
||||
await updateNode(
|
||||
|
||||
@@ -85,6 +85,39 @@ export type WorkflowNode = {
|
||||
validated?: boolean;
|
||||
};
|
||||
|
||||
export type WorkflowStartNodeConfig = {
|
||||
executionMethod: string;
|
||||
crontab?: string;
|
||||
};
|
||||
|
||||
export type WorkflowApplyNodeConfig = {
|
||||
domain: string;
|
||||
email: string;
|
||||
provider: string;
|
||||
providerAccessId: string;
|
||||
keyAlgorithm: string;
|
||||
nameservers?: string;
|
||||
propagationTimeout?: number;
|
||||
disableFollowCNAME?: boolean;
|
||||
};
|
||||
|
||||
export type WorkflowDeployNodeConfig = {
|
||||
provider: string;
|
||||
providerAccessId: string;
|
||||
certificate: string;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
export type WorkflowNotifyNodeConfig = {
|
||||
channel: string;
|
||||
subject: string;
|
||||
message: string;
|
||||
};
|
||||
|
||||
export type WorkflowBranchNodeConfig = never;
|
||||
|
||||
export type WorkflowEndNodeConfig = never;
|
||||
|
||||
export type WorkflowNodeIO = {
|
||||
name: string;
|
||||
type: string;
|
||||
@@ -150,7 +183,7 @@ export const newNode = (nodeType: WorkflowNodeType, options: NewNodeOptions = {}
|
||||
case WorkflowNodeType.Apply:
|
||||
case WorkflowNodeType.Deploy:
|
||||
{
|
||||
node.config = {};
|
||||
node.config = {} as Record<string, unknown>;
|
||||
node.input = workflowNodeTypeDefaultInputs.get(nodeType);
|
||||
node.output = workflowNodeTypeDefaultOutputs.get(nodeType);
|
||||
}
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
"workflow_node.apply.form.email.label": "Contact email",
|
||||
"workflow_node.apply.form.email.placeholder": "Please enter contact email",
|
||||
"workflow_node.apply.form.email.tooltip": "Contact information required for SSL certificate application. Please pay attention to the <a href=\"https://letsencrypt.org/docs/rate-limits/\" target=\"_blank\">rate limits</a>.",
|
||||
"workflow_node.apply.form.access.label": "DNS provider authorization",
|
||||
"workflow_node.apply.form.access.placeholder": "Please select an authorization of DNS provider",
|
||||
"workflow_node.apply.form.access.tooltip": "Used to manage DNS records during ACME DNS-01 authentication.",
|
||||
"workflow_node.apply.form.access.button": "Create",
|
||||
"workflow_node.apply.form.provider_access.label": "DNS provider authorization",
|
||||
"workflow_node.apply.form.provider_access.placeholder": "Please select an authorization of DNS provider",
|
||||
"workflow_node.apply.form.provider_access.tooltip": "Used to manage DNS records during ACME DNS-01 authentication.",
|
||||
"workflow_node.apply.form.provider_access.button": "Create",
|
||||
"workflow_node.apply.form.advanced_config.label": "Advanced settings",
|
||||
"workflow_node.apply.form.key_algorithm.label": "Certificate key algorithm",
|
||||
"workflow_node.apply.form.key_algorithm.placeholder": "Please select certificate key algorithm",
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
"workflow_node.apply.form.email.label": "联系邮箱",
|
||||
"workflow_node.apply.form.email.placeholder": "请输入联系邮箱",
|
||||
"workflow_node.apply.form.email.tooltip": "申请签发 SSL 证书时所需的联系方式。请注意 Let's Encrypt 账户注册的速率限制。<br><a href=\"https://letsencrypt.org/zh-cn/docs/rate-limits/\" target=\"_blank\">点此了解更多</a>。",
|
||||
"workflow_node.apply.form.access.label": "DNS 提供商授权",
|
||||
"workflow_node.apply.form.access.placeholder": "请选择 DNS 提供商授权",
|
||||
"workflow_node.apply.form.access.tooltip": "用于 ACME DNS-01 认证时操作域名解析记录,注意与部署阶段所需的主机提供商相区分。",
|
||||
"workflow_node.apply.form.access.button": "新建",
|
||||
"workflow_node.apply.form.provider_access.label": "DNS 提供商授权",
|
||||
"workflow_node.apply.form.provider_access.placeholder": "请选择 DNS 提供商授权",
|
||||
"workflow_node.apply.form.provider_access.tooltip": "用于 ACME DNS-01 认证时操作域名解析记录,注意与部署阶段所需的主机提供商相区分。",
|
||||
"workflow_node.apply.form.provider_access.button": "新建",
|
||||
"workflow_node.apply.form.advanced_config.label": "高级设置",
|
||||
"workflow_node.apply.form.key_algorithm.label": "数字证书算法",
|
||||
"workflow_node.apply.form.key_algorithm.placeholder": "请选择数字证书算法",
|
||||
|
||||
Reference in New Issue
Block a user