import React, { useState, useEffect } from "react"; import { X, Plus, Trash } from "lucide-react"; import { Node } from "reactflow"; import { useFlowStore } from "../store/flowStore"; interface ConfigPanelProps { node: Node | null; onClose: () => void; onUpdateNode: (id: string, data: any) => void; } interface Field { name: string; type: string; validation?: string; } const getDefaultDataForType = (type: string) => { const baseData = { label: type.charAt(0).toUpperCase() + type.slice(1).replace("-", " ") }; switch (type) { case "variable": return { ...baseData, name: "", type: "string", defaultValue: "" }; case "url": return { ...baseData, method: "GET", path: "", fields: [], queryFields: [] }; case "auth": return { ...baseData, authType: "bearer", tokenVar: "" }; case "output": return { ...baseData, outputType: "definition", statusCode: 200, fields: [], responseRaw: "" }; case "logic": return { ...baseData, code: "" }; case "db-find": case "db-query": return { ...baseData, model: "", operation: "findMany", query: "", resultVar: "result" }; case "db-insert": return { ...baseData, model: "", variables: "", resultVar: "result" }; case "db-update": case "db-delete": return { ...baseData, model: "", idField: "id", variables: "", resultVar: "result" }; default: return baseData; } }; export function ConfigPanel({ node, onClose, onUpdateNode }: ConfigPanelProps) { const { models, updateNode } = useFlowStore(); const [newField, setNewField] = useState({ name: "", type: "string" }); const [newQueryField, setNewQueryField] = useState({ name: "", type: "string", }); useEffect(() => { if (node) { // Initialize node data with defaults if not already set const defaultData = getDefaultDataForType(node.type); const newData = { ...defaultData, ...node.data // This will override defaults with any existing data }; // Only update if the data is different if (JSON.stringify(newData) !== JSON.stringify(node.data)) { onUpdateNode(node.id, newData); updateNode(node.id, newData); } } }, [node?.id, node?.type]); useEffect(() => { console.log("ConfigPanel re-rendered with node:", node); }, [node]); if (!node) return null; console.log("what up"); const handleChange = ( e: React.ChangeEvent ) => { if (!node) return; console.log("Handling change for:", e.target.name, "with value:", e.target.value); const newData = { ...node.data, [e.target.name]: e.target.value, }; console.log("New data to update:", newData); onUpdateNode(node.id, newData); updateNode(node.id, newData); }; const handleArrayChange = ( index: number, field: string, value: string, arrayName: string ) => { const array = [...node.data[arrayName]]; array[index] = { ...array[index], [field]: value }; const newData = { ...node.data, [arrayName]: array, }; onUpdateNode(node.id, newData); updateNode(node.id, newData); }; const addField = (arrayName: string) => { const fieldToAdd = arrayName === "queryFields" ? newQueryField : newField; if (!fieldToAdd.name.trim()) return; const array = [...node.data[arrayName], { ...fieldToAdd }]; const newData = { ...node.data, [arrayName]: array, }; onUpdateNode(node.id, newData); updateNode(node.id, newData); // Reset the appropriate state if (arrayName === "queryFields") { setNewQueryField({ name: "", type: "string" }); } else { setNewField({ name: "", type: "string" }); } }; const removeField = (index: number, arrayName: string) => { const array = [...node.data[arrayName]]; array.splice(index, 1); const newData = { ...node.data, [arrayName]: array, }; onUpdateNode(node.id, newData); updateNode(node.id, newData); }; const copyQueryFields = () => { const currentFields = node.data.fields || []; navigator.clipboard.writeText(JSON.stringify(currentFields, null, 2)); }; const extractQueryParams = (path: string) => { const params = path.match(/:[a-zA-Z]+/g) || []; return params.map((param) => ({ name: param.substring(1), type: "string", validation: "", })); }; const renderDatabaseFields = () => ( <>