64 lines
2.2 KiB
TypeScript
64 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import React from "react";
|
|
|
|
interface TableColumn {
|
|
name: string;
|
|
type: string;
|
|
description: string;
|
|
}
|
|
|
|
interface Table {
|
|
tableName: string;
|
|
displayName: string;
|
|
description: string;
|
|
columns: TableColumn[];
|
|
}
|
|
|
|
interface TableNodeData {
|
|
table: Table;
|
|
onColumnClick: (tableName: string, columnName: string) => void;
|
|
onScrollAreaEnter?: () => void;
|
|
onScrollAreaLeave?: () => void;
|
|
selectedColumns?: string[]; // 선택된 컬럼 목록
|
|
}
|
|
|
|
export const TableNode: React.FC<{ data: TableNodeData }> = ({ data }) => {
|
|
const { table, onColumnClick, onScrollAreaEnter, onScrollAreaLeave, selectedColumns = [] } = data;
|
|
|
|
return (
|
|
<div className="relative flex min-w-[280px] flex-col overflow-hidden rounded-lg border-2 border-gray-300 bg-white shadow-lg">
|
|
{/* 테이블 헤더 */}
|
|
<div className="bg-blue-600 p-3 text-white">
|
|
<h3 className="truncate text-sm font-semibold">{table.displayName}</h3>
|
|
{table.description && <p className="mt-1 truncate text-xs opacity-75">{table.description}</p>}
|
|
</div>
|
|
|
|
{/* 컬럼 목록 */}
|
|
<div className="flex-1 overflow-hidden p-2" onMouseEnter={onScrollAreaEnter} onMouseLeave={onScrollAreaLeave}>
|
|
<div className="space-y-1">
|
|
{table.columns.map((column) => {
|
|
const isSelected = selectedColumns.includes(column.name);
|
|
|
|
return (
|
|
<div
|
|
key={column.name}
|
|
onClick={() => onColumnClick(table.tableName, column.name)}
|
|
className={`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"
|
|
}`}
|
|
>
|
|
<div className="flex items-center justify-between">
|
|
<span className="font-mono font-medium">{column.name}</span>
|
|
<span className="text-gray-500">{column.type}</span>
|
|
</div>
|
|
{column.description && <div className="mt-0.5 text-gray-500">{column.description}</div>}
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|