/** * 커넥션 선택 패널 * 제어관리에서 FROM/TO 커넥션을 선택할 수 있는 컴포넌트 */ import React, { useState, useEffect } from "react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Badge } from "@/components/ui/badge"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { AlertCircle, Database, ExternalLink } from "lucide-react"; import { getActiveConnections, ConnectionInfo } from "@/lib/api/multiConnection"; import { useToast } from "@/hooks/use-toast"; export interface ConnectionSelectionPanelProps { fromConnectionId?: number; toConnectionId?: number; onFromConnectionChange: (connectionId: number) => void; onToConnectionChange: (connectionId: number) => void; actionType: "insert" | "update" | "delete"; // 🆕 자기 자신 테이블 작업 지원 allowSameConnection?: boolean; currentConnectionId?: number; // 현재 메인 DB 커넥션 disabled?: boolean; } export const ConnectionSelectionPanel: React.FC = ({ fromConnectionId, toConnectionId, onFromConnectionChange, onToConnectionChange, actionType, allowSameConnection = true, currentConnectionId = 0, disabled = false, }) => { const { toast } = useToast(); const [availableConnections, setAvailableConnections] = useState([]); const [loading, setLoading] = useState(true); // 커넥션 목록 로드 (한 번만 실행) useEffect(() => { let isMounted = true; const loadConnections = async () => { try { setLoading(true); console.log("🔍 커넥션 목록 로드 시작..."); const connections = await getActiveConnections(); if (isMounted) { console.log("✅ 커넥션 목록 로드 성공:", connections); setAvailableConnections(Array.isArray(connections) ? connections : []); } } catch (error) { if (isMounted) { console.error("❌ 커넥션 목록 로드 실패:", error); console.error("Error details:", { message: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined, response: error && typeof error === "object" && "response" in error ? error.response : undefined, }); toast({ title: "커넥션 로드 실패", description: `활성 커넥션 목록을 불러오는데 실패했습니다. ${error instanceof Error ? error.message : String(error)}`, variant: "destructive", }); } } finally { if (isMounted) { setLoading(false); } } }; // 컴포넌트가 마운트된 후 1초 딜레이로 API 호출 (Rate Limiting 방지) const timeoutId = setTimeout(() => { if (isMounted) { loadConnections(); } }, 1000); return () => { isMounted = false; clearTimeout(timeoutId); }; }, []); // 의존성 배열을 빈 배열로 수정 // 액션 타입별 라벨 정의 const getConnectionLabels = () => { switch (actionType) { case "insert": return { from: { title: "소스 데이터베이스 연결", desc: "데이터를 가져올 데이터베이스 연결을 선택하세요", }, to: { title: "대상 데이터베이스 연결", desc: "데이터를 저장할 데이터베이스 연결을 선택하세요", }, }; case "update": return { from: { title: "조건 확인 데이터베이스", desc: "업데이트 조건을 확인할 데이터베이스 연결을 선택하세요 (자기 자신 가능)", }, to: { title: "업데이트 대상 데이터베이스", desc: "데이터를 업데이트할 데이터베이스 연결을 선택하세요 (자기 자신 가능)", }, }; case "delete": return { from: { title: "조건 확인 데이터베이스", desc: "삭제 조건을 확인할 데이터베이스 연결을 선택하세요 (자기 자신 가능)", }, to: { title: "삭제 대상 데이터베이스", desc: "데이터를 삭제할 데이터베이스 연결을 선택하세요 (자기 자신 가능)", }, }; } }; // 🆕 자기 자신 테이블 작업 시 경고 메시지 const getSameConnectionWarning = () => { if (fromConnectionId === toConnectionId && fromConnectionId !== undefined) { switch (actionType) { case "update": return "⚠️ 같은 데이터베이스에서 UPDATE 작업을 수행합니다. 조건을 신중히 설정하세요."; case "delete": return "🚨 같은 데이터베이스에서 DELETE 작업을 수행합니다. 데이터 손실에 주의하세요."; } } return null; }; const labels = getConnectionLabels(); const warningMessage = getSameConnectionWarning(); // 커넥션 선택 핸들러 const handleFromConnectionChange = (value: string) => { const connectionId = parseInt(value); onFromConnectionChange(connectionId); }; const handleToConnectionChange = (value: string) => { const connectionId = parseInt(value); onToConnectionChange(connectionId); }; // 커넥션 아이템 렌더링 const renderConnectionItem = (connection: ConnectionInfo) => (
{connection.id === 0 ? ( 현재 DB ) : ( {connection.db_type?.toUpperCase()} )} {connection.connection_name}
); if (loading) { return (
); } return (
{/* FROM 커넥션 선택 */} {labels.from.title} {labels.from.desc} {/* TO 커넥션 선택 */} {labels.to.title} {labels.to.desc}
{/* 🆕 자기 자신 테이블 작업 시 경고 */} {warningMessage && ( 주의사항 {warningMessage} )} {/* 연결 상태 표시 */} {fromConnectionId !== undefined && toConnectionId !== undefined && (
연결 상태: {availableConnections.find((c) => c.id === fromConnectionId)?.connection_name || "Unknown"} {availableConnections.find((c) => c.id === toConnectionId)?.connection_name || "Unknown"}
)}
); };