"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"; import { categoryValueCascadingApi, CategoryValueCascadingGroup } from "@/lib/api/categoryValueCascading"; 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); // 🆕 카테고리 값 연쇄관계 상태 const [categoryRelationEnabled, setCategoryRelationEnabled] = useState(!!(config as any).categoryRelationCode); const [categoryRelationList, setCategoryRelationList] = useState([]); const [loadingCategoryRelations, setLoadingCategoryRelations] = useState(false); // 연쇄 관계 목록 로드 useEffect(() => { if (cascadingEnabled && relationList.length === 0) { loadRelationList(); } }, [cascadingEnabled]); // 🆕 카테고리 값 연쇄관계 목록 로드 useEffect(() => { if (categoryRelationEnabled && categoryRelationList.length === 0) { loadCategoryRelationList(); } }, [categoryRelationEnabled]); // config 변경 시 상태 동기화 useEffect(() => { setCascadingEnabled(!!config.cascadingRelationCode); setCategoryRelationEnabled(!!(config as any).categoryRelationCode); }, [config.cascadingRelationCode, (config as any).categoryRelationCode]); 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 loadCategoryRelationList = async () => { setLoadingCategoryRelations(true); try { const response = await categoryValueCascadingApi.getGroups("Y"); if (response.success && response.data) { setCategoryRelationList(response.data); } } catch (error) { console.error("카테고리 값 연쇄관계 목록 로드 실패:", error); } finally { setLoadingCategoryRelations(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(); // 카테고리 값 연쇄관계 비활성화 (둘 중 하나만 사용) if (categoryRelationEnabled) { setCategoryRelationEnabled(false); onChange({ ...config, categoryRelationCode: undefined } as any); } } }; // 🆕 카테고리 값 연쇄관계 토글 const handleCategoryRelationToggle = (enabled: boolean) => { setCategoryRelationEnabled(enabled); if (!enabled) { // 비활성화 시 관계 설정 제거 const newConfig = { ...config, categoryRelationCode: undefined, cascadingRole: undefined, cascadingParentField: undefined, } as any; onChange(newConfig); } else { loadCategoryRelationList(); // 일반 연쇄관계 비활성화 (둘 중 하나만 사용) if (cascadingEnabled) { setCascadingEnabled(false); onChange({ ...config, cascadingRelationCode: undefined }); } } }; // 🆕 같은 연쇄 관계의 부모 역할 컴포넌트 찾기 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 expectedParentColumn = selectedRelation?.parent_value_column; // 부모 역할에 맞는 컴포넌트만 필터링 const parentFieldCandidates = allComponents.filter((comp) => { // 현재 컴포넌트 제외 if (currentComponent && comp.id === currentComponent.id) return false; // 관계에서 지정한 부모 컬럼명과 일치하는 컴포넌트만 if (expectedParentColumn && comp.columnName !== expectedParentColumn) return false; // columnName이 있어야 함 return !!comp.columnName; }); return (
{expectedParentColumn && (

관계에서 지정된 부모 컬럼: {expectedParentColumn}

)}

상위 값을 제공할 필드를 선택하세요.

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

부모 카테고리 값 선택에 따라 자식 카테고리 옵션이 변경됩니다.
예: 검사유형 선택 시 해당 유형에 맞는 적용대상만 표시

{categoryRelationEnabled && (
{/* 관계 선택 */}
{/* 역할 선택 */} {(config as any).categoryRelationCode && (

{config.cascadingRole === "parent" ? "이 필드가 상위 카테고리 선택 역할을 합니다. (예: 검사유형)" : config.cascadingRole === "child" ? "이 필드는 상위 카테고리 값에 따라 옵션이 변경됩니다. (예: 적용대상)" : "이 필드의 역할을 선택하세요."}

)} {/* 부모 필드 설정 (자식 역할일 때만) */} {(config as any).categoryRelationCode && config.cascadingRole === "child" && (() => { // 선택된 관계 정보 가져오기 const selectedRelation = categoryRelationList.find( (r) => r.relation_code === (config as any).categoryRelationCode ); const expectedParentColumn = selectedRelation?.parent_column_name; // 부모 역할에 맞는 컴포넌트만 필터링 const parentFieldCandidates = allComponents.filter((comp) => { // 현재 컴포넌트 제외 if (currentComponent && comp.id === currentComponent.id) return false; // 관계에서 지정한 부모 컬럼명과 일치하는 컴포넌트만 if (expectedParentColumn && comp.columnName !== expectedParentColumn) return false; // columnName이 있어야 함 return !!comp.columnName; }); return (
{expectedParentColumn && (

관계에서 지정된 부모 컬럼: {expectedParentColumn}

)}

상위 카테고리 값을 제공할 필드를 선택하세요.

); })()} {/* 관계 관리 페이지 링크 */}
)}
); };