"use client" import { useState } from "react" import type { Node } from "@xyflow/react" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Textarea } from "@/components/ui/textarea" import { VariableSelector } from "./variable-selector" import type { WorkflowNodeSpec, WorkflowVariableRef, WorkflowVariableSelector, } from "./workflow-utils" type WorkflowNodeData = Record & { nodeType?: string name?: string config?: Record inputs?: Record } export function NodeConfigPanel({ node, nodeSpec, availableVariables, onChange, }: { node: Node | null nodeSpec?: WorkflowNodeSpec availableVariables: WorkflowVariableRef[] onChange: (nodeId: string, data: WorkflowNodeData) => void }) { if (!node) { return (
选择一个节点后,可以配置输入映射并查看输出变量。
) } return ( ) } function NodeConfigForm({ node, nodeSpec, availableVariables, onChange, }: { node: Node nodeSpec?: WorkflowNodeSpec availableVariables: WorkflowVariableRef[] onChange: (nodeId: string, data: WorkflowNodeData) => void }) { const [name, setName] = useState(node.data.name ?? "") const [configText, setConfigText] = useState(JSON.stringify(node.data.config ?? {}, null, 2)) const [inputs, setInputs] = useState>( node.data.inputs ?? {} ) const [error, setError] = useState("") const inputSchema = nodeSpec?.inputSchema ?? [] const outputSchema = nodeSpec?.outputSchema ?? [] const commitChange = (next: Partial) => { onChange(node.id, { ...node.data, name: name.trim() || node.data.nodeType || node.id, config: node.data.config ?? {}, inputs, ...next, }) } const handleApply = () => { try { const parsed = JSON.parse(configText || "{}") as Record setError("") commitChange({ config: parsed }) } catch { setError("Config must be valid JSON.") } } return (
{node.data.nodeType ?? node.id}
{node.id}
setName(event.target.value)} onBlur={() => commitChange({ name: name.trim() || node.data.nodeType || node.id })} />
{inputSchema.length > 0 ? (
输入映射
{availableVariables.length === 0 ? (
当前节点前面还没有可用变量,请先连接上游节点。
) : null} {inputSchema.map((input) => (
{input.type}
{ const nextInputs = { ...inputs, [input.name]: value, } setInputs(nextInputs) commitChange({ inputs: nextInputs, }) }} /> {inputs[input.name] ? (
已选择:{inputs[input.name].nodeId}.{inputs[input.name].field}
) : null} {input.description ? (
{input.description}
) : null}
))}
) : null}
高级配置 JSON