import { styled } from 'styled-components'; import React, { Fragment, useEffect, useState } from 'react'; import { Title } from '../../../styles/Components'; import { BtnWrapper, TableStyle } from '../../../styles/Components'; import Button from '../../../components/common/button/Button'; import Modal from '../../../components/common/modal/Modal'; import { TableWrapper } from '../../../styles/Components'; import { Tab, TabContent } from '../../../styles/ModuleComponents'; import { convertKTC, getFieldLabel } from '../../../utils'; import { historyBenField } from '../../../assets/data/data'; const LogDetailModal = ({ detailView, handleDetailView, detailData, changedData, viewMode = 'both', title = '로그 상세정보' }) => { const [activeTab, setActiveTab] = useState('data'); // viewMode가 변경될 때 적절한 탭 활성화 useEffect(() => { if (viewMode === 'data' || viewMode === 'changed') { setActiveTab(viewMode); } }, [viewMode]); // data 객체의 키-값 쌍을 테이블 형식으로 변환 const renderDataTable = () => { if (!detailData || !detailData) return null; // data 객체를 평탄화하는 함수 (중첩된 객체도 처리) const flattenObject = (obj, prefix = '') => { return Object.keys(obj).reduce((acc, key) => { const newKey = prefix ? `${prefix}.${key}` : key; if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) { // $date나 $oid 같은 특수 키를 포함하는 MongoDB 형식 객체 처리 if (obj[key].$date) { acc[newKey] = new Date(obj[key].$date).toLocaleString('ko-KR'); return acc; } if (obj[key].$oid) { acc[newKey] = obj[key].$oid; return acc; } if (obj[key].$numberLong) { acc[newKey] = obj[key].$numberLong; return acc; } // 일반 중첩 객체는 재귀적으로 평탄화 return {...acc, ...flattenObject(obj[key], newKey)}; } // 배열 값은 JSON 문자열로 변환 if (Array.isArray(obj[key])) { acc[newKey] = JSON.stringify(obj[key]); } else { acc[newKey] = obj[key]; } return acc; }, {}); }; const flattenedData = flattenObject(detailData); return ( 데이터 상세 정보 필드명 값 {detailData && Object.entries(flattenedData).map(([key, value], index) => ( {getFieldLabel(key)} {value !== null && value !== undefined ? String(value) : ''} ))} ); }; // changed 배열의 항목들을 테이블로 표시 const renderChangedTable = () => { if (!changedData || !Array.isArray(changedData)) { return null; } const allChangedItems = []; changedData.forEach((item, itemIndex) => { if (item.domain.changed && Array.isArray(item.domain.changed)) { item.domain.changed.forEach((changedItem) => { allChangedItems.push({ ...changedItem, // 어떤 데이터 항목에서 온 것인지 구분하기 위한 정보 추가 sourceIndex: itemIndex, sourceInfo: { dbType: item.dbType, logTime: item.logTime, operationType: item.domain.operationType, historyType: item.historyType, tableName: item.tableName, tranId: item.tranId, worker: item.worker } }); }); } }); if (allChangedItems.length === 0) { return (
변경 항목이 없습니다.
); } // 값 포맷팅 함수 const formatValue = (value) => { if (value === null || value === undefined) return ''; if (typeof value === 'object') { if (value.$date) return convertKTC(value.$date,false); if (value.$oid) return value.$oid; if (value.$numberLong) return value.$numberLong; return JSON.stringify(value); } return String(value); }; return ( 변경 항목 목록 유형 필드명 신규 값 이전 값 작업자 작업일시(KST) {allChangedItems.map((item, index) => { if (historyBenField.includes(item.fieldName)) { return null; } return ( {getFieldLabel(item.sourceInfo.operationType)} {getFieldLabel(item.fieldName)} {formatValue(item.newValue)} {formatValue(item.oldValue)} {item.sourceInfo.worker} {convertKTC(item.sourceInfo.logTime, false)} ) })} ); }; // 단일 뷰 또는 탭 뷰 렌더링 결정 const renderContent = () => { if ((viewMode === 'data' && !detailData) || (viewMode === 'changed' && !changedData)) return null; // 단일 뷰 모드 if (viewMode === 'data') { return renderDataTable(); } if (viewMode === 'changed') { return renderChangedTable(); } return ( <> {/* 탭 메뉴 */} setActiveTab('data')} > 데이터 정보 setActiveTab('changed')} > 변경 항목 {/* 탭 컨텐츠 */} {renderDataTable()} {renderChangedTable()} ); }; return ( <> {title} {renderContent()}