"use client"; /** * UnifiedSelect 설정 패널 * 통합 선택 컴포넌트의 세부 설정을 관리합니다. */ import React, { useState, useEffect, useCallback } from "react"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Separator } from "@/components/ui/separator"; import { Checkbox } from "@/components/ui/checkbox"; import { Button } from "@/components/ui/button"; import { Plus, Trash2, Loader2 } from "lucide-react"; import { apiClient } from "@/lib/api/client"; interface ColumnOption { columnName: string; columnLabel: string; } interface UnifiedSelectConfigPanelProps { config: Record; onChange: (config: Record) => void; /** 컬럼의 inputType (entity 타입인 경우에만 엔티티 소스 표시) */ inputType?: string; } export const UnifiedSelectConfigPanel: React.FC = ({ config, onChange, inputType, }) => { // 엔티티 타입인지 확인 const isEntityType = inputType === "entity"; // 엔티티 테이블의 컬럼 목록 const [entityColumns, setEntityColumns] = useState([]); const [loadingColumns, setLoadingColumns] = useState(false); // 설정 업데이트 핸들러 const updateConfig = (field: string, value: any) => { onChange({ ...config, [field]: value }); }; // 엔티티 테이블 변경 시 컬럼 목록 조회 const loadEntityColumns = useCallback(async (tableName: string) => { if (!tableName) { setEntityColumns([]); return; } setLoadingColumns(true); try { const response = await apiClient.get(`/table-management/tables/${tableName}/columns?size=500`); const data = response.data.data || response.data; const columns = data.columns || data || []; const columnOptions: ColumnOption[] = columns.map((col: any) => { const name = col.columnName || col.column_name || col.name; // displayName 우선 사용 const label = col.displayName || col.display_name || col.columnLabel || col.column_label || name; return { columnName: name, columnLabel: label, }; }); setEntityColumns(columnOptions); } catch (error) { console.error("컬럼 목록 조회 실패:", error); setEntityColumns([]); } finally { setLoadingColumns(false); } }, []); // 엔티티 테이블이 변경되면 컬럼 목록 로드 useEffect(() => { if (config.source === "entity" && config.entityTable) { loadEntityColumns(config.entityTable); } }, [config.source, config.entityTable, loadEntityColumns]); // 정적 옵션 관리 const options = config.options || []; const addOption = () => { const newOptions = [...options, { value: "", label: "" }]; updateConfig("options", newOptions); }; const updateOption = (index: number, field: "value" | "label", value: string) => { const newOptions = [...options]; newOptions[index] = { ...newOptions[index], [field]: value }; updateConfig("options", newOptions); }; const removeOption = (index: number) => { const newOptions = options.filter((_: any, i: number) => i !== index); updateConfig("options", newOptions); }; return (
{/* 선택 모드 */}
{/* 데이터 소스 */}
{/* 정적 옵션 관리 */} {config.source === "static" && (
{options.map((option: any, index: number) => (
updateOption(index, "value", e.target.value)} placeholder="값" className="h-7 text-xs flex-1" /> updateOption(index, "label", e.target.value)} placeholder="표시 텍스트" className="h-7 text-xs flex-1" />
))} {options.length === 0 && (

옵션을 추가해주세요

)}
)} {/* 공통 코드 설정 - 테이블 타입 관리에서 설정되므로 정보만 표시 */} {config.source === "code" && (
{config.codeGroup ? (

{config.codeGroup}

) : (

테이블 타입 관리에서 코드 그룹을 설정해주세요

)}
)} {/* 엔티티(참조 테이블) 설정 */} {config.source === "entity" && (

조인할 테이블명 (테이블 타입 관리에서 설정된 경우 자동 입력됨)

{/* 컬럼 로딩 중 표시 */} {loadingColumns && (
컬럼 목록 로딩 중...
)} {/* 컬럼 선택 - 테이블이 설정되어 있고 컬럼 목록이 있는 경우 Select로 표시 */}
{entityColumns.length > 0 ? ( ) : ( updateConfig("entityValueColumn", e.target.value)} placeholder="id" className="h-8 text-xs" /> )}

저장될 값

{entityColumns.length > 0 ? ( ) : ( updateConfig("entityLabelColumn", e.target.value)} placeholder="name" className="h-8 text-xs" /> )}

화면에 표시될 값

{/* 컬럼이 없는 경우 안내 */} {config.entityTable && !loadingColumns && entityColumns.length === 0 && (

테이블 컬럼을 조회할 수 없습니다. 테이블 타입 관리에서 참조 테이블을 설정해주세요.

)}
)} {/* 추가 옵션 */}
updateConfig("multiple", checked)} />
updateConfig("searchable", checked)} />
updateConfig("allowClear", checked)} />
{/* 다중 선택 시 최대 개수 */} {config.multiple && (
updateConfig("maxSelect", e.target.value ? Number(e.target.value) : undefined)} placeholder="제한 없음" min="1" className="h-8 text-xs" />
)}
); }; UnifiedSelectConfigPanel.displayName = "UnifiedSelectConfigPanel"; export default UnifiedSelectConfigPanel;