"use client"; import React, { useState, useEffect, useCallback } from "react"; import { ComponentRendererProps } from "@/types/component"; import { ReportParamMapping, ReportViewerConfig } from "./types"; import { useScreenContextOptional } from "@/contexts/ScreenContext"; import { reportApi } from "@/lib/api/reportApi"; import { ReportMaster } from "@/types/report"; import { ReportListPreviewModal } from "@/components/report/ReportListPreviewModal"; import { FileText, Loader2 } from "lucide-react"; import { Button } from "@/components/ui/button"; /** * paramMappings가 있으면 명시적 매핑, 없으면 formData 그대로 전달 (휴리스틱 유지) */ function buildContextParams( formData: Record, mappings: ReportParamMapping[], ): Record { if (mappings.length === 0) return formData; const result: Record = {}; for (const { param, formField } of mappings) { if (param && formField) { result[param] = formData[formField] ?? null; } } return result; } interface ReportViewerComponentProps extends ComponentRendererProps { config?: ReportViewerConfig; formData?: Record; } export const ReportViewerComponent: React.FC = ({ component, isDesignMode = false, formData, }) => { const screenContext = useScreenContextOptional(); const menuObjid = screenContext?.menuObjid; const contextFormData = screenContext?.formData ?? formData ?? {}; const config = (component?.componentConfig ?? component?.overrides ?? {}) as ReportViewerConfig; const title = config.title || "리포트"; const paramMappings = config.paramMappings ?? []; const resolvedContextParams = buildContextParams(contextFormData, paramMappings); const [reports, setReports] = useState([]); const [isLoading, setIsLoading] = useState(false); const [selectedReport, setSelectedReport] = useState(null); const fetchReports = useCallback(async () => { if (!menuObjid) return; setIsLoading(true); try { const res = await reportApi.getReportsByMenuObjid(menuObjid); if (res.success) setReports(res.data.items); } catch { // 실패 시 빈 목록 유지 } finally { setIsLoading(false); } }, [menuObjid]); useEffect(() => { if (isDesignMode) return; fetchReports(); }, [isDesignMode, fetchReports]); // 디자인 모드: 플레이스홀더 if (isDesignMode) { return (
{title} (리포트 뷰어) 실행 시 메뉴에 연결된 리포트 목록이 표시됩니다
); } // menuObjid 없음 if (!menuObjid) { return (
연결된 메뉴가 없습니다
); } if (isLoading) { return (
); } if (reports.length === 0) { return (
연결된 리포트가 없습니다
); } return ( <>
{reports.map((report) => ( ))}
setSelectedReport(null)} contextParams={resolvedContextParams} /> ); };