"use client"; import { useState, useEffect } from "react"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; import { useFlowEditorStore } from "@/lib/stores/flowEditorStore"; import { RestAPISourceNodeData } from "@/types/node-editor"; import { Globe, Plus, Trash2 } from "lucide-react"; interface RestAPISourcePropertiesProps { nodeId: string; data: RestAPISourceNodeData; } const HTTP_METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH"]; const AUTH_TYPES = [ { value: "none", label: "인증 없음" }, { value: "bearer", label: "Bearer Token" }, { value: "basic", label: "Basic Auth" }, { value: "apikey", label: "API Key" }, ]; export function RestAPISourceProperties({ nodeId, data }: RestAPISourcePropertiesProps) { const { updateNode } = useFlowEditorStore(); const [displayName, setDisplayName] = useState(data.displayName || ""); const [url, setUrl] = useState(data.url || ""); const [method, setMethod] = useState(data.method || "GET"); const [headers, setHeaders] = useState(data.headers || {}); const [newHeaderKey, setNewHeaderKey] = useState(""); const [newHeaderValue, setNewHeaderValue] = useState(""); const [body, setBody] = useState(JSON.stringify(data.body || {}, null, 2)); const [authType, setAuthType] = useState(data.authentication?.type || "none"); const [authToken, setAuthToken] = useState(data.authentication?.token || ""); const [timeout, setTimeout] = useState(data.timeout?.toString() || "30000"); const [responseMapping, setResponseMapping] = useState(data.responseMapping || ""); const [responseFields, setResponseFields] = useState(data.responseFields || []); useEffect(() => { setDisplayName(data.displayName || ""); setUrl(data.url || ""); setMethod(data.method || "GET"); setHeaders(data.headers || {}); setBody(JSON.stringify(data.body || {}, null, 2)); setAuthType(data.authentication?.type || "none"); setAuthToken(data.authentication?.token || ""); setTimeout(data.timeout?.toString() || "30000"); setResponseMapping(data.responseMapping || ""); setResponseFields(data.responseFields || []); }, [data]); const handleApply = () => { let parsedBody = {}; try { parsedBody = body.trim() ? JSON.parse(body) : {}; } catch (e) { alert("Body JSON 형식이 올바르지 않습니다."); return; } console.log("🔧 REST API 노드 업데이트 중..."); console.log("📦 responseFields:", responseFields); console.log("📊 responseFields 개수:", responseFields.length); updateNode(nodeId, { displayName, url, method: method as any, headers, body: parsedBody, authentication: { type: authType as any, token: authToken || undefined, }, timeout: parseInt(timeout) || 30000, responseMapping, responseFields, }); console.log("✅ REST API 노드 업데이트 완료"); }; const addHeader = () => { if (newHeaderKey.trim() && newHeaderValue.trim()) { setHeaders({ ...headers, [newHeaderKey.trim()]: newHeaderValue.trim() }); setNewHeaderKey(""); setNewHeaderValue(""); } }; const removeHeader = (key: string) => { const newHeaders = { ...headers }; delete newHeaders[key]; setHeaders(newHeaders); }; const addResponseField = () => { const newFields = [ ...responseFields, { name: "", label: "", dataType: "TEXT", }, ]; console.log("➕ 응답 필드 추가:", newFields); setResponseFields(newFields); }; const updateResponseField = (index: number, field: string, value: string) => { const updated = [...responseFields]; updated[index] = { ...updated[index], [field]: value }; console.log(`✏️ 응답 필드 ${index} 업데이트 (${field}=${value}):`, updated); setResponseFields(updated); }; const removeResponseField = (index: number) => { const newFields = responseFields.filter((_, i) => i !== index); console.log("🗑️ 응답 필드 삭제:", newFields); setResponseFields(newFields); }; return (
REST API 소스
setDisplayName(e.target.value)} placeholder="노드에 표시될 이름" className="mt-1 text-sm" />
setUrl(e.target.value)} placeholder="https://api.example.com/data" className="mt-1 text-sm" />
setNewHeaderKey(e.target.value)} placeholder="Key" className="text-sm" /> setNewHeaderValue(e.target.value)} onKeyDown={(e) => e.key === "Enter" && addHeader()} placeholder="Value" className="text-sm" />
{Object.entries(headers).map(([key, value]) => (
{key}: {value}
))}
{(method === "POST" || method === "PUT" || method === "PATCH") && (