import { useState, useCallback, useEffect } from 'react'; import { batchApi, type ApiLogPageResponse, type ApiLogStatus } from '../api/batchApi'; import { formatDateTime } from '../utils/formatters'; import Pagination from './Pagination'; import CopyButton from './CopyButton'; interface ApiLogSectionProps { stepExecutionId: number; summary: { totalCalls: number; successCount: number; errorCount: number }; } export default function ApiLogSection({ stepExecutionId, summary }: ApiLogSectionProps) { const [open, setOpen] = useState(false); const [status, setStatus] = useState('ALL'); const [page, setPage] = useState(0); const [logData, setLogData] = useState(null); const [loading, setLoading] = useState(false); const fetchLogs = useCallback(async (p: number, s: ApiLogStatus) => { setLoading(true); try { const data = await batchApi.getStepApiLogs(stepExecutionId, { page: p, size: 10, status: s }); setLogData(data); } catch { setLogData(null); } finally { setLoading(false); } }, [stepExecutionId]); useEffect(() => { if (open) { fetchLogs(page, status); } }, [open, page, status, fetchLogs]); const handleStatusChange = (s: ApiLogStatus) => { setStatus(s); setPage(0); }; const filters: { key: ApiLogStatus; label: string; count: number }[] = [ { key: 'ALL', label: '전체', count: summary.totalCalls }, { key: 'SUCCESS', label: '성공', count: summary.successCount }, { key: 'ERROR', label: '에러', count: summary.errorCount }, ]; return (
{open && (
{/* 상태 필터 탭 */}
{filters.map(({ key, label, count }) => ( ))}
{loading ? (
로딩중...
) : logData && logData.content.length > 0 ? ( <>
{logData.content.map((log, idx) => { const isError = (log.statusCode != null && log.statusCode >= 400) || log.errorMessage; return ( ); })}
# URI Method 상태 응답(ms) 건수 시간 에러
{page * 10 + idx + 1}
{log.requestUri}
{log.httpMethod} {log.statusCode ?? '-'} {log.responseTimeMs?.toLocaleString() ?? '-'} {log.responseCount?.toLocaleString() ?? '-'} {formatDateTime(log.createdAt)} {log.errorMessage || '-'}
{/* 페이지네이션 */} ) : (

조회된 로그가 없습니다.

)}
)}
); }