import { forwardRef, memo, useEffect, useImperativeHandle, useState } from "react"; import { useTranslation } from "react-i18next"; import { Alert, Form, type FormInstance, Input, Radio } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import dayjs from "dayjs"; import { z } from "zod"; import Show from "@/components/Show"; import { WORKFLOW_TRIGGERS, type WorkflowNodeConfigForStart, type WorkflowTriggerType } from "@/domain/workflow"; import { useAntdForm } from "@/hooks"; import { getNextCronExecutions, validCronExpression } from "@/utils/cron"; type StartNodeConfigFormFieldValues = Partial; export type StartNodeConfigFormProps = { className?: string; style?: React.CSSProperties; disabled?: boolean; initialValues?: StartNodeConfigFormFieldValues; onValuesChange?: (values: StartNodeConfigFormFieldValues) => void; }; export type StartNodeConfigFormInstance = { getFieldsValue: () => ReturnType["getFieldsValue"]>; resetFields: FormInstance["resetFields"]; validateFields: FormInstance["validateFields"]; }; const initFormModel = (): StartNodeConfigFormFieldValues => { return { trigger: WORKFLOW_TRIGGERS.AUTO, triggerCron: "0 0 * * *", }; }; const StartNodeConfigForm = forwardRef( ({ className, style, disabled, initialValues, onValuesChange }, ref) => { const { t } = useTranslation(); const formSchema = z .object({ trigger: z.string({ message: t("workflow_node.start.form.trigger.placeholder") }).min(1, t("workflow_node.start.form.trigger.placeholder")), triggerCron: z.string().nullish(), }) .superRefine((data, ctx) => { if (data.trigger !== WORKFLOW_TRIGGERS.AUTO) { return; } if (!validCronExpression(data.triggerCron!)) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: t("workflow_node.start.form.trigger_cron.errmsg.invalid"), path: ["triggerCron"], }); } }); const formRule = createSchemaFieldRule(formSchema); const { form: formInst, formProps } = useAntdForm({ name: "workflowNodeStartConfigForm", initialValues: initialValues ?? initFormModel(), }); const fieldTrigger = Form.useWatch("trigger", formInst); const fieldTriggerCron = Form.useWatch("triggerCron", formInst); const [fieldTriggerCronExpectedExecutions, setFieldTriggerCronExpectedExecutions] = useState([]); useEffect(() => { setFieldTriggerCronExpectedExecutions(getNextCronExecutions(fieldTriggerCron, 5)); }, [fieldTriggerCron]); const handleTriggerChange = (value: string) => { if (value === WORKFLOW_TRIGGERS.AUTO) { formInst.setFieldValue("triggerCron", formProps.initialValues?.triggerCron || initFormModel().triggerCron); } else { formInst.setFieldValue("triggerCron", undefined); } onValuesChange?.(formInst.getFieldsValue(true)); }; const handleFormChange = (_: unknown, values: z.infer) => { onValuesChange?.(values as StartNodeConfigFormFieldValues); }; useImperativeHandle(ref, () => { return { getFieldsValue: () => { return formInst.getFieldsValue(true); }, resetFields: (fields) => { return formInst.resetFields(fields); }, validateFields: (nameList, config) => { return formInst.validateFields(nameList, config); }, } as StartNodeConfigFormInstance; }); return (
} > handleTriggerChange(e.target.value)}> {t("workflow_node.start.form.trigger.option.auto.label")} {t("workflow_node.start.form.trigger.option.manual.label")} } />
); } ); export default memo(StartNodeConfigForm);