ERP-node/frontend/components/dataflow/ScreenNode.tsx

110 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import React from "react";
import { Handle, Position } from "@xyflow/react";
interface ScreenField {
name: string;
type: string;
description: string;
}
interface Screen {
screenId: string;
screenName: string;
screenCode: string;
tableName: string;
fields: ScreenField[];
}
interface ScreenNodeData {
screen: Screen;
onFieldClick: (screenId: string, fieldName: string) => void;
}
export const ScreenNode: React.FC<{ data: ScreenNodeData }> = ({ data }) => {
const { screen, onFieldClick } = data;
// 필드 타입에 따른 색상 반환
const getFieldTypeColor = (type: string) => {
if (type.includes("INTEGER") || type.includes("NUMERIC")) return "text-blue-600 bg-blue-50";
if (type.includes("VARCHAR") || type.includes("TEXT")) return "text-green-600 bg-green-50";
if (type.includes("TIMESTAMP") || type.includes("DATE")) return "text-purple-600 bg-purple-50";
if (type.includes("BOOLEAN")) return "text-orange-600 bg-orange-50";
return "text-gray-600 bg-gray-50";
};
return (
<div className="max-w-96 min-w-80 rounded-lg border-2 border-gray-300 bg-white shadow-lg transition-shadow hover:shadow-xl">
{/* 노드 헤더 */}
<div className="rounded-t-lg bg-gradient-to-r from-blue-500 to-blue-600 p-4 text-white">
<div className="mb-1 text-base font-bold">{screen.screenName}</div>
<div className="mb-1 text-sm opacity-90">ID: {screen.screenCode}</div>
<div className="flex items-center text-xs opacity-75">
<span className="mr-1">🗃</span>
: {screen.tableName}
</div>
</div>
{/* 필드 목록 */}
<div className="p-4">
<div className="mb-3 flex items-center justify-between">
<div className="text-sm font-semibold text-gray-700"> </div>
<div className="rounded-full bg-gray-100 px-2 py-1 text-xs text-gray-500">{screen.fields.length}</div>
</div>
<div className="max-h-64 space-y-2 overflow-y-auto">
{screen.fields.map((field, index) => (
<div
key={field.name}
className="flex cursor-pointer items-center justify-between rounded-lg border border-transparent p-3 transition-colors hover:border-gray-200 hover:bg-gray-50"
onClick={() => onFieldClick(screen.screenId, field.name)}
>
<div className="min-w-0 flex-1">
<div className="mb-1 flex items-center">
<div className="truncate text-sm font-medium text-gray-900">{field.name}</div>
{index === 0 && (
<span className="ml-2 rounded bg-yellow-100 px-1.5 py-0.5 text-xs text-yellow-800">PK</span>
)}
</div>
<div className="truncate text-xs text-gray-500">{field.description}</div>
</div>
<div className={`ml-2 rounded px-2 py-1 font-mono text-xs ${getFieldTypeColor(field.type)}`}>
{field.type}
</div>
</div>
))}
</div>
</div>
{/* React Flow 핸들 */}
<Handle
type="source"
position={Position.Right}
className="h-4 w-4 border-2 border-white bg-blue-500 shadow-md transition-colors hover:bg-blue-600"
title="연결 시작점"
/>
<Handle
type="target"
position={Position.Left}
className="h-4 w-4 border-2 border-white bg-green-500 shadow-md transition-colors hover:bg-green-600"
title="연결 도착점"
/>
{/* 추가 핸들들 (상하) */}
<Handle
type="source"
position={Position.Bottom}
className="h-4 w-4 border-2 border-white bg-blue-500 shadow-md transition-colors hover:bg-blue-600"
id="bottom-source"
/>
<Handle
type="target"
position={Position.Top}
className="h-4 w-4 border-2 border-white bg-green-500 shadow-md transition-colors hover:bg-green-600"
id="top-target"
/>
</div>
);
};