"use client"; import React, { useState, useEffect } from "react"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Checkbox } from "@/components/ui/checkbox"; import { Switch } from "@/components/ui/switch"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Button } from "@/components/ui/button"; import { Link2, ExternalLink } from "lucide-react"; import Link from "next/link"; import { SelectBasicConfig } from "./types"; import { cascadingRelationApi, CascadingRelation } from "@/lib/api/cascadingRelation"; export interface SelectBasicConfigPanelProps { config: SelectBasicConfig; onChange: (config: Partial) => void; /** 현재 화면의 모든 컴포넌트 목록 (부모 필드 자동 감지용) */ allComponents?: any[]; /** 현재 컴포넌트 정보 */ currentComponent?: any; } /** * SelectBasic 설정 패널 * 컴포넌트의 설정값들을 편집할 수 있는 UI 제공 */ export const SelectBasicConfigPanel: React.FC = ({ config, onChange, allComponents = [], currentComponent, }) => { // 연쇄 드롭다운 관련 상태 const [cascadingEnabled, setCascadingEnabled] = useState(!!config.cascadingRelationCode); const [relationList, setRelationList] = useState([]); const [loadingRelations, setLoadingRelations] = useState(false); // 연쇄 관계 목록 로드 useEffect(() => { if (cascadingEnabled && relationList.length === 0) { loadRelationList(); } }, [cascadingEnabled]); // config 변경 시 상태 동기화 useEffect(() => { setCascadingEnabled(!!config.cascadingRelationCode); }, [config.cascadingRelationCode]); const loadRelationList = async () => { setLoadingRelations(true); try { const response = await cascadingRelationApi.getList("Y"); if (response.success && response.data) { setRelationList(response.data); } } catch (error) { console.error("연쇄 관계 목록 로드 실패:", error); } finally { setLoadingRelations(false); } }; const handleChange = (key: keyof SelectBasicConfig, value: any) => { // 기존 config와 병합하여 전체 객체 전달 (다른 속성 보호) const newConfig = { ...config, [key]: value }; onChange(newConfig); }; // 연쇄 드롭다운 토글 const handleCascadingToggle = (enabled: boolean) => { setCascadingEnabled(enabled); if (!enabled) { // 비활성화 시 관계 설정 제거 const newConfig = { ...config, cascadingRelationCode: undefined, cascadingRole: undefined, cascadingParentField: undefined, }; onChange(newConfig); } else { loadRelationList(); } }; // 🆕 같은 연쇄 관계의 부모 역할 컴포넌트 찾기 const findParentComponent = (relationCode: string) => { console.log("🔍 findParentComponent 호출:", { relationCode, allComponentsLength: allComponents?.length, currentComponentId: currentComponent?.id, }); if (!allComponents || allComponents.length === 0) { console.log("❌ allComponents가 비어있음"); return null; } // 모든 컴포넌트의 cascading 설정 확인 allComponents.forEach((comp: any) => { const compConfig = comp.componentConfig || {}; if (compConfig.cascadingRelationCode) { console.log("📦 컴포넌트 cascading 설정:", { id: comp.id, columnName: comp.columnName, cascadingRelationCode: compConfig.cascadingRelationCode, cascadingRole: compConfig.cascadingRole, }); } }); const found = allComponents.find((comp: any) => { const compConfig = comp.componentConfig || {}; return ( comp.id !== currentComponent?.id && // 자기 자신 제외 compConfig.cascadingRelationCode === relationCode && compConfig.cascadingRole === "parent" ); }); console.log("🔍 찾은 부모 컴포넌트:", found); return found; }; // 역할 변경 시 부모 필드 자동 감지 const handleRoleChange = (role: "parent" | "child") => { let parentField = config.cascadingParentField; // 자식 역할 선택 시 부모 필드 자동 감지 if (role === "child" && config.cascadingRelationCode) { const parentComp = findParentComponent(config.cascadingRelationCode); if (parentComp) { parentField = parentComp.columnName; console.log("🔗 부모 필드 자동 감지:", parentField); } } const newConfig = { ...config, cascadingRole: role, // 부모 역할일 때는 부모 필드 불필요, 자식일 때는 자동 감지된 값 또는 기존 값 cascadingParentField: role === "parent" ? undefined : parentField, }; onChange(newConfig); }; // 선택된 관계 정보 const selectedRelation = relationList.find(r => r.relation_code === config.cascadingRelationCode); return (
select-basic 설정
{/* select 관련 설정 */}
handleChange("placeholder", e.target.value)} />
{/* 공통 설정 */}
handleChange("disabled", checked)} />
handleChange("required", checked)} />
handleChange("readonly", checked)} />
handleChange("multiple", checked)} />
{/* 연쇄 드롭다운 설정 */}

다른 필드의 값에 따라 옵션이 동적으로 변경됩니다.

{cascadingEnabled && (
{/* 관계 선택 */}
{/* 역할 선택 */} {config.cascadingRelationCode && (

{config.cascadingRole === "parent" ? "이 필드가 상위 선택 역할을 합니다. (예: 창고 선택)" : config.cascadingRole === "child" ? "이 필드는 상위 필드 값에 따라 옵션이 변경됩니다. (예: 위치 선택)" : "이 필드의 역할을 선택하세요."}

)} {/* 부모 필드 설정 (자식 역할일 때만) */} {config.cascadingRelationCode && config.cascadingRole === "child" && (
{(() => { const parentComp = findParentComponent(config.cascadingRelationCode); const isAutoDetected = parentComp && config.cascadingParentField === parentComp.columnName; return ( <>
handleChange("cascadingParentField", e.target.value || undefined)} placeholder="예: warehouse_code" className="text-xs flex-1" /> {parentComp && !isAutoDetected && ( )}
{isAutoDetected ? (

자동 감지됨: {parentComp.label || parentComp.columnName}

) : parentComp ? (

감지된 부모 필드: {parentComp.columnName} ({parentComp.label || "라벨 없음"})

) : (

같은 관계의 부모 역할 필드가 없습니다. 수동으로 입력하세요.

)} ); })()}
)} {/* 선택된 관계 정보 표시 */} {selectedRelation && config.cascadingRole && (
{config.cascadingRole === "parent" ? ( <>
부모 역할 (상위 선택)
데이터 소스:{" "} {selectedRelation.parent_table}
저장 값:{" "} {selectedRelation.parent_value_column}
) : ( <>
자식 역할 (하위 선택)
데이터 소스:{" "} {selectedRelation.child_table}
필터 기준:{" "} {selectedRelation.child_filter_column}
저장 값:{" "} {selectedRelation.child_value_column}
)}
)} {/* 관계 관리 페이지 링크 */}
)}
); };