"use client"; /** * 테이블 소스 노드 속성 편집 */ import { useEffect, useState } from "react"; import { Check, ChevronsUpDown } from "lucide-react"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { cn } from "@/lib/utils"; import { useFlowEditorStore } from "@/lib/stores/flowEditorStore"; import { tableTypeApi } from "@/lib/api/screen"; import type { TableSourceNodeData } from "@/types/node-editor"; interface TableSourcePropertiesProps { nodeId: string; data: TableSourceNodeData; } interface TableOption { tableName: string; displayName: string; description: string; label: string; // 표시용 (라벨 또는 테이블명) } export function TableSourceProperties({ nodeId, data }: TableSourcePropertiesProps) { const { updateNode } = useFlowEditorStore(); const [displayName, setDisplayName] = useState(data.displayName || data.tableName); const [tableName, setTableName] = useState(data.tableName); // 테이블 선택 관련 상태 const [tables, setTables] = useState([]); const [loading, setLoading] = useState(false); const [open, setOpen] = useState(false); // 데이터 변경 시 로컬 상태 업데이트 useEffect(() => { setDisplayName(data.displayName || data.tableName); setTableName(data.tableName); }, [data.displayName, data.tableName]); // 테이블 목록 로딩 useEffect(() => { loadTables(); }, []); /** * 테이블 목록 로드 */ const loadTables = async () => { try { setLoading(true); console.log("🔍 테이블 목록 로딩 중..."); const tableList = await tableTypeApi.getTables(); // 테이블 목록 변환 (라벨 또는 displayName 우선 표시) const options: TableOption[] = tableList.map((table) => { // tableLabel이 있으면 우선 사용, 없으면 displayName, 그것도 없으면 tableName const label = (table as any).tableLabel || table.displayName || table.tableName || "알 수 없는 테이블"; return { tableName: table.tableName, displayName: table.displayName || table.tableName, description: table.description || "", label, }; }); setTables(options); console.log(`✅ 테이블 ${options.length}개 로딩 완료`); } catch (error) { console.error("❌ 테이블 목록 로딩 실패:", error); setTables([]); } finally { setLoading(false); } }; /** * 테이블 선택 핸들러 (즉시 노드 업데이트 + 컬럼 로드) */ const handleTableSelect = async (selectedTableName: string) => { const selectedTable = tables.find((t) => t.tableName === selectedTableName); if (selectedTable) { const newTableName = selectedTable.tableName; const newDisplayName = selectedTable.label; setTableName(newTableName); setDisplayName(newDisplayName); setOpen(false); // 컬럼 정보 로드 console.log(`🔍 테이블 "${newTableName}" 컬럼 로드 중...`); try { const columns = await tableTypeApi.getColumns(newTableName); console.log("🔍 API에서 받은 컬럼 데이터:", columns); const fields = columns.map((col: any) => ({ name: col.column_name || col.columnName, type: col.data_type || col.dataType || "unknown", nullable: col.is_nullable === "YES" || col.isNullable === true, // displayName이 라벨입니다! label: col.displayName || col.label_ko || col.columnLabel || col.column_label, })); console.log(`✅ ${fields.length}개 컬럼 로드 완료:`, fields); // 필드 정보와 함께 노드 업데이트 updateNode(nodeId, { displayName: newDisplayName, tableName: newTableName, fields, }); } catch (error) { console.error("❌ 컬럼 로드 실패:", error); // 실패해도 테이블 정보는 업데이트 updateNode(nodeId, { displayName: newDisplayName, tableName: newTableName, fields: [], }); } console.log(`✅ 테이블 선택: ${newTableName} (${newDisplayName})`); } }; /** * 표시 이름 변경 핸들러 */ const handleDisplayNameChange = (newDisplayName: string) => { setDisplayName(newDisplayName); updateNode(nodeId, { displayName: newDisplayName, tableName, }); }; // 현재 선택된 테이블의 라벨 찾기 const selectedTableLabel = tables.find((t) => t.tableName === tableName)?.label || tableName; return (
{/* 기본 정보 */}

기본 정보

handleDisplayNameChange(e.target.value)} className="mt-1" placeholder="노드 표시 이름" />
{/* 테이블 선택 Combobox */}
검색 결과가 없습니다. {tables.map((table) => ( handleTableSelect(table.tableName)} className="cursor-pointer" >
{table.label} {table.label !== table.tableName && ( {table.tableName} )} {table.description && ( {table.description} )}
))}
{tableName && selectedTableLabel !== tableName && (

실제 테이블명: {tableName}

)}
{/* 필드 정보 */}

출력 필드

{data.fields && data.fields.length > 0 ? (
{data.fields.map((field) => (
{field.name} {field.type}
))}
) : (
필드 정보가 없습니다
)}
{/* 안내 */}
✅ 변경 사항이 즉시 노드에 반영됩니다.
); }