"use client"; import React, { useState, useEffect } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog"; import { AlertDialog, AlertDialogAction, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { CheckCircle } from "lucide-react"; import { JsonRelationship } from "@/lib/api/dataflow"; interface SaveDiagramModalProps { isOpen: boolean; onClose: () => void; onSave: (diagramName: string) => Promise<{ success: boolean; error?: string }>; relationships: JsonRelationship[]; defaultName?: string; isLoading?: boolean; } const SaveDiagramModal: React.FC = ({ isOpen, onClose, onSave, relationships, defaultName = "", isLoading = false, }) => { const [diagramName, setDiagramName] = useState(defaultName); const [nameError, setNameError] = useState(""); const [showSuccessModal, setShowSuccessModal] = useState(false); const [savedDiagramName, setSavedDiagramName] = useState(""); // defaultName이 변경될 때마다 diagramName 업데이트 useEffect(() => { setDiagramName(defaultName); }, [defaultName]); const handleSave = async () => { const trimmedName = diagramName.trim(); if (!trimmedName) { setNameError("관계도 이름을 입력해주세요."); return; } if (trimmedName.length < 2) { setNameError("관계도 이름은 2글자 이상이어야 합니다."); return; } if (trimmedName.length > 100) { setNameError("관계도 이름은 100글자를 초과할 수 없습니다."); return; } setNameError(""); try { // 부모에게 저장 요청하고 결과 받기 const result = await onSave(trimmedName); if (result.success) { // 성공 시 성공 모달 표시 setSavedDiagramName(trimmedName); setShowSuccessModal(true); } else { // 실패 시 에러 메시지 표시 if ( result.error?.includes("중복된 이름입니다") || result.error?.includes("중복") || result.error?.includes("duplicate") || result.error?.includes("already exists") ) { setNameError("중복된 이름입니다."); } else { setNameError(result.error || "저장 중 오류가 발생했습니다."); } } } catch (error) { // 중복 에러가 아닌 경우만 콘솔에 로그 출력 const isDuplicateError = error && typeof error === "object" && "response" in error && (error as any).response?.status === 409; if (!isDuplicateError) { console.error("저장 오류:", error); } setNameError("저장 중 오류가 발생했습니다."); } }; const handleClose = () => { if (!isLoading) { setDiagramName(defaultName); setNameError(""); onClose(); } }; const handleSuccessModalClose = () => { setShowSuccessModal(false); setSavedDiagramName(""); handleClose(); // 원래 모달도 닫기 }; const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === "Enter" && !isLoading) { handleSave(); } }; // 관련된 테이블 목록 추출 const connectedTables = Array.from( new Set([...relationships.map((rel) => rel.fromTable), ...relationships.map((rel) => rel.toTable)]), ).sort(); return ( <> 📊 관계도 저장
{/* 관계도 이름 입력 */}
{ setDiagramName(e.target.value); if (nameError) setNameError(""); }} onKeyPress={handleKeyPress} placeholder="예: 사용자-부서 관계도" disabled={isLoading} className={nameError ? "border-destructive focus:border-destructive" : ""} /> {nameError &&

{nameError}

}
{/* 관계 요약 정보 */}
{relationships.length}
관계 수
{connectedTables.length}
연결된 테이블
{relationships.reduce((sum, rel) => sum + rel.fromColumns.length, 0)}
연결된 컬럼
{/* 연결된 테이블 목록 */} {connectedTables.length > 0 && ( 연결된 테이블
{connectedTables.map((table) => ( {table} ))}
)} {/* 관계 목록 미리보기 */} {relationships.length > 0 && ( 관계 목록
{relationships.map((relationship, index) => (
{relationship.connectionType || "simple-key"} {relationship.relationshipName || `${relationship.fromTable} → ${relationship.toTable}`}
{relationship.fromTable} → {relationship.toTable}
{relationship.connectionType}
))}
)} {/* 관계가 없는 경우 안내 */} {relationships.length === 0 && (
📭
생성된 관계가 없습니다.
테이블을 추가하고 컬럼을 연결해서 관계를 생성해보세요.
)}
{/* 저장 성공 알림 모달 */} 관계도 저장 완료 {savedDiagramName} 관계도가 성공적으로 저장되었습니다.
저장된 관계도는 관리 메뉴에서 확인하고 수정할 수 있습니다.
확인
); }; export default SaveDiagramModal;