diff --git a/ui/src/components/notify/Mail.tsx b/ui/src/components/notify/Mail.tsx index 7b6195fb..ca75125c 100644 --- a/ui/src/components/notify/Mail.tsx +++ b/ui/src/components/notify/Mail.tsx @@ -43,13 +43,13 @@ const Mail = () => { id: config.id ?? "", name: "notifyChannels", data: { - senderAddress: "", - receiverAddresses: "", - smtpHostAddr: "", - smtpHostPort: "25", - username: "", - password: "", - enabled: false, + senderAddress: "", + receiverAddresses: "", + smtpHostAddr: "", + smtpHostPort: "25", + username: "", + password: "", + enabled: false, }, }); @@ -79,13 +79,13 @@ const Mail = () => { const getDetailMail = () => { const df: NotifyChannelMail = { - senderAddress: "", - receiverAddresses: "", - smtpHostAddr: "", - smtpHostPort: "25", - username: "", - password: "", - enabled: false, + senderAddress: "", + receiverAddresses: "", + smtpHostAddr: "", + smtpHostPort: "25", + username: "", + password: "", + enabled: false, }; if (!config.content) { return df; @@ -99,7 +99,14 @@ const Mail = () => { }; const checkChanged = (data: NotifyChannelMail) => { - if (data.senderAddress !== originMail.data.senderAddress || data.receiverAddresses !== originMail.data.receiverAddresses || data.smtpHostAddr !== originMail.data.smtpHostAddr || data.smtpHostPort !== originMail.data.smtpHostPort || data.username !== originMail.data.username || data.password !== originMail.data.password) { + if ( + data.senderAddress !== originMail.data.senderAddress || + data.receiverAddresses !== originMail.data.receiverAddresses || + data.smtpHostAddr !== originMail.data.smtpHostAddr || + data.smtpHostPort !== originMail.data.smtpHostPort || + data.username !== originMail.data.username || + data.password !== originMail.data.password + ) { setChanged(true); } else { setChanged(false); @@ -236,55 +243,55 @@ const Mail = () => { checkChanged(newData.data); setmail(newData); }} - /> - + { - const newData = { + const newData = { ...mail, data: { - ...mail.data, - smtpHostPort: e.target.value, + ...mail.data, + smtpHostPort: e.target.value, }, - }; - checkChanged(newData.data); - setmail(newData); + }; + checkChanged(newData.data); + setmail(newData); }} - /> - + { - const newData = { + const newData = { ...mail, data: { - ...mail.data, - username: e.target.value, + ...mail.data, + username: e.target.value, }, - }; - checkChanged(newData.data); - setmail(newData); + }; + checkChanged(newData.data); + setmail(newData); }} - /> - + { - const newData = { + const newData = { ...mail, data: { - ...mail.data, - password: e.target.value, + ...mail.data, + password: e.target.value, }, - }; - checkChanged(newData.data); - setmail(newData); + }; + checkChanged(newData.data); + setmail(newData); }} - /> + />
diff --git a/ui/src/components/workflow/DeployForm.tsx b/ui/src/components/workflow/DeployForm.tsx index 3e0b7883..d9fce0ef 100644 --- a/ui/src/components/workflow/DeployForm.tsx +++ b/ui/src/components/workflow/DeployForm.tsx @@ -4,15 +4,17 @@ import DeployToAliyunOSS from "./DeployToAliyunOss"; export type DeployFormProps = { data: WorkflowNode; + defaultProivder?: string; }; -const DeployForm = ({ data }: DeployFormProps) => { - return getForm(data); +const DeployForm = ({ data, defaultProivder }: DeployFormProps) => { + return getForm(data, defaultProivder); }; export default memo(DeployForm); -const getForm = (data: WorkflowNode) => { - switch (data.config?.providerType) { +const getForm = (data: WorkflowNode, defaultProivder?: string) => { + const provider = defaultProivder || data.config?.providerType; + switch (provider) { case "aliyun-oss": return ; case "tencent": diff --git a/ui/src/components/workflow/DeployPanelBody.tsx b/ui/src/components/workflow/DeployPanelBody.tsx index 8fcdb589..cd5a9c24 100644 --- a/ui/src/components/workflow/DeployPanelBody.tsx +++ b/ui/src/components/workflow/DeployPanelBody.tsx @@ -22,7 +22,7 @@ const DeployPanelBody = ({ data }: DeployPanelBodyProps) => { return ( <> {/* 默认展示服务商列表 */} - }> + }>
选择服务商
{deployTargets .reduce((acc: DeployTarget[][], provider, index) => { diff --git a/ui/src/components/workflow/DeployToAliyunOss.tsx b/ui/src/components/workflow/DeployToAliyunOss.tsx index 5ce80b7b..130a98b8 100644 --- a/ui/src/components/workflow/DeployToAliyunOss.tsx +++ b/ui/src/components/workflow/DeployToAliyunOss.tsx @@ -105,7 +105,7 @@ const DeployToAliyunOSS = ({ data }: DeployFormProps) => { {item.name} {item.output?.map((output) => ( - +
{item.name}-{output.label}
diff --git a/ui/src/components/workflow/NotifyForm.tsx b/ui/src/components/workflow/NotifyForm.tsx new file mode 100644 index 00000000..66620f87 --- /dev/null +++ b/ui/src/components/workflow/NotifyForm.tsx @@ -0,0 +1,181 @@ +import { WorkflowNode, WorkflowNodeConfig } from "@/domain/workflow"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "../ui/form"; +import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger } from "../ui/select"; +import { Input } from "../ui/input"; +import { useWorkflowStore, WorkflowState } from "@/providers/workflow"; +import { useShallow } from "zustand/shallow"; +import { usePanel } from "./PanelProvider"; +import { useTranslation } from "react-i18next"; +import { Button } from "../ui/button"; +import { useNotifyContext } from "@/providers/notify"; +import { useEffect, useState } from "react"; +import { NotifyChannels, channels as supportedChannels } from "@/domain/settings"; +import { SelectValue } from "@radix-ui/react-select"; +import { Textarea } from "../ui/textarea"; +import { RefreshCw, Settings } from "lucide-react"; + +type NotifyFormProps = { + data: WorkflowNode; +}; + +const selectState = (state: WorkflowState) => ({ + updateNode: state.updateNode, +}); +type ChannelName = { + name: string; + label: string; +}; +const NotifyForm = ({ data }: NotifyFormProps) => { + const { updateNode } = useWorkflowStore(useShallow(selectState)); + const { hidePanel } = usePanel(); + const { t } = useTranslation(); + const { config: notifyConfig, initChannels } = useNotifyContext(); + + const [chanels, setChanels] = useState([]); + + useEffect(() => { + setChanels(getChannels()); + }, [notifyConfig]); + + const getChannels = () => { + const rs: ChannelName[] = []; + if (!notifyConfig.content) { + return rs; + } + + const chanels = notifyConfig.content as NotifyChannels; + for (const channel of supportedChannels) { + if (chanels[channel.name] && chanels[channel.name].enabled) { + rs.push(channel); + } + } + return rs; + }; + + const formSchema = z.object({ + channel: z.string(), + title: z.string().min(1), + content: z.string().min(1), + }); + + let config: WorkflowNodeConfig = { + channel: "", + title: "", + content: "", + }; + + if (data) config = data.config ?? config; + + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { + channel: config.channel as string, + title: config.title as string, + content: config.content as string, + }, + }); + + const onSubmit = (config: z.infer) => { + updateNode({ ...data, config }); + hidePanel(); + }; + + return ( + <> +
+ { + e.stopPropagation(); + form.handleSubmit(onSubmit)(e); + }} + className="space-y-8" + > + ( + + +
+
推送渠道
+ initChannels()} /> +
+ +
设置推送渠道
+
+
+ + + + + +
+ )} + /> + ( + + 标题 + + + + + + + )} + /> + + ( + + 内容 + +