"use client"; import React, { useState, useMemo, useEffect } from "react"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Switch } from "@/components/ui/switch"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Slider } from "@/components/ui/slider"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem } from "@/components/ui/command"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { Button } from "@/components/ui/button"; import { Check, ChevronsUpDown, ArrowRight } from "lucide-react"; import { cn } from "@/lib/utils"; import { SplitPanelLayoutConfig } from "./types"; import { TableInfo, ColumnInfo } from "@/types/screen"; import { tableTypeApi } from "@/lib/api/screen"; interface SplitPanelLayoutConfigPanelProps { config: SplitPanelLayoutConfig; onChange: (config: SplitPanelLayoutConfig) => void; tables?: TableInfo[]; // 전체 테이블 목록 (선택적) screenTableName?: string; // 현재 화면의 테이블명 (좌측 패널에서 사용) } /** * SplitPanelLayout 설정 패널 */ export const SplitPanelLayoutConfigPanel: React.FC = ({ config, onChange, tables = [], // 기본값 빈 배열 screenTableName, // 현재 화면의 테이블명 }) => { const [rightTableOpen, setRightTableOpen] = useState(false); const [leftColumnOpen, setLeftColumnOpen] = useState(false); const [rightColumnOpen, setRightColumnOpen] = useState(false); const [loadedTableColumns, setLoadedTableColumns] = useState>({}); const [loadingColumns, setLoadingColumns] = useState>({}); // screenTableName이 변경되면 좌측 패널 테이블을 항상 화면 테이블로 설정 useEffect(() => { if (screenTableName) { // 좌측 패널은 항상 현재 화면의 테이블 사용 if (config.leftPanel?.tableName !== screenTableName) { updateLeftPanel({ tableName: screenTableName }); } } // eslint-disable-next-line react-hooks/exhaustive-deps }, [screenTableName]); // 테이블 컬럼 로드 함수 const loadTableColumns = async (tableName: string) => { if (loadedTableColumns[tableName] || loadingColumns[tableName]) { return; // 이미 로드되었거나 로딩 중 } setLoadingColumns((prev) => ({ ...prev, [tableName]: true })); try { const columnsResponse = await tableTypeApi.getColumns(tableName); console.log(`📊 테이블 ${tableName} 컬럼 응답:`, columnsResponse); const columns: ColumnInfo[] = (columnsResponse || []).map((col: any) => ({ tableName: col.tableName || tableName, columnName: col.columnName || col.column_name, columnLabel: col.displayName || col.columnLabel || col.column_label || col.columnName || col.column_name, dataType: col.dataType || col.data_type || col.dbType, webType: col.webType || col.web_type, input_type: col.inputType || col.input_type, widgetType: col.widgetType || col.widget_type || col.webType || col.web_type, isNullable: col.isNullable || col.is_nullable, required: col.required !== undefined ? col.required : col.isNullable === "NO" || col.is_nullable === "NO", columnDefault: col.columnDefault || col.column_default, characterMaximumLength: col.characterMaximumLength || col.character_maximum_length, codeCategory: col.codeCategory || col.code_category, codeValue: col.codeValue || col.code_value, })); console.log(`✅ 테이블 ${tableName} 컬럼 ${columns.length}개 로드됨:`, columns); setLoadedTableColumns((prev) => ({ ...prev, [tableName]: columns })); } catch (error) { console.error(`테이블 ${tableName} 컬럼 로드 실패:`, error); setLoadedTableColumns((prev) => ({ ...prev, [tableName]: [] })); } finally { setLoadingColumns((prev) => ({ ...prev, [tableName]: false })); } }; // 좌측/우측 테이블이 변경되면 해당 테이블의 컬럼 로드 useEffect(() => { if (config.leftPanel?.tableName) { loadTableColumns(config.leftPanel.tableName); } }, [config.leftPanel?.tableName]); useEffect(() => { if (config.rightPanel?.tableName) { loadTableColumns(config.rightPanel.tableName); } }, [config.rightPanel?.tableName]); console.log("🔧 SplitPanelLayoutConfigPanel 렌더링"); console.log(" - config:", config); console.log(" - tables:", tables); console.log(" - tablesCount:", tables.length); console.log(" - screenTableName:", screenTableName); console.log(" - leftTable:", config.leftPanel?.tableName); console.log(" - rightTable:", config.rightPanel?.tableName); const updateConfig = (updates: Partial) => { const newConfig = { ...config, ...updates }; console.log("🔄 Config 업데이트:", newConfig); onChange(newConfig); }; const updateLeftPanel = (updates: Partial) => { const newConfig = { ...config, leftPanel: { ...config.leftPanel, ...updates }, }; console.log("🔄 Left Panel 업데이트:", newConfig); onChange(newConfig); }; const updateRightPanel = (updates: Partial) => { const newConfig = { ...config, rightPanel: { ...config.rightPanel, ...updates }, }; console.log("🔄 Right Panel 업데이트:", newConfig); onChange(newConfig); }; // 좌측 테이블 컬럼 (로드된 컬럼 사용) const leftTableColumns = useMemo(() => { const tableName = config.leftPanel?.tableName || screenTableName; return tableName ? loadedTableColumns[tableName] || [] : []; }, [loadedTableColumns, config.leftPanel?.tableName, screenTableName]); // 우측 테이블 컬럼 (로드된 컬럼 사용) const rightTableColumns = useMemo(() => { const tableName = config.rightPanel?.tableName; return tableName ? loadedTableColumns[tableName] || [] : []; }, [loadedTableColumns, config.rightPanel?.tableName]); // 테이블 데이터 로딩 상태 확인 if (!tables || tables.length === 0) { return (

테이블 데이터를 불러올 수 없습니다.

화면에 테이블이 연결되지 않았거나 테이블 목록이 로드되지 않았습니다.

); } // 관계 타입에 따라 우측 테이블을 자동으로 설정 const relationshipType = config.rightPanel?.relation?.type || "detail"; return (
{/* 관계 타입 선택 */}

