관계도 조회 구현
This commit is contained in:
@@ -22,10 +22,18 @@ interface TableNodeData {
|
||||
onScrollAreaEnter?: () => void;
|
||||
onScrollAreaLeave?: () => void;
|
||||
selectedColumns?: string[]; // 선택된 컬럼 목록
|
||||
connectedColumns?: { [columnName: string]: { direction: "source" | "target" | "both" } }; // 연결된 컬럼 정보
|
||||
}
|
||||
|
||||
export const TableNode: React.FC<{ data: TableNodeData }> = ({ data }) => {
|
||||
const { table, onColumnClick, onScrollAreaEnter, onScrollAreaLeave, selectedColumns = [] } = data;
|
||||
const {
|
||||
table,
|
||||
onColumnClick,
|
||||
onScrollAreaEnter,
|
||||
onScrollAreaLeave,
|
||||
selectedColumns = [],
|
||||
connectedColumns = {},
|
||||
} = data;
|
||||
|
||||
return (
|
||||
<div className="relative flex min-w-[280px] flex-col overflow-hidden rounded-lg border-2 border-gray-300 bg-white shadow-lg">
|
||||
@@ -42,17 +50,47 @@ export const TableNode: React.FC<{ data: TableNodeData }> = ({ data }) => {
|
||||
{/* 컬럼 목록 */}
|
||||
<div className="flex-1 overflow-hidden p-2" onMouseEnter={onScrollAreaEnter} onMouseLeave={onScrollAreaLeave}>
|
||||
<div className="space-y-1">
|
||||
{table.columns.map((column) => {
|
||||
{table.columns.map((column, index) => {
|
||||
const isSelected = selectedColumns.includes(column.name);
|
||||
const connectionInfo = connectedColumns[column.name];
|
||||
const isConnected = !!connectionInfo;
|
||||
|
||||
// 연결된 컬럼에만 핸들 표시
|
||||
const showSourceHandle =
|
||||
isConnected && (connectionInfo.direction === "source" || connectionInfo.direction === "both");
|
||||
const showTargetHandle =
|
||||
isConnected && (connectionInfo.direction === "target" || connectionInfo.direction === "both");
|
||||
|
||||
return (
|
||||
<div
|
||||
key={column.name}
|
||||
onClick={() => onColumnClick(table.tableName, column.name)}
|
||||
className={`cursor-pointer rounded px-2 py-1 text-xs transition-colors ${
|
||||
className={`relative cursor-pointer rounded px-2 py-1 text-xs transition-colors ${
|
||||
isSelected ? "bg-blue-100 text-blue-800 ring-2 ring-blue-500" : "text-gray-700 hover:bg-gray-100"
|
||||
}`}
|
||||
onClick={() => onColumnClick(table.tableName, column.name)}
|
||||
>
|
||||
{/* Target Handle (왼쪽) - 세련된 디자인 */}
|
||||
{showTargetHandle && (
|
||||
<Handle
|
||||
type="target"
|
||||
position={Position.Left}
|
||||
id={`${table.tableName}-${column.name}-target`}
|
||||
className="!absolute !left-[-6px] !h-2 !w-2 !rounded-full !border-0 !bg-blue-500 !shadow-sm hover:!bg-blue-600 hover:!shadow-md"
|
||||
style={{ top: "50%", transform: "translateY(-50%)" }}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Source Handle (오른쪽) - 세련된 디자인 */}
|
||||
{showSourceHandle && (
|
||||
<Handle
|
||||
type="source"
|
||||
position={Position.Right}
|
||||
id={`${table.tableName}-${column.name}-source`}
|
||||
className="!absolute !right-[-6px] !h-2 !w-2 !rounded-full !border-0 !bg-blue-500 !shadow-sm hover:!bg-blue-600 hover:!shadow-md"
|
||||
style={{ top: "50%", transform: "translateY(-50%)" }}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="font-mono font-medium">{column.name}</span>
|
||||
<span className="text-gray-500">{column.type}</span>
|
||||
|
||||
Reference in New Issue
Block a user