From 252da5d7e1f30e1cc5ee2ea1bbac89d6287b4cdd Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Wed, 4 Jun 2025 10:50:52 +0800 Subject: [PATCH] refactor(ui): clean code --- .../workflow/node-processor/monitor_node.go | 5 +- .../workflow/node/ApplyNodeConfigForm.tsx | 8 +-- .../workflow/node/ConditionNodeConfigForm.tsx | 4 +- .../workflow/node/DeployNodeConfigForm.tsx | 6 +- .../workflow/node/MonitorNodeConfigForm.tsx | 8 +-- .../workflow/node/NotifyNodeConfigForm.tsx | 4 +- .../workflow/node/StartNodeConfigForm.tsx | 7 +-- .../workflow/node/UploadNodeConfigForm.tsx | 4 +- ui/src/domain/workflow.ts | 60 +++++++++++++++++-- 9 files changed, 72 insertions(+), 34 deletions(-) diff --git a/internal/workflow/node-processor/monitor_node.go b/internal/workflow/node-processor/monitor_node.go index 4b875f26..86714d57 100644 --- a/internal/workflow/node-processor/monitor_node.go +++ b/internal/workflow/node-processor/monitor_node.go @@ -6,6 +6,7 @@ import ( "crypto/x509" "fmt" "math" + "net" "net/http" "strconv" "strings" @@ -34,9 +35,9 @@ func (n *monitorNode) Process(ctx context.Context) error { nodeCfg := n.node.GetConfigForMonitor() - targetAddr := fmt.Sprintf("%s:%d", nodeCfg.Host, nodeCfg.Port) + targetAddr := net.JoinHostPort(nodeCfg.Host, fmt.Sprintf("%d", nodeCfg.Port)) if nodeCfg.Port == 0 { - targetAddr = fmt.Sprintf("%s:443", nodeCfg.Host) + targetAddr = net.JoinHostPort(nodeCfg.Host, "443") } targetDomain := nodeCfg.Domain diff --git a/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx b/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx index ae56efc3..abbce8b4 100644 --- a/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/ApplyNodeConfigForm.tsx @@ -28,7 +28,7 @@ import ACMEDns01ProviderSelect from "@/components/provider/ACMEDns01ProviderSele import CAProviderSelect from "@/components/provider/CAProviderSelect"; import Show from "@/components/Show"; import { ACCESS_USAGES, ACME_DNS01_PROVIDERS, accessProvidersMap, acmeDns01ProvidersMap, caProvidersMap } from "@/domain/provider"; -import { type WorkflowNodeConfigForApply } from "@/domain/workflow"; +import { type WorkflowNodeConfigForApply, defaultNodeConfigForApply } from "@/domain/workflow"; import { useAntdForm, useAntdFormName, useZustandShallowSelector } from "@/hooks"; import { useAccessesStore } from "@/stores/access"; import { useContactEmailsStore } from "@/stores/contact"; @@ -59,11 +59,7 @@ export type ApplyNodeConfigFormInstance = { const MULTIPLE_INPUT_SEPARATOR = ";"; const initFormModel = (): ApplyNodeConfigFormFieldValues => { - return { - challengeType: "dns-01", - keyAlgorithm: "RSA2048", - skipBeforeExpiryDays: 30, - }; + return defaultNodeConfigForApply(); }; const ApplyNodeConfigForm = forwardRef( diff --git a/ui/src/components/workflow/node/ConditionNodeConfigForm.tsx b/ui/src/components/workflow/node/ConditionNodeConfigForm.tsx index 3cd92d7b..1a2794e7 100644 --- a/ui/src/components/workflow/node/ConditionNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/ConditionNodeConfigForm.tsx @@ -4,7 +4,7 @@ import { Form, type FormInstance } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type Expr, type WorkflowNodeConfigForCondition } from "@/domain/workflow"; +import { type Expr, type WorkflowNodeConfigForCondition, defaultNodeConfigForCondition } from "@/domain/workflow"; import { useAntdForm } from "@/hooks"; import ConditionNodeConfigFormExpressionEditor, { type ConditionNodeConfigFormExpressionEditorInstance } from "./ConditionNodeConfigFormExpressionEditor"; @@ -29,7 +29,7 @@ export type ConditionNodeConfigFormInstance = { }; const initFormModel = (): ConditionNodeConfigFormFieldValues => { - return {}; + return defaultNodeConfigForCondition(); }; const ConditionNodeConfigForm = forwardRef( diff --git a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx index c0083298..96e50911 100644 --- a/ui/src/components/workflow/node/DeployNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/DeployNodeConfigForm.tsx @@ -11,7 +11,7 @@ import DeploymentProviderPicker from "@/components/provider/DeploymentProviderPi import DeploymentProviderSelect from "@/components/provider/DeploymentProviderSelect.tsx"; import Show from "@/components/Show"; import { ACCESS_USAGES, DEPLOYMENT_PROVIDERS, accessProvidersMap, deploymentProvidersMap } from "@/domain/provider"; -import { type WorkflowNodeConfigForDeploy, WorkflowNodeType } from "@/domain/workflow"; +import { type WorkflowNodeConfigForDeploy, WorkflowNodeType, defaultNodeConfigForDeploy } from "@/domain/workflow"; import { useAntdForm, useAntdFormName, useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; @@ -117,9 +117,7 @@ export type DeployNodeConfigFormInstance = { }; const initFormModel = (): DeployNodeConfigFormFieldValues => { - return { - skipOnLastSucceeded: true, - }; + return defaultNodeConfigForDeploy(); }; const DeployNodeConfigForm = forwardRef( diff --git a/ui/src/components/workflow/node/MonitorNodeConfigForm.tsx b/ui/src/components/workflow/node/MonitorNodeConfigForm.tsx index 883124f9..92eef42e 100644 --- a/ui/src/components/workflow/node/MonitorNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/MonitorNodeConfigForm.tsx @@ -4,7 +4,7 @@ import { Alert, Form, type FormInstance, Input, InputNumber } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; -import { type WorkflowNodeConfigForMonitor } from "@/domain/workflow"; +import { type WorkflowNodeConfigForMonitor, defaultNodeConfigForMonitor } from "@/domain/workflow"; import { useAntdForm } from "@/hooks"; import { validDomainName, validIPv4Address, validIPv6Address, validPortNumber } from "@/utils/validators"; @@ -25,11 +25,7 @@ export type MonitorNodeConfigFormInstance = { }; const initFormModel = (): MonitorNodeConfigFormFieldValues => { - return { - host: "", - port: 443, - requestPath: "/", - }; + return defaultNodeConfigForMonitor(); }; const MonitorNodeConfigForm = forwardRef( diff --git a/ui/src/components/workflow/node/NotifyNodeConfigForm.tsx b/ui/src/components/workflow/node/NotifyNodeConfigForm.tsx index 3c612df8..4473da6a 100644 --- a/ui/src/components/workflow/node/NotifyNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/NotifyNodeConfigForm.tsx @@ -12,7 +12,7 @@ import NotificationProviderSelect from "@/components/provider/NotificationProvid import Show from "@/components/Show"; import { ACCESS_USAGES, NOTIFICATION_PROVIDERS, accessProvidersMap, notificationProvidersMap } from "@/domain/provider"; import { notifyChannelsMap } from "@/domain/settings"; -import { type WorkflowNodeConfigForNotify } from "@/domain/workflow"; +import { type WorkflowNodeConfigForNotify, defaultNodeConfigForNotify } from "@/domain/workflow"; import { useAntdForm, useAntdFormName, useZustandShallowSelector } from "@/hooks"; import { useAccessesStore } from "@/stores/access"; import { useNotifyChannelsStore } from "@/stores/notify"; @@ -41,7 +41,7 @@ export type NotifyNodeConfigFormInstance = { }; const initFormModel = (): NotifyNodeConfigFormFieldValues => { - return {}; + return defaultNodeConfigForNotify(); }; const NotifyNodeConfigForm = forwardRef( diff --git a/ui/src/components/workflow/node/StartNodeConfigForm.tsx b/ui/src/components/workflow/node/StartNodeConfigForm.tsx index 7b3ba73d..7acdfddc 100644 --- a/ui/src/components/workflow/node/StartNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/StartNodeConfigForm.tsx @@ -6,7 +6,7 @@ import dayjs from "dayjs"; import { z } from "zod"; import Show from "@/components/Show"; -import { WORKFLOW_TRIGGERS, type WorkflowNodeConfigForStart, type WorkflowTriggerType } from "@/domain/workflow"; +import { WORKFLOW_TRIGGERS, type WorkflowNodeConfigForStart, type WorkflowTriggerType, defaultNodeConfigForStart } from "@/domain/workflow"; import { useAntdForm } from "@/hooks"; import { getNextCronExecutions, validCronExpression } from "@/utils/cron"; @@ -27,10 +27,7 @@ export type StartNodeConfigFormInstance = { }; const initFormModel = (): StartNodeConfigFormFieldValues => { - return { - trigger: WORKFLOW_TRIGGERS.AUTO, - triggerCron: "0 0 * * *", - }; + return defaultNodeConfigForStart(); }; const StartNodeConfigForm = forwardRef( diff --git a/ui/src/components/workflow/node/UploadNodeConfigForm.tsx b/ui/src/components/workflow/node/UploadNodeConfigForm.tsx index 5dc16b0b..27898401 100644 --- a/ui/src/components/workflow/node/UploadNodeConfigForm.tsx +++ b/ui/src/components/workflow/node/UploadNodeConfigForm.tsx @@ -6,7 +6,7 @@ import { z } from "zod"; import { validateCertificate, validatePrivateKey } from "@/api/certificates"; import TextFileInput from "@/components/TextFileInput"; -import { type WorkflowNodeConfigForUpload } from "@/domain/workflow"; +import { type WorkflowNodeConfigForUpload, defaultNodeConfigForUpload } from "@/domain/workflow"; import { useAntdForm } from "@/hooks"; import { getErrMsg } from "@/utils/error"; @@ -27,7 +27,7 @@ export type UploadNodeConfigFormInstance = { }; const initFormModel = (): UploadNodeConfigFormFieldValues => { - return {}; + return defaultNodeConfigForUpload(); }; const UploadNodeConfigForm = forwardRef( diff --git a/ui/src/domain/workflow.ts b/ui/src/domain/workflow.ts index 6ebb7c97..50a0be4a 100644 --- a/ui/src/domain/workflow.ts +++ b/ui/src/domain/workflow.ts @@ -133,6 +133,13 @@ export type WorkflowNodeConfigForStart = { triggerCron?: string; }; +export const defaultNodeConfigForStart = (): Partial => { + return { + trigger: WORKFLOW_TRIGGERS.AUTO, + triggerCron: "0 0 * * *", + }; +}; + export type WorkflowNodeConfigForApply = { domains: string; contactEmail: string; @@ -152,6 +159,14 @@ export type WorkflowNodeConfigForApply = { skipBeforeExpiryDays: number; }; +export const defaultNodeConfigForApply = (): Partial => { + return { + challengeType: "dns-01", + keyAlgorithm: "RSA2048", + skipBeforeExpiryDays: 30, + }; +}; + export type WorkflowNodeConfigForUpload = { certificateId: string; domains: string; @@ -159,6 +174,10 @@ export type WorkflowNodeConfigForUpload = { privateKey: string; }; +export const defaultNodeConfigForUpload = (): Partial => { + return {}; +}; + export type WorkflowNodeConfigForMonitor = { host: string; port: number; @@ -166,6 +185,13 @@ export type WorkflowNodeConfigForMonitor = { requestPath?: string; }; +export const defaultNodeConfigForMonitor = (): Partial => { + return { + port: 443, + requestPath: "/", + }; +}; + export type WorkflowNodeConfigForDeploy = { certificate: string; provider: string; @@ -174,6 +200,12 @@ export type WorkflowNodeConfigForDeploy = { skipOnLastSucceeded: boolean; }; +export const defaultNodeConfigForDeploy = (): Partial => { + return { + skipOnLastSucceeded: true, + }; +}; + export type WorkflowNodeConfigForNotify = { subject: string; message: string; @@ -186,10 +218,18 @@ export type WorkflowNodeConfigForNotify = { providerConfig?: Record; }; +export const defaultNodeConfigForNotify = (): Partial => { + return {}; +}; + export type WorkflowNodeConfigForCondition = { expression?: Expr; }; +export const defaultNodeConfigForCondition = (): Partial => { + return {}; +}; + export type WorkflowNodeConfigForBranch = never; export type WorkflowNodeConfigForEnd = never; @@ -243,15 +283,18 @@ type InitWorkflowOptions = { }; export const initWorkflow = (options: InitWorkflowOptions = {}): WorkflowModel => { - const root = newNode(WorkflowNodeType.Start, {}) as WorkflowNode; - root.config = { trigger: WORKFLOW_TRIGGERS.MANUAL }; + const root = newNode(WorkflowNodeType.Start, { + nodeConfig: { trigger: WORKFLOW_TRIGGERS.MANUAL }, + }); switch (options.template) { case "standard": { let current = root; - const applyNode = newNode(WorkflowNodeType.Apply); + const applyNode = newNode(WorkflowNodeType.Apply, { + nodeConfig: defaultNodeConfigForApply(), + }); current.next = applyNode; current = current.next; @@ -260,6 +303,7 @@ export const initWorkflow = (options: InitWorkflowOptions = {}): WorkflowModel = current = current.next!.branches![1]; current.next = newNode(WorkflowNodeType.Notify, { nodeConfig: { + ...defaultNodeConfigForNotify(), subject: "[Certimate] Workflow Failure Alert!", message: "Your workflow run for the certificate application has failed. Please check the details.", } as WorkflowNodeConfigForNotify, @@ -268,8 +312,8 @@ export const initWorkflow = (options: InitWorkflowOptions = {}): WorkflowModel = current = applyNode.next!.branches![0]; current.next = newNode(WorkflowNodeType.Deploy, { nodeConfig: { + ...defaultNodeConfigForDeploy(), certificate: `${applyNode.id}#certificate`, - skipOnLastSucceeded: true, } as WorkflowNodeConfigForDeploy, }); @@ -279,6 +323,7 @@ export const initWorkflow = (options: InitWorkflowOptions = {}): WorkflowModel = current = current.next!.branches![1]; current.next = newNode(WorkflowNodeType.Notify, { nodeConfig: { + ...defaultNodeConfigForNotify(), subject: "[Certimate] Workflow Failure Alert!", message: "Your workflow run for the certificate deployment has failed. Please check the details.", } as WorkflowNodeConfigForNotify, @@ -290,7 +335,9 @@ export const initWorkflow = (options: InitWorkflowOptions = {}): WorkflowModel = { let current = root; - const monitorNode = newNode(WorkflowNodeType.Monitor); + const monitorNode = newNode(WorkflowNodeType.Monitor, { + nodeConfig: defaultNodeConfigForMonitor(), + }); current.next = monitorNode; current = current.next; @@ -299,6 +346,7 @@ export const initWorkflow = (options: InitWorkflowOptions = {}): WorkflowModel = current = current.next!.branches![1]; current.next = newNode(WorkflowNodeType.Notify, { nodeConfig: { + ...defaultNodeConfigForNotify(), subject: "[Certimate] Workflow Failure Alert!", message: "Your workflow run for the certificate monitoring has failed. Please check the details.", } as WorkflowNodeConfigForNotify, @@ -352,6 +400,7 @@ export const initWorkflow = (options: InitWorkflowOptions = {}): WorkflowModel = } as WorkflowNodeConfigForCondition; current.next = newNode(WorkflowNodeType.Notify, { nodeConfig: { + ...defaultNodeConfigForNotify(), subject: "[Certimate] Certificate Expiry Alert!", message: "The certificate will expire soon. Please pay attention to your website.", } as WorkflowNodeConfigForNotify, @@ -380,6 +429,7 @@ export const initWorkflow = (options: InitWorkflowOptions = {}): WorkflowModel = } as WorkflowNodeConfigForCondition; current.next = newNode(WorkflowNodeType.Notify, { nodeConfig: { + ...defaultNodeConfigForNotify(), subject: "[Certimate] Certificate Expiry Alert!", message: "The certificate has already expired. Please pay attention to your website.", } as WorkflowNodeConfigForNotify,