"use client"; import { useState, useEffect, useCallback } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Textarea } from "@/components/ui/textarea"; import { toast } from "sonner"; import { Plus, Pencil, Trash2, Link2, Database } from "lucide-react"; import { getFieldJoins, createFieldJoin, updateFieldJoin, deleteFieldJoin, FieldJoin, } from "@/lib/api/screenGroup"; interface FieldJoinPanelProps { screenId: number; componentId?: string; layoutId?: number; } export default function FieldJoinPanel({ screenId, componentId, layoutId }: FieldJoinPanelProps) { // 상태 관리 const [fieldJoins, setFieldJoins] = useState([]); const [loading, setLoading] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false); const [selectedJoin, setSelectedJoin] = useState(null); const [formData, setFormData] = useState({ field_name: "", save_table: "", save_column: "", join_table: "", join_column: "", display_column: "", join_type: "LEFT", filter_condition: "", sort_column: "", sort_direction: "ASC", is_active: "Y", }); // 데이터 로드 const loadFieldJoins = useCallback(async () => { if (!screenId) return; setLoading(true); try { const response = await getFieldJoins(screenId); if (response.success && response.data) { // 현재 컴포넌트에 해당하는 조인만 필터링 const filtered = componentId ? response.data.filter(join => join.component_id === componentId) : response.data; setFieldJoins(filtered); } } catch (error) { console.error("필드 조인 로드 실패:", error); } finally { setLoading(false); } }, [screenId, componentId]); useEffect(() => { loadFieldJoins(); }, [loadFieldJoins]); // 모달 열기 const openModal = (join?: FieldJoin) => { if (join) { setSelectedJoin(join); setFormData({ field_name: join.field_name || "", save_table: join.save_table, save_column: join.save_column, join_table: join.join_table, join_column: join.join_column, display_column: join.display_column, join_type: join.join_type, filter_condition: join.filter_condition || "", sort_column: join.sort_column || "", sort_direction: join.sort_direction || "ASC", is_active: join.is_active, }); } else { setSelectedJoin(null); setFormData({ field_name: "", save_table: "", save_column: "", join_table: "", join_column: "", display_column: "", join_type: "LEFT", filter_condition: "", sort_column: "", sort_direction: "ASC", is_active: "Y", }); } setIsModalOpen(true); }; // 저장 const handleSave = async () => { if (!formData.save_table || !formData.save_column || !formData.join_table || !formData.join_column || !formData.display_column) { toast.error("필수 필드를 모두 입력해주세요."); return; } try { const payload = { screen_id: screenId, layout_id: layoutId, component_id: componentId, ...formData, }; let response; if (selectedJoin) { response = await updateFieldJoin(selectedJoin.id, payload); } else { response = await createFieldJoin(payload); } if (response.success) { toast.success(selectedJoin ? "조인 설정이 수정되었습니다." : "조인 설정이 추가되었습니다."); setIsModalOpen(false); loadFieldJoins(); } else { toast.error(response.message || "저장에 실패했습니다."); } } catch (error) { toast.error("저장 중 오류가 발생했습니다."); } }; // 삭제 const handleDelete = async (id: number) => { if (!confirm("이 조인 설정을 삭제하시겠습니까?")) return; try { const response = await deleteFieldJoin(id); if (response.success) { toast.success("조인 설정이 삭제되었습니다."); loadFieldJoins(); } else { toast.error(response.message || "삭제에 실패했습니다."); } } catch (error) { toast.error("삭제 중 오류가 발생했습니다."); } }; return (
{/* 헤더 */}

필드 조인 설정

{/* 설명 */}

이 필드가 다른 테이블의 값을 참조하여 표시할 때 조인 설정을 추가하세요.

{/* 조인 목록 */} {loading ? (
) : fieldJoins.length === 0 ? (

설정된 조인이 없습니다

) : (
저장 테이블.컬럼 조인 테이블.컬럼 표시 컬럼 관리 {fieldJoins.map((join) => ( {join.save_table}.{join.save_column} {join.join_table}.{join.join_column} {join.display_column}
))}
)} {/* 추가/수정 모달 */} {selectedJoin ? "조인 설정 수정" : "조인 설정 추가"} 필드가 참조할 테이블과 컬럼을 설정합니다
{/* 필드명 */}
setFormData({ ...formData, field_name: e.target.value })} placeholder="화면에 표시될 필드명" className="h-8 text-xs sm:h-10 sm:text-sm" />
{/* 저장 테이블/컬럼 */}
setFormData({ ...formData, save_table: e.target.value })} placeholder="예: work_orders" className="h-8 font-mono text-xs sm:h-10 sm:text-sm" />
setFormData({ ...formData, save_column: e.target.value })} placeholder="예: item_code" className="h-8 font-mono text-xs sm:h-10 sm:text-sm" />
{/* 조인 테이블/컬럼 */}
setFormData({ ...formData, join_table: e.target.value })} placeholder="예: item_mng" className="h-8 font-mono text-xs sm:h-10 sm:text-sm" />
setFormData({ ...formData, join_column: e.target.value })} placeholder="예: id" className="h-8 font-mono text-xs sm:h-10 sm:text-sm" />
{/* 표시 컬럼 */}
setFormData({ ...formData, display_column: e.target.value })} placeholder="예: item_name (화면에 표시될 컬럼)" className="h-8 font-mono text-xs sm:h-10 sm:text-sm" />
{/* 조인 타입/정렬 */}
setFormData({ ...formData, sort_column: e.target.value })} placeholder="예: name" className="h-8 font-mono text-xs sm:h-10 sm:text-sm" />
{/* 필터 조건 */}