128 lines
4.6 KiB
TypeScript
128 lines
4.6 KiB
TypeScript
|
|
"use client";
|
||
|
|
|
||
|
|
import React from "react";
|
||
|
|
import { SelectedEdgeInfo } from "@/types/dataflowTypes";
|
||
|
|
|
||
|
|
interface EdgeInfoPanelProps {
|
||
|
|
isOpen: boolean;
|
||
|
|
edgeInfo: SelectedEdgeInfo | null;
|
||
|
|
position: { x: number; y: number };
|
||
|
|
onClose: () => void;
|
||
|
|
onEdit: () => void;
|
||
|
|
onDelete: () => void;
|
||
|
|
}
|
||
|
|
|
||
|
|
export const EdgeInfoPanel: React.FC<EdgeInfoPanelProps> = ({
|
||
|
|
isOpen,
|
||
|
|
edgeInfo,
|
||
|
|
position,
|
||
|
|
onClose,
|
||
|
|
onEdit,
|
||
|
|
onDelete,
|
||
|
|
}) => {
|
||
|
|
if (!isOpen || !edgeInfo) return null;
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div
|
||
|
|
className="fixed z-50 rounded-xl border border-gray-200 bg-white shadow-2xl"
|
||
|
|
style={{
|
||
|
|
left: position.x - 160,
|
||
|
|
top: position.y - 100,
|
||
|
|
minWidth: "320px",
|
||
|
|
maxWidth: "380px",
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
{/* 헤더 */}
|
||
|
|
<div className="flex items-center justify-between rounded-t-xl border-b border-gray-200 bg-blue-600 p-4">
|
||
|
|
<div className="flex items-center gap-3">
|
||
|
|
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-white/20 backdrop-blur-sm">
|
||
|
|
<span className="text-sm text-white">🔗</span>
|
||
|
|
</div>
|
||
|
|
<div>
|
||
|
|
<div className="text-sm font-bold text-white">{edgeInfo.relationshipName}</div>
|
||
|
|
<div className="text-xs text-blue-100">데이터 관계 정보</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<button
|
||
|
|
onClick={onClose}
|
||
|
|
className="flex h-6 w-6 items-center justify-center rounded-full text-white/80 transition-all hover:bg-white/20 hover:text-white"
|
||
|
|
>
|
||
|
|
<span className="text-sm">✕</span>
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 관계 정보 요약 */}
|
||
|
|
<div className="border-b border-gray-100 bg-gray-50 p-3">
|
||
|
|
<div className="flex items-center justify-center gap-4">
|
||
|
|
<div className="text-center">
|
||
|
|
<div className="text-xs font-medium tracking-wide text-gray-500 uppercase">연결 유형</div>
|
||
|
|
<div className="mt-1 inline-flex items-center rounded-full bg-indigo-100 px-2 py-0.5 text-xs font-semibold text-indigo-800">
|
||
|
|
{edgeInfo.connectionType}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 연결 정보 */}
|
||
|
|
<div className="space-y-3 p-4">
|
||
|
|
{/* From 테이블 */}
|
||
|
|
<div className="rounded-lg border-l-4 border-emerald-400 bg-emerald-50 p-3">
|
||
|
|
<div className="mb-2 text-xs font-bold tracking-wide text-emerald-700 uppercase">FROM</div>
|
||
|
|
<div className="mb-2 text-base font-bold text-gray-800">{edgeInfo.fromTable}</div>
|
||
|
|
<div className="space-y-1">
|
||
|
|
<div className="flex flex-wrap gap-2">
|
||
|
|
{edgeInfo.fromColumns.map((column, index) => (
|
||
|
|
<span
|
||
|
|
key={index}
|
||
|
|
className="inline-flex items-center rounded-md bg-emerald-100 px-2.5 py-0.5 text-xs font-medium text-emerald-800 ring-1 ring-emerald-200"
|
||
|
|
>
|
||
|
|
{column}
|
||
|
|
</span>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 관계 화살표 */}
|
||
|
|
<div className="flex justify-center">
|
||
|
|
<span className="text-l text-gray-600">→</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* To 테이블 */}
|
||
|
|
<div className="rounded-lg border-l-4 border-blue-400 bg-blue-50 p-3">
|
||
|
|
<div className="mb-2 text-xs font-bold tracking-wide text-blue-700 uppercase">TO</div>
|
||
|
|
<div className="mb-2 text-base font-bold text-gray-800">{edgeInfo.toTable}</div>
|
||
|
|
<div className="space-y-1">
|
||
|
|
<div className="flex flex-wrap gap-2">
|
||
|
|
{edgeInfo.toColumns.map((column, index) => (
|
||
|
|
<span
|
||
|
|
key={index}
|
||
|
|
className="inline-flex items-center rounded-md bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-800 ring-1 ring-blue-200"
|
||
|
|
>
|
||
|
|
{column}
|
||
|
|
</span>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* 액션 버튼 */}
|
||
|
|
<div className="flex gap-2 border-t border-gray-200 bg-gray-50 p-3">
|
||
|
|
<button
|
||
|
|
onClick={onEdit}
|
||
|
|
className="flex flex-1 items-center justify-center gap-1 rounded-lg bg-blue-600 px-3 py-2 text-xs font-semibold text-white shadow-sm transition-all hover:bg-blue-700 hover:shadow-md"
|
||
|
|
>
|
||
|
|
<span>수정</span>
|
||
|
|
</button>
|
||
|
|
<button
|
||
|
|
onClick={onDelete}
|
||
|
|
className="flex flex-1 items-center justify-center gap-1 rounded-lg bg-red-600 px-3 py-2 text-xs font-semibold text-white shadow-sm transition-all hover:bg-red-700 hover:shadow-md"
|
||
|
|
>
|
||
|
|
<span>삭제</span>
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
};
|