패널 관계 타입

{/* 좌측 패널 설정 (마스터) */}

좌측 패널 설정 (마스터)

updateLeftPanel({ title: e.target.value })} placeholder="좌측 패널 제목" />

{config.leftPanel?.tableName || screenTableName || "테이블이 지정되지 않음"}

좌측 패널은 현재 화면의 테이블 데이터를 표시합니다

updateLeftPanel({ showSearch: checked })} />
updateLeftPanel({ showAdd: checked })} />
{/* 우측 패널 설정 */}

우측 패널 설정 ({relationshipType === "detail" ? "상세" : "조인"})

updateRightPanel({ title: e.target.value })} placeholder="우측 패널 제목" />
{/* 관계 타입에 따라 테이블 선택 UI 변경 */} {relationshipType === "detail" ? ( // 상세 모드: 좌측과 동일한 테이블 (자동 설정)

{config.leftPanel?.tableName || screenTableName || "테이블이 지정되지 않음"}

상세 모드에서는 좌측과 동일한 테이블을 사용합니다

) : ( // 조인 모드: 전체 테이블에서 선택 가능
테이블을 찾을 수 없습니다. {tables.map((table) => ( { updateRightPanel({ tableName: value }); setRightTableOpen(false); }} > {table.tableName} ({table.tableLabel || ""}) ))}
)} {/* 컬럼 매핑 - 조인 모드에서만 표시 */} {relationshipType !== "detail" && (

좌측 테이블의 컬럼을 우측 테이블의 컬럼과 연결합니다

컬럼을 찾을 수 없습니다. {leftTableColumns.map((column) => ( { updateRightPanel({ relation: { ...config.rightPanel?.relation, leftColumn: value }, }); setLeftColumnOpen(false); }} > {column.columnName} ({column.columnLabel || ""}) ))}
컬럼을 찾을 수 없습니다. {rightTableColumns.map((column) => ( { updateRightPanel({ relation: { ...config.rightPanel?.relation, foreignKey: value }, }); setRightColumnOpen(false); }} > {column.columnName} ({column.columnLabel || ""}) ))}
)}
updateRightPanel({ showSearch: checked })} />
updateRightPanel({ showAdd: checked })} />
{/* 레이아웃 설정 */}

레이아웃 설정

updateConfig({ splitRatio: value[0] })} min={20} max={80} step={5} />
updateConfig({ resizable: checked })} />
updateConfig({ autoLoad: checked })} />
); };