From 849e065bb2f9fb4aa942ae4fde0d5e0115e45123 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Fri, 3 Jan 2025 21:51:40 +0800 Subject: [PATCH] refactor(ui): clean code --- ui/.eslintrc.cjs | 1 + ui/src/components/DrawerForm.tsx | 4 +- ui/src/components/ModalForm.tsx | 4 +- ui/src/components/workflow/PanelProvider.tsx | 7 +- .../components/workflow/WorkflowElements.tsx | 2 +- ui/src/components/workflow/node/AddNode.tsx | 71 ++++++-------- .../components/workflow/node/BranchNode.tsx | 2 +- .../workflow/node/ConditionNode.tsx | 10 +- .../workflow/{ => node}/NodeRender.tsx | 17 ++-- ui/src/components/workflow/types.ts | 17 ---- ui/src/domain/settings.ts | 2 +- ui/src/domain/workflow.ts | 94 ++++++++----------- ui/src/hooks/useAntdForm.ts | 10 +- ui/src/stores/workflow/index.ts | 5 +- 14 files changed, 103 insertions(+), 143 deletions(-) rename ui/src/components/workflow/{ => node}/NodeRender.tsx (66%) delete mode 100644 ui/src/components/workflow/types.ts diff --git a/ui/.eslintrc.cjs b/ui/.eslintrc.cjs index 8dfca5e2..e96e20b7 100644 --- a/ui/.eslintrc.cjs +++ b/ui/.eslintrc.cjs @@ -93,6 +93,7 @@ module.exports = { ignoreDeclarationSort: true, }, ], + "tailwindcss/no-custom-classname": "off", }, settings: { "import/resolver": { diff --git a/ui/src/components/DrawerForm.tsx b/ui/src/components/DrawerForm.tsx index 1e4bb958..121f2e83 100644 --- a/ui/src/components/DrawerForm.tsx +++ b/ui/src/components/DrawerForm.tsx @@ -4,7 +4,7 @@ import { Button, Drawer, type DrawerProps, Form, type FormProps, type ModalProps import { useAntdForm, useTriggerElement } from "@/hooks"; -export interface DrawerFormProps = NonNullable> extends Omit, "title" | "onFinish"> { +export interface DrawerFormProps = any> extends Omit, "title" | "onFinish"> { className?: string; style?: React.CSSProperties; children?: React.ReactNode; @@ -22,7 +22,7 @@ export interface DrawerFormProps = NonNullable void | Promise; } -const DrawerForm = = NonNullable>({ +const DrawerForm = = any>({ className, style, children, diff --git a/ui/src/components/ModalForm.tsx b/ui/src/components/ModalForm.tsx index 2962a278..c685bb69 100644 --- a/ui/src/components/ModalForm.tsx +++ b/ui/src/components/ModalForm.tsx @@ -3,7 +3,7 @@ import { Form, type FormProps, Modal, type ModalProps } from "antd"; import { useAntdForm, useTriggerElement } from "@/hooks"; -export interface ModalFormProps = NonNullable> extends Omit, "title" | "onFinish"> { +export interface ModalFormProps = any> extends Omit, "title" | "onFinish"> { className?: string; style?: React.CSSProperties; children?: React.ReactNode; @@ -35,7 +35,7 @@ export interface ModalFormProps = NonNullable void | Promise; } -const ModalForm = = NonNullable>({ +const ModalForm = = any>({ className, style, children, diff --git a/ui/src/components/workflow/PanelProvider.tsx b/ui/src/components/workflow/PanelProvider.tsx index dfbb032f..eb8ed998 100644 --- a/ui/src/components/workflow/PanelProvider.tsx +++ b/ui/src/components/workflow/PanelProvider.tsx @@ -4,13 +4,13 @@ import Panel from "./Panel"; type PanelContentProps = { name: string; children: React.ReactNode }; -type PanelContextType = { +type PanelContextProps = { open: boolean; showPanel: ({ name, children }: PanelContentProps) => void; hidePanel: () => void; }; -const PanelContext = createContext(undefined); +const PanelContext = createContext(undefined); export const PanelProvider = ({ children }: { children: React.ReactNode }) => { const [open, setOpen] = useState(false); @@ -20,6 +20,7 @@ export const PanelProvider = ({ children }: { children: React.ReactNode }) => { setOpen(true); setPanelContent(panelContent); }; + const hidePanel = () => { setOpen(false); setPanelContent(null); @@ -36,7 +37,7 @@ export const PanelProvider = ({ children }: { children: React.ReactNode }) => { export const usePanel = () => { const context = useContext(PanelContext); if (!context) { - throw new Error("useDialog must be used within DialogProvider"); + throw new Error("`usePanel` must be used within PanelProvider"); } return context; }; diff --git a/ui/src/components/workflow/WorkflowElements.tsx b/ui/src/components/workflow/WorkflowElements.tsx index 9f9b9791..201faf47 100644 --- a/ui/src/components/workflow/WorkflowElements.tsx +++ b/ui/src/components/workflow/WorkflowElements.tsx @@ -1,8 +1,8 @@ import { useMemo } from "react"; -import NodeRender from "@/components/workflow/NodeRender"; import WorkflowProvider from "@/components/workflow/WorkflowProvider"; import EndNode from "@/components/workflow/node/EndNode"; +import NodeRender from "@/components/workflow/node/NodeRender"; import { type WorkflowNode } from "@/domain/workflow"; import { useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; diff --git a/ui/src/components/workflow/node/AddNode.tsx b/ui/src/components/workflow/node/AddNode.tsx index 6290104c..2426eb63 100644 --- a/ui/src/components/workflow/node/AddNode.tsx +++ b/ui/src/components/workflow/node/AddNode.tsx @@ -1,3 +1,5 @@ +import { useMemo } from "react"; +import { useTranslation } from "react-i18next"; import { CloudUploadOutlined as CloudUploadOutlinedIcon, PlusOutlined as PlusOutlinedIcon, @@ -7,60 +9,45 @@ import { } from "@ant-design/icons"; import { Dropdown } from "antd"; -import { WorkflowNodeType, newNode, workflowNodeTypeDefaultNames } from "@/domain/workflow"; +import { type WorkflowNode, WorkflowNodeType, newNode } from "@/domain/workflow"; import { useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; -import { type BrandNodeProps, type NodeProps } from "../types"; +export type AddNodeProps = { + node: WorkflowNode; +}; -const dropdownMenus = [ - { - type: WorkflowNodeType.Apply, - label: workflowNodeTypeDefaultNames.get(WorkflowNodeType.Apply), - icon: , - }, - { - type: WorkflowNodeType.Deploy, - label: workflowNodeTypeDefaultNames.get(WorkflowNodeType.Deploy), - icon: , - }, - { - type: WorkflowNodeType.Branch, - label: workflowNodeTypeDefaultNames.get(WorkflowNodeType.Branch), - icon: , - }, - { - type: WorkflowNodeType.Notify, - label: workflowNodeTypeDefaultNames.get(WorkflowNodeType.Notify), - icon: , - }, -]; +const AddNode = ({ node }: AddNodeProps) => { + const { t } = useTranslation(); -const AddNode = ({ node: supnode }: NodeProps | BrandNodeProps) => { const { addNode } = useWorkflowStore(useZustandShallowSelector(["addNode"])); + const dropdownMenus = useMemo(() => { + return [ + [WorkflowNodeType.Apply, "workflow_node.apply.label", ], + [WorkflowNodeType.Deploy, "workflow_node.deploy.label", ], + [WorkflowNodeType.Branch, "workflow_node.branch.label", ], + [WorkflowNodeType.Notify, "workflow_node.notify.label", ], + ].map(([type, label, icon]) => { + return { + key: type as string, + label: t(label as string), + icon: icon, + onClick: () => { + handleNodeTypeSelect(type as WorkflowNodeType); + }, + }; + }); + }, []); + const handleNodeTypeSelect = (type: WorkflowNodeType) => { - const node = newNode(type); - addNode(node, supnode.id); + const nextNode = newNode(type); + addNode(nextNode, node.id); }; return (
- { - return { - key: item.type, - label: item.label, - icon: item.icon, - onClick: () => { - handleNodeTypeSelect(item.type); - }, - }; - }), - }} - trigger={["click"]} - > +
diff --git a/ui/src/components/workflow/node/BranchNode.tsx b/ui/src/components/workflow/node/BranchNode.tsx index 3231f6a0..e5202dc1 100644 --- a/ui/src/components/workflow/node/BranchNode.tsx +++ b/ui/src/components/workflow/node/BranchNode.tsx @@ -6,8 +6,8 @@ import { type WorkflowNode } from "@/domain/workflow"; import { useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; -import NodeRender from "../NodeRender"; import AddNode from "./AddNode"; +import NodeRender from "./NodeRender"; export type BrandNodeProps = { node: WorkflowNode; diff --git a/ui/src/components/workflow/node/ConditionNode.tsx b/ui/src/components/workflow/node/ConditionNode.tsx index 40213dcd..a19f6b10 100644 --- a/ui/src/components/workflow/node/ConditionNode.tsx +++ b/ui/src/components/workflow/node/ConditionNode.tsx @@ -3,13 +3,19 @@ import { CloseCircleOutlined as CloseCircleOutlinedIcon, EllipsisOutlined as Ell import { Button, Card, Dropdown, Popover } from "antd"; import { produce } from "immer"; +import { type WorkflowNode } from "@/domain/workflow"; import { useZustandShallowSelector } from "@/hooks"; import { useWorkflowStore } from "@/stores/workflow"; import AddNode from "./AddNode"; -import { type NodeProps } from "../types"; -const ConditionNode = ({ node, branchId, branchIndex }: NodeProps) => { +export type ConditionNodeProps = { + node: WorkflowNode; + branchId?: string; + branchIndex?: number; +}; + +const ConditionNode = ({ node, branchId, branchIndex }: ConditionNodeProps) => { const { t } = useTranslation(); const { updateNode, removeBranch } = useWorkflowStore(useZustandShallowSelector(["updateNode", "removeBranch"])); diff --git a/ui/src/components/workflow/NodeRender.tsx b/ui/src/components/workflow/node/NodeRender.tsx similarity index 66% rename from ui/src/components/workflow/NodeRender.tsx rename to ui/src/components/workflow/node/NodeRender.tsx index f3ae6d11..2e7b1e57 100644 --- a/ui/src/components/workflow/NodeRender.tsx +++ b/ui/src/components/workflow/node/NodeRender.tsx @@ -2,13 +2,18 @@ import { memo } from "react"; import { type WorkflowNode, WorkflowNodeType } from "@/domain/workflow"; -import WorkflowElement from "./WorkflowElement"; -import BranchNode from "./node/BranchNode"; -import ConditionNode from "./node/ConditionNode"; -import EndNode from "./node/EndNode"; -import { type NodeProps } from "./types"; +import WorkflowElement from "../WorkflowElement"; +import BranchNode from "./BranchNode"; +import ConditionNode from "./ConditionNode"; +import EndNode from "./EndNode"; -const NodeRender = ({ node: data, branchId, branchIndex }: NodeProps) => { +export type NodeRenderProps = { + node: WorkflowNode; + branchId?: string; + branchIndex?: number; +}; + +const NodeRender = ({ node: data, branchId, branchIndex }: NodeRenderProps) => { const render = () => { switch (data.type) { case WorkflowNodeType.Start: diff --git a/ui/src/components/workflow/types.ts b/ui/src/components/workflow/types.ts deleted file mode 100644 index 36ffc38f..00000000 --- a/ui/src/components/workflow/types.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { type WorkflowBranchNode, type WorkflowNode } from "@/domain/workflow"; - -/** - * @deprecated - */ -export type NodeProps = { - node: WorkflowNode | WorkflowBranchNode; - branchId?: string; - branchIndex?: number; -}; - -/** - * @deprecated - */ -export type BrandNodeProps = { - node: WorkflowBranchNode; -}; diff --git a/ui/src/domain/settings.ts b/ui/src/domain/settings.ts index a20822c8..a27e61e1 100644 --- a/ui/src/domain/settings.ts +++ b/ui/src/domain/settings.ts @@ -7,7 +7,7 @@ export const SETTINGS_NAMES = Object.freeze({ export type SettingsNames = (typeof SETTINGS_NAMES)[keyof typeof SETTINGS_NAMES]; -export interface SettingsModel = NonNullable> extends BaseModel { +export interface SettingsModel = any> extends BaseModel { name: string; content: T; } diff --git a/ui/src/domain/workflow.ts b/ui/src/domain/workflow.ts index 195934b5..124d5f3a 100644 --- a/ui/src/domain/workflow.ts +++ b/ui/src/domain/workflow.ts @@ -3,7 +3,6 @@ import { produce } from "immer"; import { nanoid } from "nanoid"; import i18n from "@/i18n"; -import { deployProvidersMap } from "./provider"; export interface WorkflowModel extends BaseModel { name: string; @@ -28,7 +27,7 @@ export enum WorkflowNodeType { Custom = "custom", } -export const workflowNodeTypeDefaultNames: Map = new Map([ +const workflowNodeTypeDefaultNames: Map = new Map([ [WorkflowNodeType.Start, i18n.t("workflow_node.start.label")], [WorkflowNodeType.End, i18n.t("workflow_node.end.label")], [WorkflowNodeType.Branch, i18n.t("workflow_node.branch.label")], @@ -39,7 +38,7 @@ export const workflowNodeTypeDefaultNames: Map = new M [WorkflowNodeType.Custom, i18n.t("workflow_node.custom.title")], ]); -export const workflowNodeTypeDefaultInputs: Map = new Map([ +const workflowNodeTypeDefaultInputs: Map = new Map([ [WorkflowNodeType.Apply, []], [ WorkflowNodeType.Deploy, @@ -55,7 +54,7 @@ export const workflowNodeTypeDefaultInputs: Map = new Map([ +const workflowNodeTypeDefaultOutputs: Map = new Map([ [ WorkflowNodeType.Apply, [ @@ -80,25 +79,12 @@ export type WorkflowNode = { input?: WorkflowNodeIO[]; output?: WorkflowNodeIO[]; - next?: WorkflowNode | WorkflowBranchNode; + next?: WorkflowNode; branches?: WorkflowNode[]; validated?: boolean; }; -/** - * @deprecated - */ -export type WorkflowBranchNode = { - id: string; - name: string; - type: WorkflowNodeType.Branch; - - branches: WorkflowNode[]; - - next?: WorkflowNode | WorkflowBranchNode; -}; - export type WorkflowNodeIO = { name: string; type: string; @@ -150,11 +136,11 @@ type NewNodeOptions = { branchIndex?: number; }; -export const newNode = (nodeType: WorkflowNodeType, options: NewNodeOptions = {}): WorkflowNode | WorkflowBranchNode => { +export const newNode = (nodeType: WorkflowNodeType, options: NewNodeOptions = {}): WorkflowNode => { const nodeTypeName = workflowNodeTypeDefaultNames.get(nodeType) || ""; const nodeName = options.branchIndex != null ? `${nodeTypeName} ${options.branchIndex + 1}` : nodeTypeName; - const node: WorkflowNode | WorkflowBranchNode = { + const node: WorkflowNode = { id: nanoid(), name: nodeName, type: nodeType, @@ -186,11 +172,7 @@ export const newNode = (nodeType: WorkflowNodeType, options: NewNodeOptions = {} return node; }; -export const isWorkflowBranchNode = (node: WorkflowNode | WorkflowBranchNode): node is WorkflowBranchNode => { - return node.type === WorkflowNodeType.Branch; -}; - -export const updateNode = (node: WorkflowNode | WorkflowBranchNode, targetNode: WorkflowNode | WorkflowBranchNode) => { +export const updateNode = (node: WorkflowNode, targetNode: WorkflowNode) => { return produce(node, (draft) => { let current = draft; while (current) { @@ -198,8 +180,8 @@ export const updateNode = (node: WorkflowNode | WorkflowBranchNode, targetNode: Object.assign(current, targetNode); break; } - if (isWorkflowBranchNode(current)) { - current.branches = current.branches.map((branch) => updateNode(branch, targetNode)); + if (current.type === WorkflowNodeType.Branch) { + current.branches = current.branches!.map((branch) => updateNode(branch, targetNode)); } current = current.next as WorkflowNode; } @@ -207,21 +189,21 @@ export const updateNode = (node: WorkflowNode | WorkflowBranchNode, targetNode: }); }; -export const addNode = (node: WorkflowNode | WorkflowBranchNode, preId: string, targetNode: WorkflowNode | WorkflowBranchNode) => { +export const addNode = (node: WorkflowNode, preId: string, targetNode: WorkflowNode) => { return produce(node, (draft) => { let current = draft; while (current) { - if (current.id === preId && !isWorkflowBranchNode(targetNode)) { + if (current.id === preId && targetNode.type !== WorkflowNodeType.Branch) { targetNode.next = current.next; current.next = targetNode; break; - } else if (current.id === preId && isWorkflowBranchNode(targetNode)) { - targetNode.branches[0].next = current.next; + } else if (current.id === preId && targetNode.type === WorkflowNodeType.Branch) { + targetNode.branches![0].next = current.next; current.next = targetNode; break; } - if (isWorkflowBranchNode(current)) { - current.branches = current.branches.map((branch) => addNode(branch, preId, targetNode)); + if (current.type === WorkflowNodeType.Branch) { + current.branches = current.branches!.map((branch) => addNode(branch, preId, targetNode)); } current = current.next as WorkflowNode; } @@ -229,23 +211,23 @@ export const addNode = (node: WorkflowNode | WorkflowBranchNode, preId: string, }); }; -export const addBranch = (node: WorkflowNode | WorkflowBranchNode, branchNodeId: string) => { +export const addBranch = (node: WorkflowNode, branchNodeId: string) => { return produce(node, (draft) => { let current = draft; while (current) { if (current.id === branchNodeId) { - if (!isWorkflowBranchNode(current)) { + if (current.type !== WorkflowNodeType.Branch) { return draft; } - current.branches.push( + current.branches!.push( newNode(WorkflowNodeType.Condition, { - branchIndex: current.branches.length, + branchIndex: current.branches!.length, }) ); break; } - if (isWorkflowBranchNode(current)) { - current.branches = current.branches.map((branch) => addBranch(branch, branchNodeId)); + if (current.type === WorkflowNodeType.Branch) { + current.branches = current.branches!.map((branch) => addBranch(branch, branchNodeId)); } current = current.next as WorkflowNode; } @@ -253,7 +235,7 @@ export const addBranch = (node: WorkflowNode | WorkflowBranchNode, branchNodeId: }); }; -export const removeNode = (node: WorkflowNode | WorkflowBranchNode, targetNodeId: string) => { +export const removeNode = (node: WorkflowNode, targetNodeId: string) => { return produce(node, (draft) => { let current = draft; while (current) { @@ -261,8 +243,8 @@ export const removeNode = (node: WorkflowNode | WorkflowBranchNode, targetNodeId current.next = current.next.next; break; } - if (isWorkflowBranchNode(current)) { - current.branches = current.branches.map((branch) => removeNode(branch, targetNodeId)); + if (current.type === WorkflowNodeType.Branch) { + current.branches = current.branches!.map((branch) => removeNode(branch, targetNodeId)); } current = current.next as WorkflowNode; } @@ -270,10 +252,10 @@ export const removeNode = (node: WorkflowNode | WorkflowBranchNode, targetNodeId }); }; -export const removeBranch = (node: WorkflowNode | WorkflowBranchNode, branchNodeId: string, branchIndex: number) => { +export const removeBranch = (node: WorkflowNode, branchNodeId: string, branchIndex: number) => { return produce(node, (draft) => { let current = draft; - let last: WorkflowNode | WorkflowBranchNode | undefined = { + let last: WorkflowNode | undefined = { id: "", name: "", type: WorkflowNodeType.Start, @@ -281,17 +263,17 @@ export const removeBranch = (node: WorkflowNode | WorkflowBranchNode, branchNode }; while (current && last) { if (current.id === branchNodeId) { - if (!isWorkflowBranchNode(current)) { + if (current.type !== WorkflowNodeType.Branch) { return draft; } - current.branches.splice(branchIndex, 1); + current.branches!.splice(branchIndex, 1); // 如果仅剩一个分支,删除分支节点,将分支节点的下一个节点挂载到当前节点 - if (current.branches.length === 1) { - const branch = current.branches[0]; + if (current.branches!.length === 1) { + const branch = current.branches![0]; if (branch.next) { last.next = branch.next; - let lastNode: WorkflowNode | WorkflowBranchNode | undefined = branch.next; + let lastNode: WorkflowNode | undefined = branch.next; while (lastNode?.next) { lastNode = lastNode.next; } @@ -303,8 +285,8 @@ export const removeBranch = (node: WorkflowNode | WorkflowBranchNode, branchNode break; } - if (isWorkflowBranchNode(current)) { - current.branches = current.branches.map((branch) => removeBranch(branch, branchNodeId, branchIndex)); + if (current.type === WorkflowNodeType.Branch) { + current.branches = current.branches!.map((branch) => removeBranch(branch, branchNodeId, branchIndex)); } current = current.next as WorkflowNode; last = last.next; @@ -314,10 +296,10 @@ export const removeBranch = (node: WorkflowNode | WorkflowBranchNode, branchNode }; // 1 个分支的节点,不应该能获取到相邻分支上节点的输出 -export const getWorkflowOutputBeforeId = (node: WorkflowNode | WorkflowBranchNode, id: string, type: string): WorkflowNode[] => { +export const getWorkflowOutputBeforeId = (node: WorkflowNode, id: string, type: string): WorkflowNode[] => { const output: WorkflowNode[] = []; - const traverse = (current: WorkflowNode | WorkflowBranchNode, output: WorkflowNode[]) => { + const traverse = (current: WorkflowNode, output: WorkflowNode[]) => { if (!current) { return false; } @@ -325,16 +307,16 @@ export const getWorkflowOutputBeforeId = (node: WorkflowNode | WorkflowBranchNod return true; } - if (!isWorkflowBranchNode(current) && current.output && current.output.some((io) => io.type === type)) { + if (current.type !== WorkflowNodeType.Branch && current.output && current.output.some((io) => io.type === type)) { output.push({ ...current, output: current.output.filter((io) => io.type === type), }); } - if (isWorkflowBranchNode(current)) { + if (current.type === WorkflowNodeType.Branch) { const currentLength = output.length; - for (const branch of current.branches) { + for (const branch of current.branches!) { if (traverse(branch, output)) { return true; } diff --git a/ui/src/hooks/useAntdForm.ts b/ui/src/hooks/useAntdForm.ts index af59cfb8..525d1b71 100644 --- a/ui/src/hooks/useAntdForm.ts +++ b/ui/src/hooks/useAntdForm.ts @@ -2,13 +2,13 @@ import { useDeepCompareEffect } from "ahooks"; import { Form, type FormInstance, type FormProps } from "antd"; -export interface UseAntdFormOptions = NonNullable> { +export interface UseAntdFormOptions = any> { form?: FormInstance; initialValues?: Partial | (() => Partial | Promise>); onSubmit?: (values: T) => unknown; } -export interface UseAntdFormReturns = NonNullable> { +export interface UseAntdFormReturns = any> { form: FormInstance; formProps: Omit, "children">; formPending: boolean; @@ -20,11 +20,7 @@ export interface UseAntdFormReturns = NonNullable * @param {UseAntdFormOptions} options * @returns {UseAntdFormReturns} */ -const useAntdForm = = NonNullable>({ - initialValues, - form, - onSubmit, -}: UseAntdFormOptions): UseAntdFormReturns => { +const useAntdForm = = any>({ initialValues, form, onSubmit }: UseAntdFormOptions): UseAntdFormReturns => { const formInst = form ?? Form["useForm"]()[0]; const [formInitialValues, setFormInitialValues] = useState>(); const [formPending, setFormPending] = useState(false); diff --git a/ui/src/stores/workflow/index.ts b/ui/src/stores/workflow/index.ts index 369347c1..5f84d54d 100644 --- a/ui/src/stores/workflow/index.ts +++ b/ui/src/stores/workflow/index.ts @@ -1,7 +1,6 @@ import { create } from "zustand"; import { - type WorkflowBranchNode, type WorkflowModel, type WorkflowNode, addBranch, @@ -112,7 +111,7 @@ export const useWorkflowStore = create((set, get) => ({ }); }, - updateNode: async (node: WorkflowNode | WorkflowBranchNode) => { + updateNode: async (node: WorkflowNode) => { const newRoot = updateNode(get().workflow.draft as WorkflowNode, node); const resp = await saveWorkflow({ id: (get().workflow.id as string) ?? "", @@ -132,7 +131,7 @@ export const useWorkflowStore = create((set, get) => ({ }); }, - addNode: async (node: WorkflowNode | WorkflowBranchNode, preId: string) => { + addNode: async (node: WorkflowNode, preId: string) => { const newRoot = addNode(get().workflow.draft as WorkflowNode, preId, node); const resp = await saveWorkflow({ id: (get().workflow.id as string) ?? "",