"use client"; import { useState, useEffect } from "react"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; import { Checkbox } from "@/components/ui/checkbox"; import { Plus } from "lucide-react"; import { toast } from "sonner"; import { createColumnMapping } from "@/lib/api/tableCategoryValue"; import { tableManagementApi } from "@/lib/api/tableManagement"; import { apiClient } from "@/lib/api/client"; interface SecondLevelMenu { menuObjid: number; menuName: string; parentMenuName: string; screenCode?: string; } interface AddCategoryColumnDialogProps { tableName: string; onSuccess: () => void; } /** * 카테고리 컬럼 추가 다이얼로그 * * 논리적 컬럼명과 물리적 컬럼명을 매핑하여 메뉴별로 독립적인 카테고리 관리 가능 * * 2레벨 메뉴를 선택하면 해당 메뉴의 모든 하위 메뉴에서 사용 가능 */ export function AddCategoryColumnDialog({ tableName, onSuccess, }: AddCategoryColumnDialogProps) { const [open, setOpen] = useState(false); const [loading, setLoading] = useState(false); const [physicalColumns, setPhysicalColumns] = useState([]); const [secondLevelMenus, setSecondLevelMenus] = useState([]); const [selectedMenus, setSelectedMenus] = useState([]); const [logicalColumnName, setLogicalColumnName] = useState(""); const [physicalColumnName, setPhysicalColumnName] = useState(""); const [description, setDescription] = useState(""); // 다이얼로그 열릴 때 데이터 로드 useEffect(() => { if (open) { loadPhysicalColumns(); loadSecondLevelMenus(); } }, [open, tableName]); // 테이블의 실제 컬럼 목록 조회 const loadPhysicalColumns = async () => { try { const response = await tableManagementApi.getTableColumns(tableName); if (response.success && response.data) { setPhysicalColumns(response.data.map((col: any) => col.columnName)); } } catch (error) { console.error("컬럼 목록 조회 실패:", error); toast.error("컬럼 목록을 불러올 수 없습니다"); } }; // 2레벨 메뉴 목록 조회 const loadSecondLevelMenus = async () => { try { const response = await apiClient.get<{ success: boolean; data: SecondLevelMenu[]; }>("table-categories/second-level-menus"); if (response.data.success && response.data.data) { setSecondLevelMenus(response.data.data); } } catch (error) { console.error("2레벨 메뉴 목록 조회 실패:", error); toast.error("메뉴 목록을 불러올 수 없습니다"); } }; // 메뉴 선택/해제 const toggleMenu = (menuObjid: number) => { setSelectedMenus((prev) => prev.includes(menuObjid) ? prev.filter((id) => id !== menuObjid) : [...prev, menuObjid] ); }; const handleSave = async () => { // 입력 검증 if (!logicalColumnName.trim()) { toast.error("논리적 컬럼명을 입력해주세요"); return; } if (!physicalColumnName) { toast.error("실제 컬럼을 선택해주세요"); return; } if (selectedMenus.length === 0) { toast.error("최소 하나 이상의 메뉴를 선택해주세요"); return; } setLoading(true); try { // 선택된 각 메뉴에 대해 매핑 생성 const promises = selectedMenus.map((menuObjid) => createColumnMapping({ tableName, logicalColumnName: logicalColumnName.trim(), physicalColumnName, menuObjid, description: description.trim() || undefined, }) ); const results = await Promise.all(promises); // 모든 요청이 성공했는지 확인 const failedCount = results.filter((r) => !r.success).length; if (failedCount === 0) { toast.success(`논리적 컬럼이 ${selectedMenus.length}개 메뉴에 추가되었습니다`); setOpen(false); resetForm(); onSuccess(); } else if (failedCount < results.length) { toast.warning( `${results.length - failedCount}개 메뉴에 추가 성공, ${failedCount}개 실패` ); onSuccess(); } else { toast.error("모든 메뉴에 대한 매핑 생성에 실패했습니다"); } } catch (error: any) { console.error("컬럼 매핑 생성 실패:", error); toast.error(error.message || "컬럼 매핑 생성 중 오류가 발생했습니다"); } finally { setLoading(false); } }; const resetForm = () => { setLogicalColumnName(""); setPhysicalColumnName(""); setDescription(""); setSelectedMenus([]); }; return ( 카테고리 컬럼 추가 2레벨 메뉴를 선택하면 해당 메뉴의 모든 하위 메뉴에서 사용할 수 있습니다
{/* 실제 컬럼 선택 */}

테이블의 실제 컬럼명

{/* 논리적 컬럼명 입력 */}
setLogicalColumnName(e.target.value)} placeholder="예: status_stock, status_sales" className="h-8 text-xs sm:h-10 sm:text-sm" />

선택한 메뉴들에서 사용할 고유한 이름을 입력하세요

{/* 적용할 2레벨 메뉴 선택 (체크박스) */}
{secondLevelMenus.length === 0 ? (

로딩 중...

) : ( secondLevelMenus.map((menu) => (
toggleMenu(menu.menuObjid)} className="h-4 w-4" />
)) )}

선택한 메뉴의 모든 하위 메뉴에서 이 카테고리를 사용할 수 있습니다

{selectedMenus.length > 0 && (

{selectedMenus.length}개 메뉴 선택됨

)}
{/* 설명 (선택사항) */}