import { useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; import { PageHeader } from "@ant-design/pro-components"; import { Card, Col, Form, Input, type InputRef, Row, Spin, Typography, notification } from "antd"; import { createSchemaFieldRule } from "antd-zod"; import { z } from "zod"; import ModalForm from "@/components/ModalForm"; import { type WorkflowModel, initWorkflow } from "@/domain/workflow"; import { useAntdForm } from "@/hooks"; import { save as saveWorkflow } from "@/repository/workflow"; import { getErrMsg } from "@/utils/error"; const TEMPLATE_KEY_BLANK = "blank" as const; const TEMPLATE_KEY_STANDARD = "standard" as const; type TemplateKeys = typeof TEMPLATE_KEY_BLANK | typeof TEMPLATE_KEY_STANDARD; const WorkflowNew = () => { const navigate = useNavigate(); const { t } = useTranslation(); const [notificationApi, NotificationContextHolder] = notification.useNotification(); const templateGridSpans = { xs: { flex: "100%" }, md: { flex: "100%" }, lg: { flex: "50%" }, xl: { flex: "50%" }, xxl: { flex: "50%" }, }; const [templateSelectKey, setTemplateSelectKey] = useState(); const formSchema = z.object({ name: z .string({ message: t("workflow.new.modal.form.name.placeholder") }) .min(1, t("workflow.new.modal.form.name.placeholder")) .max(64, t("common.errmsg.string_max", { max: 64 })) .trim(), description: z .string({ message: t("workflow.new.modal.form.description.placeholder") }) .max(256, t("common.errmsg.string_max", { max: 256 })) .trim() .nullish(), }); const formRule = createSchemaFieldRule(formSchema); const { form: formInst, formPending, formProps, submit: submitForm, } = useAntdForm>({ onSubmit: async (values) => { try { let workflow: WorkflowModel; switch (templateSelectKey) { case TEMPLATE_KEY_BLANK: workflow = initWorkflow(); break; case TEMPLATE_KEY_STANDARD: workflow = initWorkflow({ template: "standard" }); break; default: throw "Invalid state: `templateSelectKey`"; } workflow.name = values.name?.trim() ?? workflow.name; workflow.description = values.description?.trim() ?? workflow.description; workflow = await saveWorkflow(workflow); navigate(`/workflows/${workflow.id}`, { replace: true }); } catch (err) { notificationApi.error({ message: t("common.text.request_error"), description: getErrMsg(err) }); throw err; } }, }); const [formModalOpen, setFormModalOpen] = useState(false); useEffect(() => { if (formModalOpen) { setTimeout(() => inputRef.current?.focus({ cursor: "end" }), 1); } else { setTemplateSelectKey(undefined); formInst.resetFields(); } }, [formModalOpen]); const inputRef = useRef(null); const handleTemplateClick = (key: TemplateKeys) => { setTemplateSelectKey(key); setFormModalOpen(true); }; const handleModalOpenChange = (open: boolean) => { setFormModalOpen(open); }; const handleModalFormFinish = () => { return submitForm(); }; return (
{NotificationContextHolder} {t("workflow.new.subtitle")}
{t("workflow.new.templates.title")}
} hoverable onClick={() => handleTemplateClick(TEMPLATE_KEY_STANDARD)} >
} hoverable onClick={() => handleTemplateClick(TEMPLATE_KEY_BLANK)} >
); }; export default WorkflowNew;