"use client"; /** * V2Hierarchy 설정 패널 * 토스식 단계별 UX: 계층 타입 카드 선택 -> 데이터 소스 설정 -> 고급 설정(접힘) */ import React, { useState, useEffect } 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 { Switch } from "@/components/ui/switch"; import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"; import { GitFork, Building2, Layers, ListTree, Database, FileJson, Globe, Settings, ChevronDown, Loader2, } from "lucide-react"; import { cn } from "@/lib/utils"; import { tableTypeApi } from "@/lib/api/screen"; interface V2HierarchyConfigPanelProps { config: Record; onChange: (config: Record) => void; } interface TableOption { tableName: string; displayName: string; } interface ColumnOption { columnName: string; displayName: string; } const HIERARCHY_TYPE_CARDS = [ { value: "tree", icon: GitFork, title: "트리", description: "계층 구조를 표시해요" }, { value: "org-chart", icon: Building2, title: "조직도", description: "조직 구조를 보여줘요" }, { value: "bom", icon: Layers, title: "BOM", description: "부품 구성을 관리해요" }, { value: "cascading", icon: ListTree, title: "연쇄 선택", description: "단계별로 선택해요" }, ] as const; const DATA_SOURCE_CARDS = [ { value: "static", icon: FileJson, title: "정적 데이터", description: "직접 입력해요" }, { value: "db", icon: Database, title: "데이터베이스", description: "테이블에서 가져와요" }, { value: "api", icon: Globe, title: "API", description: "외부 API로 조회해요" }, ] as const; export const V2HierarchyConfigPanel: React.FC = ({ config, onChange, }) => { const [tables, setTables] = useState([]); const [loadingTables, setLoadingTables] = useState(false); const [columns, setColumns] = useState([]); const [loadingColumns, setLoadingColumns] = useState(false); const [advancedOpen, setAdvancedOpen] = useState(false); const updateConfig = (field: string, value: any) => { onChange({ ...config, [field]: value }); }; useEffect(() => { const loadTables = async () => { setLoadingTables(true); try { const data = await tableTypeApi.getTables(); setTables(data.map(t => ({ tableName: t.tableName, displayName: t.displayName || t.tableName }))); } catch (error) { console.error("테이블 목록 로드 실패:", error); } finally { setLoadingTables(false); } }; loadTables(); }, []); useEffect(() => { const loadColumns = async () => { if (!config.tableName) { setColumns([]); return; } setLoadingColumns(true); try { const data = await tableTypeApi.getColumns(config.tableName); setColumns(data.map((c: any) => ({ columnName: c.columnName || c.column_name, displayName: c.displayName || c.columnName || c.column_name }))); } catch (error) { console.error("컬럼 목록 로드 실패:", error); } finally { setLoadingColumns(false); } }; loadColumns(); }, [config.tableName]); const hierarchyType = config.hierarchyType || config.type || "tree"; const dataSource = config.dataSource || "static"; return (
{/* ─── 1단계: 계층 타입 선택 (카드) ─── */}

어떤 계층 구조를 사용하나요?

{HIERARCHY_TYPE_CARDS.map((card) => { const Icon = card.icon; const isSelected = hierarchyType === card.value; return ( ); })}
{/* ─── 2단계: 표시 방식 ─── */}
표시 방식

데이터를 어떤 형태로 보여줄지 선택해요

{/* ─── 3단계: 데이터 소스 선택 (카드) ─── */}

데이터는 어디서 가져오나요?

{DATA_SOURCE_CARDS.map((card) => { const Icon = card.icon; const isSelected = dataSource === card.value; return ( ); })}
{/* ─── DB 소스 설정 ─── */} {dataSource === "db" && (
테이블 설정

데이터 테이블

{loadingTables ? (
테이블 로딩 중...
) : ( )}
{config.tableName && ( <> {loadingColumns ? (
컬럼 로딩 중...
) : ( <>

컬럼 매핑

표시 컬럼

)} )}
)} {/* ─── API 소스 설정 ─── */} {dataSource === "api" && (
API 설정

엔드포인트 URL

updateConfig("apiEndpoint", e.target.value)} placeholder="/api/hierarchy" className="h-8 text-sm" />
)} {/* ─── BOM 전용 설정 ─── */} {hierarchyType === "bom" && (
BOM 설정

수량 표시

부품별 수량이 표시돼요

updateConfig("showQuantity", checked)} />
수량 컬럼
)} {/* ─── Cascading 전용 설정 ─── */} {hierarchyType === "cascading" && (
연쇄 선택 설정
부모 필드

부모 변경 시 초기화

상위 항목이 바뀌면 하위 선택이 초기화돼요

updateConfig("clearOnParentChange", checked)} />
)} {/* ─── 고급 설정 (Collapsible) ─── */}
{/* 최대 레벨 */}
최대 레벨 updateConfig("maxLevel", e.target.value ? Number(e.target.value) : undefined)} placeholder="제한 없음" min="1" className="h-7 w-[120px] text-xs" />
{/* 토글 옵션들 */}

드래그 앤 드롭

항목을 끌어서 위치를 변경할 수 있어요

updateConfig("draggable", checked)} />

선택 가능

항목을 클릭해서 선택할 수 있어요

updateConfig("selectable", checked)} />

다중 선택

여러 항목을 동시에 선택할 수 있어요

updateConfig("multiSelect", checked)} />

체크박스 표시

각 항목에 체크박스가 표시돼요

updateConfig("showCheckbox", checked)} />

기본 전체 펼침

처음부터 모든 노드가 열려있어요

updateConfig("expandAll", checked)} />
); }; V2HierarchyConfigPanel.displayName = "V2HierarchyConfigPanel"; export default V2HierarchyConfigPanel;