workflow multi languages

This commit is contained in:
yoan 2024-11-11 15:50:36 +08:00
parent 327c83cbc8
commit 1ea0ba18cd
32 changed files with 312 additions and 152 deletions

View File

@ -19,6 +19,7 @@ import {
} from "../ui/dropdown-menu";
import DropdownMenuItemIcon from "./DropdownMenuItemIcon";
import Show from "../Show";
import { useTranslation } from "react-i18next";
const selectState = (state: WorkflowState) => ({
addNode: state.addNode,
@ -26,6 +27,7 @@ const selectState = (state: WorkflowState) => ({
const AddNode = ({ data }: NodeProps | BrandNodeProps) => {
const { addNode } = useWorkflowStore(useShallow(selectState));
const { t } = useTranslation();
const handleTypeSelected = (type: WorkflowNodeType, provider?: string) => {
const node = newWorkflowNode(type, {
@ -44,7 +46,7 @@ const AddNode = ({ data }: NodeProps | BrandNodeProps) => {
</div>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel></DropdownMenuLabel>
<DropdownMenuLabel>{t("workflow.node.selectNodeType.label")}</DropdownMenuLabel>
<DropdownMenuSeparator />
{workflowNodeDropdownList.map((item) => (
<Show

View File

@ -82,7 +82,7 @@ const ApplyForm = ({ data }: ApplyFormProps) => {
});
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config });
updateNode({ ...data, config, validated: true });
hidePanel();
};

View File

@ -6,6 +6,7 @@ import { memo } from "react";
import { BrandNodeProps } from "./types";
import { useWorkflowStore, WorkflowState } from "@/providers/workflow";
import { useShallow } from "zustand/shallow";
import { useTranslation } from "react-i18next";
const selectState = (state: WorkflowState) => ({
addBranch: state.addBranch,
@ -13,6 +14,8 @@ const selectState = (state: WorkflowState) => ({
const BranchNode = memo(({ data }: BrandNodeProps) => {
const { addBranch } = useWorkflowStore(useShallow(selectState));
const { t } = useTranslation();
const renderNodes = (node: WorkflowBranchNode | WorkflowNode | undefined, branchNodeId?: string, branchIndex?: number) => {
const elements: JSX.Element[] = [];
let current = node;
@ -34,7 +37,7 @@ const BranchNode = memo(({ data }: BrandNodeProps) => {
variant={"outline"}
className="text-xs px-2 h-6 rounded-full absolute -top-3 left-[50%] -translate-x-1/2 z-10"
>
{t("workflow.node.addBranch.label")}
</Button>
{data.branches.map((branch, index) => (

View File

@ -74,8 +74,10 @@ const DeployToAliyunALB = ({ data }: DeployFormProps) => {
},
});
const resourceType = form.watch("resourceType");
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -94,7 +96,7 @@ const DeployToAliyunALB = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -104,7 +106,7 @@ const DeployToAliyunALB = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (
@ -174,7 +176,7 @@ const DeployToAliyunALB = ({ data }: DeployFormProps) => {
</FormItem>
)}
/>
{resourceType === "loadbalancer" && (
<FormField
control={form.control}
name="loadbalancerId"
@ -189,7 +191,9 @@ const DeployToAliyunALB = ({ data }: DeployFormProps) => {
</FormItem>
)}
/>
)}
{resourceType === "listener" && (
<FormField
control={form.control}
name="listenerId"
@ -204,6 +208,7 @@ const DeployToAliyunALB = ({ data }: DeployFormProps) => {
</FormItem>
)}
/>
)}
<div className="flex justify-end">
<Button type="submit">{t("common.save")}</Button>

View File

@ -59,7 +59,7 @@ const DeployToAliyunCDN = ({ data }: DeployFormProps) => {
});
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -78,7 +78,7 @@ const DeployToAliyunCDN = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -88,7 +88,7 @@ const DeployToAliyunCDN = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (

View File

@ -74,8 +74,10 @@ const DeployToAliyunCLB = ({ data }: DeployFormProps) => {
},
});
const resouceType = form.watch("resourceType");
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -94,7 +96,7 @@ const DeployToAliyunCLB = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -104,7 +106,7 @@ const DeployToAliyunCLB = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (
@ -190,6 +192,7 @@ const DeployToAliyunCLB = ({ data }: DeployFormProps) => {
)}
/>
{resouceType === "listener" && (
<FormField
control={form.control}
name="listenerPort"
@ -204,6 +207,7 @@ const DeployToAliyunCLB = ({ data }: DeployFormProps) => {
</FormItem>
)}
/>
)}
<div className="flex justify-end">
<Button type="submit">{t("common.save")}</Button>

View File

@ -74,8 +74,10 @@ const DeployToAliyunNLB = ({ data }: DeployFormProps) => {
},
});
const resourceType = form.watch("resourceType");
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -94,7 +96,7 @@ const DeployToAliyunNLB = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -104,7 +106,7 @@ const DeployToAliyunNLB = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (
@ -175,6 +177,7 @@ const DeployToAliyunNLB = ({ data }: DeployFormProps) => {
)}
/>
{resourceType === "loadbalancer" && (
<FormField
control={form.control}
name="loadbalancerId"
@ -189,7 +192,9 @@ const DeployToAliyunNLB = ({ data }: DeployFormProps) => {
</FormItem>
)}
/>
)}
{resourceType === "listener" && (
<FormField
control={form.control}
name="listenerId"
@ -204,6 +209,7 @@ const DeployToAliyunNLB = ({ data }: DeployFormProps) => {
</FormItem>
)}
/>
)}
<div className="flex justify-end">
<Button type="submit">{t("common.save")}</Button>

View File

@ -68,7 +68,7 @@ const DeployToAliyunOSS = ({ data }: DeployFormProps) => {
});
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -87,7 +87,7 @@ const DeployToAliyunOSS = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -97,7 +97,7 @@ const DeployToAliyunOSS = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (

View File

@ -59,7 +59,7 @@ const DeployToBaiduCloudCDN = ({ data }: DeployFormProps) => {
});
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -78,7 +78,7 @@ const DeployToBaiduCloudCDN = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -88,7 +88,7 @@ const DeployToBaiduCloudCDN = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (

View File

@ -59,7 +59,7 @@ const DeployToDogeCloudCDN = ({ data }: DeployFormProps) => {
});
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -78,7 +78,7 @@ const DeployToDogeCloudCDN = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -88,7 +88,7 @@ const DeployToDogeCloudCDN = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (

View File

@ -63,7 +63,7 @@ const DeployToHuaweiCloudCDN = ({ data }: DeployFormProps) => {
});
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -82,7 +82,7 @@ const DeployToHuaweiCloudCDN = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -92,7 +92,7 @@ const DeployToHuaweiCloudCDN = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (

View File

@ -86,7 +86,7 @@ const DeployToHuaweiCloudELB = ({ data }: DeployFormProps) => {
});
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -105,7 +105,7 @@ const DeployToHuaweiCloudELB = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -115,7 +115,7 @@ const DeployToHuaweiCloudELB = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (

View File

@ -73,7 +73,7 @@ const DeployToKubernetesSecret = ({ data }: DeployFormProps) => {
});
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -92,7 +92,7 @@ const DeployToKubernetesSecret = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -102,7 +102,7 @@ const DeployToKubernetesSecret = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (

View File

@ -114,7 +114,7 @@ const DeployToLocal = ({ data }: DeployFormProps) => {
}, [format]);
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config });
updateNode({ ...data, config, validated: true });
hidePanel();
};
@ -203,7 +203,7 @@ Remove-Item -Path "$pfxPath" -Force
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -213,7 +213,7 @@ Remove-Item -Path "$pfxPath" -Force
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (

View File

@ -59,7 +59,7 @@ const DeployToQiniuCDN = ({ data }: DeployFormProps) => {
});
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -78,7 +78,7 @@ const DeployToQiniuCDN = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -88,7 +88,7 @@ const DeployToQiniuCDN = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (

View File

@ -109,7 +109,7 @@ const DeployToSSH = ({ data }: DeployFormProps) => {
}, [format]);
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config });
updateNode({ ...data, config, validated: true });
hidePanel();
};
@ -121,7 +121,7 @@ const DeployToSSH = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -131,7 +131,7 @@ const DeployToSSH = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (

View File

@ -59,7 +59,7 @@ const DeployToTencentCDN = ({ data }: DeployFormProps) => {
});
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -78,7 +78,7 @@ const DeployToTencentCDN = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -88,7 +88,7 @@ const DeployToTencentCDN = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (

View File

@ -98,7 +98,7 @@ const DeployToTencentCLB = ({ data }: DeployFormProps) => {
});
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -117,7 +117,7 @@ const DeployToTencentCLB = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -127,7 +127,7 @@ const DeployToTencentCLB = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (

View File

@ -64,7 +64,7 @@ const DeployToTencentCOS = ({ data }: DeployFormProps) => {
});
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -83,7 +83,7 @@ const DeployToTencentCOS = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -93,7 +93,7 @@ const DeployToTencentCOS = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (

View File

@ -61,7 +61,7 @@ const DeployToTencentTEO = ({ data }: DeployFormProps) => {
});
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -80,7 +80,7 @@ const DeployToTencentTEO = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -90,7 +90,7 @@ const DeployToTencentTEO = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (

View File

@ -62,7 +62,7 @@ const DeployToWebhook = ({ data }: DeployFormProps) => {
const onSubmit = async (config: z.infer<typeof formSchema>) => {
console.log(config);
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -81,7 +81,7 @@ const DeployToWebhook = ({ data }: DeployFormProps) => {
name="certificate"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t("workflow.common.certificate.label")}</FormLabel>
<FormControl>
<Select
{...field}
@ -91,7 +91,7 @@ const DeployToWebhook = ({ data }: DeployFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择证书来源" />
<SelectValue placeholder={t("workflow.common.certificate.placeholder")} />
</SelectTrigger>
<SelectContent>
{beforeOutput.map((item) => (

View File

@ -1,8 +1,11 @@
import { useTranslation } from "react-i18next";
const End = () => {
const { t } = useTranslation();
return (
<div className="flex flex-col items-center">
<div className="h-[18px] rounded-full w-[18px] bg-stone-400"></div>
<div className="text-sm text-stone-400 mt-2"></div>
<div className="text-sm text-stone-400 mt-2">{t("workflow.node.end.title")}</div>
</div>
);
};

View File

@ -6,11 +6,17 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigge
import { Ellipsis, Trash2 } from "lucide-react";
import { usePanel } from "./PanelProvider";
import PanelBody from "./PanelBody";
import { useTranslation } from "react-i18next";
import Show from "../Show";
import { deployTargetsMap } from "@/domain/domain";
import { channelLabelMap } from "@/domain/settings";
type NodeProps = {
data: WorkflowNode;
};
const i18nPrefix = "workflow.node";
const selectState = (state: WorkflowState) => ({
updateNode: state.updateNode,
removeNode: state.removeNode,
@ -23,12 +29,61 @@ const Node = ({ data }: NodeProps) => {
const { showPanel } = usePanel();
const { t } = useTranslation();
const handleNodeSettingClick = () => {
showPanel({
name: data.name,
children: <PanelBody data={data} />,
});
};
const getSetting = () => {
console.log(data);
if (!data.validated) {
return <>{t(`${i18nPrefix}.setting.label`)}</>;
}
switch (data.type) {
case WorkflowNodeType.Start:
return (
<div className="flex space-x-2 items-baseline">
<div className="text-stone-700">
<Show when={data.config?.executionMethod == "auto"} fallback={<>{t(`workflow.node.start.form.executionMethod.options.manual`)}</>}>
{t(`workflow.node.start.form.executionMethod.options.auto`) + ":"}
</Show>
</div>
<Show when={data.config?.executionMethod == "auto"}>
<div className="text-muted-foreground">{data.config?.crontab as string}</div>
</Show>
</div>
);
case WorkflowNodeType.Apply:
return <div className="text-muted-foreground truncate">{data.config?.domain as string}</div>;
case WorkflowNodeType.Deploy: {
const provider = deployTargetsMap.get(data.config?.providerType as string);
return (
<div className="flex space-x-2 items-center text-muted-foreground">
<img src={provider?.icon} className="w-6 h-6" />
<div>{t(provider?.name ?? "")}</div>
</div>
);
}
case WorkflowNodeType.Notify: {
const channelLabel = channelLabelMap.get(data.config?.channel as string);
return (
<div className="flex space-x-2 items-baseline">
<div className="text-stone-700">{t(channelLabel?.label ?? "")}</div>
<div className="text-muted-foreground truncate">{(data.config?.title as string) ?? ""}</div>
</div>
);
}
default:
return <>{t(`${i18nPrefix}.setting.label`)}</>;
}
};
return (
<>
<div className="rounded-md shadow-md w-[260px] relative">
@ -45,7 +100,7 @@ const Node = ({ data }: NodeProps) => {
removeNode(data.id);
}}
>
<Trash2 size={16} /> <div></div>
<Trash2 size={16} /> <div>{t(`${i18nPrefix}.delete.label`)}</div>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
@ -64,7 +119,7 @@ const Node = ({ data }: NodeProps) => {
</div>
<div className="p-2 text-sm text-primary flex flex-col justify-center bg-white">
<div className="leading-7 text-primary cursor-pointer" onClick={handleNodeSettingClick}>
{getSetting()}
</div>
</div>
</div>

View File

@ -28,6 +28,8 @@ type ChannelName = {
name: string;
label: string;
};
const i18nPrefix = "workflow.node.notify.form";
const NotifyForm = ({ data }: NotifyFormProps) => {
const { updateNode } = useWorkflowStore(useShallow(selectState));
const { hidePanel } = usePanel();
@ -79,7 +81,7 @@ const NotifyForm = ({ data }: NotifyFormProps) => {
});
const onSubmit = (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config });
updateNode({ ...data, config, validated: true });
hidePanel();
};
@ -100,7 +102,7 @@ const NotifyForm = ({ data }: NotifyFormProps) => {
<FormItem>
<FormLabel className="flex justify-between items-center">
<div className="flex space-x-2 items-center">
<div></div>
<div>{t(`${i18nPrefix}.channel.label`)}</div>
<RefreshCw size={16} className="cursor-pointer" onClick={() => initChannels()} />
</div>
<a
@ -108,7 +110,7 @@ const NotifyForm = ({ data }: NotifyFormProps) => {
target="_blank"
className="flex justify-between items-center space-x-1 font-normal text-primary hover:underline cursor-pointer"
>
<Settings size={16} /> <div></div>
<Settings size={16} /> <div>{t(`${i18nPrefix}.settingChannel.label`)}</div>
</a>
</FormLabel>
<FormControl>
@ -120,7 +122,7 @@ const NotifyForm = ({ data }: NotifyFormProps) => {
}}
>
<SelectTrigger>
<SelectValue placeholder="选择推送渠道" />
<SelectValue placeholder={t(`${i18nPrefix}.channel.placeholder`)} />
</SelectTrigger>
<SelectContent>
<SelectGroup>
@ -143,9 +145,9 @@ const NotifyForm = ({ data }: NotifyFormProps) => {
name="title"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t(`${i18nPrefix}.title.label`)}</FormLabel>
<FormControl>
<Input placeholder="请输入消息标题" {...field} />
<Input placeholder={t(`${i18nPrefix}.title.placeholder`)} {...field} />
</FormControl>
<FormMessage />
@ -158,9 +160,9 @@ const NotifyForm = ({ data }: NotifyFormProps) => {
name="content"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t(`${i18nPrefix}.content.label`)}</FormLabel>
<FormControl>
<Textarea placeholder="请输入消息内容" {...field} />
<Textarea placeholder={t(`${i18nPrefix}.content.placeholder`)} {...field} />
</FormControl>
<FormMessage />

View File

@ -38,6 +38,8 @@ type StartFormProps = {
data: WorkflowNode;
};
const i18nPrefix = "workflow.node.start.form";
const selectState = (state: WorkflowState) => ({
updateNode: state.updateNode,
});
@ -72,7 +74,7 @@ const StartForm = ({ data }: StartFormProps) => {
});
const onSubmit = async (config: z.infer<typeof formSchema>) => {
updateNode({ ...data, config: { ...config } });
updateNode({ ...data, config: { ...config }, validated: true });
hidePanel();
};
@ -91,7 +93,7 @@ const StartForm = ({ data }: StartFormProps) => {
name="executionMethod"
render={({ field }) => (
<FormItem>
<FormLabel></FormLabel>
<FormLabel>{t(`${i18nPrefix}.executionMethod.label`)}</FormLabel>
<FormControl>
<RadioGroup
{...field}
@ -103,11 +105,11 @@ const StartForm = ({ data }: StartFormProps) => {
>
<div className="flex items-center space-x-2">
<RadioGroupItem value="auto" id="option-one" />
<Label htmlFor="option-one"></Label>
<Label htmlFor="option-one">{t(`${i18nPrefix}.executionMethod.options.auto`)}</Label>
</div>
<div className="flex items-center space-x-2">
<RadioGroupItem value="manual" id="option-two" />
<Label htmlFor="option-two"></Label>
<Label htmlFor="option-two">{t(`${i18nPrefix}.executionMethod.options.manual`)}</Label>
</div>
</RadioGroup>
</FormControl>
@ -122,9 +124,9 @@ const StartForm = ({ data }: StartFormProps) => {
name="crontab"
render={({ field }) => (
<FormItem hidden={method == "manual"}>
<FormLabel></FormLabel>
<FormLabel>{t(`${i18nPrefix}.crontab.label`)}</FormLabel>
<FormControl>
<Input {...field} />
<Input {...field} placeholder={t(`${i18nPrefix}.crontab.placeholder`)} />
</FormControl>
<FormMessage />

View File

@ -98,4 +98,3 @@ export const deployTargetsMap: Map<DeployTarget["type"], DeployTarget> = new Map
);
export const deployTargets = deployTargetList.map(([type, name, icon]) => ({ type, provider: type.split("-")[0], name, icon }));

View File

@ -30,7 +30,11 @@ export type NotifyChannel =
| NotifyChannelMail
| NotifyChannelBark;
export const channels = [
type ChannelLabel = {
name: string;
label: string;
};
export const channels: ChannelLabel[] = [
{
name: "dingtalk",
label: "common.provider.dingtalk",
@ -61,6 +65,8 @@ export const channels = [
},
];
export const channelLabelMap: Map<string, ChannelLabel> = new Map(channels.map((item) => [item.name, item]));
export type NotifyChannelDingTalk = {
accessToken: string;
secret: string;

View File

@ -14,15 +14,17 @@ export enum WorkflowNodeType {
Custom = "custom",
}
const i18nPrefix = "workflow.node";
export const workflowNodeTypeDefaultName: Map<WorkflowNodeType, string> = new Map([
[WorkflowNodeType.Start, "开始"],
[WorkflowNodeType.End, "结束"],
[WorkflowNodeType.Branch, "分支"],
[WorkflowNodeType.Condition, "分支"],
[WorkflowNodeType.Apply, "申请"],
[WorkflowNodeType.Deploy, "部署"],
[WorkflowNodeType.Notify, "通知"],
[WorkflowNodeType.Custom, "自定义"],
[WorkflowNodeType.Start, i18n.t(`${i18nPrefix}.start.title`)],
[WorkflowNodeType.End, i18n.t(`${i18nPrefix}.end.title`)],
[WorkflowNodeType.Branch, i18n.t(`${i18nPrefix}.branch.title`)],
[WorkflowNodeType.Condition, i18n.t(`${i18nPrefix}.condition.title`)],
[WorkflowNodeType.Apply, i18n.t(`${i18nPrefix}.apply.title`)],
[WorkflowNodeType.Deploy, i18n.t(`${i18nPrefix}.deploy.title`)],
[WorkflowNodeType.Notify, i18n.t(`${i18nPrefix}.notify.title`)],
[WorkflowNodeType.Custom, i18n.t(`${i18nPrefix}.custom.title`)],
]);
export type WorkflowNodeIo = {
@ -48,7 +50,7 @@ export const workflowNodeTypeDefaultInput: Map<WorkflowNodeType, WorkflowNodeIo[
name: "certificate",
type: " certificate",
required: true,
label: "证书",
label: i18n.t("workflow.common.certificate.label"),
},
],
],
@ -63,7 +65,7 @@ export const workflowNodeTypeDefaultOutput: Map<WorkflowNodeType, WorkflowNodeIo
name: "certificate",
type: "certificate",
required: true,
label: "证书",
label: i18n.t("workflow.common.certificate.label"),
},
],
],
@ -77,6 +79,7 @@ export type WorkflowNode = {
id: string;
name: string;
type: WorkflowNodeType;
validated?: boolean;
input?: WorkflowNodeIo[];
config?: WorkflowNodeConfig;

View File

@ -5,6 +5,7 @@ import nlsSettings from "./nls.settings.json";
import nlsDomain from "./nls.domain.json";
import nlsAccess from "./nls.access.json";
import nlsHistory from "./nls.history.json";
import nlsWorkflow from "./nls.workflow.json";
export default Object.freeze({
...nlsCommon,
@ -14,4 +15,5 @@ export default Object.freeze({
...nlsDomain,
...nlsAccess,
...nlsHistory,
...nlsWorkflow,
});

View File

@ -0,0 +1,33 @@
{
"workflow.common.certificate.label": "Certificate",
"workflow.common.certificate.placeholder": "Please select certificate source",
"workflow.node.start.title": "Start",
"workflow.node.apply.title": "Apply",
"workflow.node.deploy.title": "Deploy",
"workflow.node.branch.title": "Branch",
"workflow.node.condition.title": "Branch",
"workflow.node.end.title": "End",
"workflow.node.notify.title": "Notify",
"workflow.node.setting.label": "Setting Node",
"workflow.node.delete.label": "Delete Node",
"workflow.node.addBranch.label": "Add Branch",
"workflow.node.selectNodeType.label": "Select Node Type",
"workflow.node.start.form.executionMethod.label": "Execution Method",
"workflow.node.start.form.executionMethod.placeholder": "Please select execution method",
"workflow.node.start.form.executionMethod.options.manual": "Manual",
"workflow.node.start.form.executionMethod.options.auto": "Auto",
"workflow.node.start.form.crontab.label": "Crontab",
"workflow.node.start.form.crontab.placeholder": "Please enter crontab",
"workflow.node.notify.form.title.label": "Title",
"workflow.node.notify.form.title.placeholder": "Please enter title",
"workflow.node.notify.form.content.label": "Content",
"workflow.node.notify.form.content.placeholder": "Please enter content",
"workflow.node.notify.form.channel.label": "Channel",
"workflow.node.notify.form.channel.placeholder": "Please select channel",
"workflow.node.notify.form.settingChannel.label": "Setting Channel"
}

View File

@ -5,6 +5,7 @@ import nlsSettings from "./nls.settings.json";
import nlsDomain from "./nls.domain.json";
import nlsAccess from "./nls.access.json";
import nlsHistory from "./nls.history.json";
import nlsWorkflow from "./nls.workflow.json";
export default Object.freeze({
...nlsCommon,
@ -14,4 +15,5 @@ export default Object.freeze({
...nlsDomain,
...nlsAccess,
...nlsHistory,
...nlsWorkflow,
});

View File

@ -0,0 +1,33 @@
{
"workflow.common.certificate.label": "证书",
"workflow.common.certificate.placeholder": "请选择证书来源",
"workflow.node.start.title": "开始",
"workflow.node.apply.title": "申请",
"workflow.node.deploy.title": "部署",
"workflow.node.branch.title": "分支",
"workflow.node.condition.title": "分支",
"workflow.node.end.title": "流程结束",
"workflow.node.notify.title": "通知",
"workflow.node.setting.label": "设置节点",
"workflow.node.delete.label": "删除节点",
"workflow.node.addBranch.label": "添加分支",
"workflow.node.selectNodeType.label": "选择节点类型",
"workflow.node.start.form.executionMethod.label": "执行方式",
"workflow.node.start.form.executionMethod.placeholder": "请选择执行方式",
"workflow.node.start.form.executionMethod.options.manual": "手动",
"workflow.node.start.form.executionMethod.options.auto": "自动",
"workflow.node.start.form.crontab.label": "定时表达式",
"workflow.node.start.form.crontab.placeholder": "请输入定时表达式",
"workflow.node.notify.form.title.label": "标题",
"workflow.node.notify.form.title.placeholder": "请输入标题",
"workflow.node.notify.form.content.label": "内容",
"workflow.node.notify.form.content.placeholder": "请输入内容",
"workflow.node.notify.form.channel.label": "推送渠道",
"workflow.node.notify.form.channel.placeholder": "请选择推送渠道",
"workflow.node.notify.form.settingChannel.label": "设置推送渠道"
}