import { run } from "@/api/workflow"; import Show from "@/components/Show"; import { Button } from "@/components/ui/button"; import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"; import { Switch } from "@/components/ui/switch"; import { Toaster } from "@/components/ui/toaster"; import { useToast } from "@/components/ui/use-toast"; import End from "@/components/workflow/End"; import NodeRender from "@/components/workflow/NodeRender"; import WorkflowBaseInfoEditDialog from "@/components/workflow/WorkflowBaseInfoEditDialog"; import WorkflowLog from "@/components/workflow/WorkflowLog"; import WorkflowProvider from "@/components/workflow/WorkflowProvider"; import { allNodesValidated, WorkflowNode } from "@/domain/workflow"; import { getErrMessage } from "@/lib/error"; import { cn } from "@/lib/utils"; import { useWorkflowStore, WorkflowState } from "@/providers/workflow"; import { ArrowLeft } from "lucide-react"; import { useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { useNavigate, useSearchParams } from "react-router-dom"; import { useShallow } from "zustand/shallow"; const selectState = (state: WorkflowState) => ({ workflow: state.workflow, init: state.init, switchEnable: state.switchEnable, save: state.save, }); const WorkflowDetail = () => { // 3. 使用正确的选择器和 shallow 比较 const { workflow, init, switchEnable, save } = useWorkflowStore(useShallow(selectState)); // 从 url 中获取 workflowId const [searchParams] = useSearchParams(); const [locId, setLocId] = useState(""); const id = searchParams.get("id"); const [tab, setTab] = useState("workflow"); const [running, setRunning] = useState(false); useEffect(() => { console.log(id); init(id ?? ""); if (id) { setLocId(id); } }, [id]); const navigate = useNavigate(); const { toast } = useToast(); const { t } = useTranslation(); const elements = useMemo(() => { let current = workflow.draft as WorkflowNode; const elements: JSX.Element[] = []; while (current) { // 处理普通节点 elements.push(); current = current.next as WorkflowNode; } elements.push(); return elements; }, [workflow]); const handleBackClick = () => { // 返回上一步 navigate(-1); }; const handleEnableChange = () => { if (!workflow.enabled && !allNodesValidated(workflow.draft as WorkflowNode)) { toast({ title: t("workflow.detail.action.save.failed"), description: t("workflow.detail.action.save.failed.uncompleted"), variant: "destructive", }); return; } switchEnable(); }; const handleWorkflowSaveClick = () => { if (!allNodesValidated(workflow.draft as WorkflowNode)) { toast({ title: t("workflow.detail.action.save.failed"), description: t("workflow.detail.action.save.failed.uncompleted"), variant: "destructive", }); return; } save(); }; const getTabCls = (tabName: string) => { if (tab === tabName) { return "text-primary border-primary"; } return "border-transparent hover:text-primary hover:border-b-primary"; }; const handleRunClick = async () => { if (running) { return; } setRunning(true); try { await run(workflow.id as string); toast({ title: t("workflow.detail.action.run.success"), description: t("workflow.detail.action.run.success"), variant: "default", }); } catch (e) { toast({ title: t("workflow.detail.action.run.failed"), description: getErrMessage(e), variant: "destructive", }); } setRunning(false); }; return ( <>
{workflow.name ? workflow.name : t("workflow.props.name.default")}
{workflow.description ? workflow.description : t("workflow.props.description.placeholder")}
} />
{ setTab("workflow"); }} >
{t("workflow.detail.title")}
{ setTab("history"); }} >
{t("workflow.detail.history")}
{running ? t("workflow.detail.action.running") : t("workflow.detail.action.run")} } >
{elements}
); }; export default WorkflowDetail;