"use client"; import React, { useState, useEffect } from "react"; import { X, Save, TestTube, ChevronDown, ChevronUp } from "lucide-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 { Switch } from "@/components/ui/switch"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog"; import { useToast } from "@/hooks/use-toast"; import { ExternalRestApiConnectionAPI, ExternalRestApiConnection, AuthType, RestApiTestResult, } from "@/lib/api/externalRestApiConnection"; import { HeadersManager } from "./HeadersManager"; import { AuthenticationConfig } from "./AuthenticationConfig"; import { Badge } from "@/components/ui/badge"; interface RestApiConnectionModalProps { isOpen: boolean; onClose: () => void; onSave: () => void; connection?: ExternalRestApiConnection; } export function RestApiConnectionModal({ isOpen, onClose, onSave, connection }: RestApiConnectionModalProps) { const { toast } = useToast(); // 폼 상태 const [connectionName, setConnectionName] = useState(""); const [description, setDescription] = useState(""); const [baseUrl, setBaseUrl] = useState(""); const [endpointPath, setEndpointPath] = useState(""); const [defaultHeaders, setDefaultHeaders] = useState>({}); const [authType, setAuthType] = useState("none"); const [authConfig, setAuthConfig] = useState({}); const [timeout, setTimeout] = useState(30000); const [retryCount, setRetryCount] = useState(0); const [retryDelay, setRetryDelay] = useState(1000); const [isActive, setIsActive] = useState(true); // UI 상태 const [showAdvanced, setShowAdvanced] = useState(false); const [testEndpoint, setTestEndpoint] = useState(""); const [testing, setTesting] = useState(false); const [testResult, setTestResult] = useState(null); const [testRequestUrl, setTestRequestUrl] = useState(""); const [saving, setSaving] = useState(false); // 기존 연결 데이터 로드 useEffect(() => { if (connection) { setConnectionName(connection.connection_name); setDescription(connection.description || ""); setBaseUrl(connection.base_url); setEndpointPath(connection.endpoint_path || ""); setDefaultHeaders(connection.default_headers || {}); setAuthType(connection.auth_type); setAuthConfig(connection.auth_config || {}); setTimeout(connection.timeout || 30000); setRetryCount(connection.retry_count || 0); setRetryDelay(connection.retry_delay || 1000); setIsActive(connection.is_active === "Y"); } else { // 초기화 setConnectionName(""); setDescription(""); setBaseUrl(""); setEndpointPath(""); setDefaultHeaders({ "Content-Type": "application/json" }); setAuthType("none"); setAuthConfig({}); setTimeout(30000); setRetryCount(0); setRetryDelay(1000); setIsActive(true); } setTestResult(null); setTestEndpoint(""); setTestRequestUrl(""); }, [connection, isOpen]); // 연결 테스트 const handleTest = async () => { // 유효성 검증 if (!baseUrl.trim()) { toast({ title: "입력 오류", description: "기본 URL을 입력해주세요.", variant: "destructive", }); return; } setTesting(true); setTestResult(null); // 사용자가 테스트하려는 실제 외부 API URL 설정 const fullUrl = testEndpoint ? `${baseUrl}${testEndpoint}` : baseUrl; setTestRequestUrl(fullUrl); try { const result = await ExternalRestApiConnectionAPI.testConnection({ base_url: baseUrl, endpoint: testEndpoint || undefined, headers: defaultHeaders, auth_type: authType, auth_config: authConfig, timeout, }); setTestResult(result); if (result.success) { toast({ title: "연결 성공", description: `응답 시간: ${result.response_time}ms`, }); } else { toast({ title: "연결 실패", description: result.message, variant: "destructive", }); } } catch (error) { toast({ title: "테스트 오류", description: error instanceof Error ? error.message : "알 수 없는 오류", variant: "destructive", }); } finally { setTesting(false); } }; // 저장 const handleSave = async () => { // 유효성 검증 if (!connectionName.trim()) { toast({ title: "입력 오류", description: "연결명을 입력해주세요.", variant: "destructive", }); return; } if (!baseUrl.trim()) { toast({ title: "입력 오류", description: "기본 URL을 입력해주세요.", variant: "destructive", }); return; } // URL 형식 검증 try { new URL(baseUrl); } catch { toast({ title: "입력 오류", description: "올바른 URL 형식이 아닙니다.", variant: "destructive", }); return; } setSaving(true); try { const data: ExternalRestApiConnection = { connection_name: connectionName, description: description || undefined, base_url: baseUrl, endpoint_path: endpointPath || undefined, default_headers: defaultHeaders, auth_type: authType, auth_config: authType === "none" ? undefined : authConfig, timeout, retry_count: retryCount, retry_delay: retryDelay, company_code: "*", is_active: isActive ? "Y" : "N", }; if (connection?.id) { await ExternalRestApiConnectionAPI.updateConnection(connection.id, data); toast({ title: "수정 완료", description: "연결이 수정되었습니다.", }); } else { await ExternalRestApiConnectionAPI.createConnection(data); toast({ title: "생성 완료", description: "연결이 생성되었습니다.", }); } onSave(); onClose(); } catch (error) { toast({ title: "저장 실패", description: error instanceof Error ? error.message : "알 수 없는 오류", variant: "destructive", }); } finally { setSaving(false); } }; return ( {connection ? "REST API 연결 수정" : "새 REST API 연결 추가"}
{/* 기본 정보 */}

기본 정보

setConnectionName(e.target.value)} placeholder="예: 날씨 API" />