292 lines
7.5 KiB
JavaScript
292 lines
7.5 KiB
JavaScript
import React, { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
|
|
import {
|
|
Title,
|
|
TableStyle,
|
|
FormWrapper,
|
|
TableWrapper,
|
|
TableActionButton,
|
|
TableDetailRow,
|
|
TableDetailContainer,
|
|
TableDetailFlex,
|
|
TableDetailColumn,
|
|
DetailTableInfo,
|
|
} from '../../styles/Components';
|
|
|
|
import { withAuth } from '../../hooks/hook';
|
|
import {
|
|
authType,
|
|
modalTypes,
|
|
} from '../../assets/data';
|
|
import { INITIAL_PAGE_LIMIT, INITIAL_PAGE_SIZE } from '../../assets/data/adminConstants';
|
|
import { useTranslation } from 'react-i18next';
|
|
import {
|
|
DownloadProgress,
|
|
DynamicModal,
|
|
ExcelDownButton,
|
|
Pagination,
|
|
TopButton,
|
|
ViewTableInfo,
|
|
} from '../../components/common';
|
|
import { TableSkeleton } from '../../components/Skeleton/TableSkeleton';
|
|
import BusinessLogSearchBar, { useBusinessLogSearch } from '../../components/ServiceManage/searchBar/BusinessLogSearchBar';
|
|
import styled from 'styled-components';
|
|
import FrontPagination from '../../components/common/Pagination/FrontPagination';
|
|
import Loading from '../../components/common/Loading';
|
|
import CircularProgress from '../../components/common/CircularProgress';
|
|
|
|
const BusinessLogView = () => {
|
|
const token = sessionStorage.getItem('token');
|
|
const { t } = useTranslation();
|
|
const tableRef = useRef(null);
|
|
|
|
const [alertMsg, setAlertMsg] = useState('');
|
|
|
|
const [expandedRows, setExpandedRows] = useState({});
|
|
const [downloadState, setDownloadState] = useState({
|
|
loading: false,
|
|
progress: 0
|
|
});
|
|
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
const [itemsPerPage, setItemsPerPage] = useState(500);
|
|
const [displayData, setDisplayData] = useState([]);
|
|
|
|
const {
|
|
searchParams,
|
|
loading: dataLoading,
|
|
data: dataList,
|
|
handleSearch,
|
|
handleReset,
|
|
handlePageChange,
|
|
handleOrderByChange,
|
|
updateSearchParams
|
|
} = useBusinessLogSearch(token, 500, setAlertMsg);
|
|
|
|
const handlePageSizeChange = (newSize) => {
|
|
setItemsPerPage(newSize);
|
|
setCurrentPage(1);
|
|
};
|
|
|
|
const handleClientPageChange = useCallback((slicedData) => {
|
|
setDisplayData(slicedData);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
setCurrentPage(1);
|
|
if (dataList?.generic_list && dataList.generic_list.length > 0) {
|
|
const initialData = dataList.generic_list.slice(0, itemsPerPage);
|
|
setDisplayData(initialData);
|
|
} else {
|
|
setDisplayData([]);
|
|
}
|
|
}, [dataList, itemsPerPage]);
|
|
|
|
const toggleRowExpand = (index) => {
|
|
setExpandedRows(prev => ({
|
|
...prev,
|
|
[index]: !prev[index]
|
|
}));
|
|
};
|
|
|
|
const tableHeaders = useMemo(() => {
|
|
return [
|
|
{ id: 'logTime', label: '일시', width: '120px' },
|
|
{ id: 'userGuid', label: 'GUID', width: '200px' },
|
|
{ id: 'accountId', label: 'account ID', width: '100px' },
|
|
{ id: 'userNickname', label: '아바타명', width: '150px' },
|
|
{ id: 'tranId', label: '트랜잭션 ID', width: '200px' },
|
|
{ id: 'action', label: '액션', width: '150px' },
|
|
{ id: 'domain', label: '도메인', width: '120px' },
|
|
{ id: 'details', label: '상세 정보', width: '100px' }
|
|
];
|
|
}, []);
|
|
|
|
|
|
const renderActorData = (actor) => {
|
|
if (!actor || typeof actor !== 'object') return <></>;
|
|
|
|
return (
|
|
<DetailTableInfo>
|
|
<thead>
|
|
<tr>
|
|
<th colSpan="2">Actor 정보</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{Object.entries(actor).map(([key, value]) => (
|
|
<tr key={`actor-${key}`}>
|
|
<td>{key}</td>
|
|
<td>
|
|
{typeof value === 'object' && value !== null
|
|
? JSON.stringify(value)
|
|
: String(value)
|
|
}
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</DetailTableInfo>
|
|
);
|
|
};
|
|
|
|
const renderInfosData = (infos) => {
|
|
if (!infos || !Array.isArray(infos) || infos.length === 0) return <></>;
|
|
|
|
return (
|
|
<DetailTableInfo>
|
|
<thead>
|
|
<tr>
|
|
<th colSpan="2">Infos 정보</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{infos.map((info, infoIndex) => (
|
|
<Fragment key={`info-${infoIndex}`}>
|
|
{Object.entries(info).map(([key, value]) => (
|
|
<tr key={`info-${infoIndex}-${key}`}>
|
|
<td>{key}</td>
|
|
<td>
|
|
{typeof value === 'object' && value !== null
|
|
? JSON.stringify(value)
|
|
: Array.isArray(value)
|
|
? value.join(', ')
|
|
: String(value)
|
|
}
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</Fragment>
|
|
))}
|
|
</tbody>
|
|
</DetailTableInfo>
|
|
);
|
|
};
|
|
|
|
const handleModalSubmit = async (type, param = null) => {
|
|
switch (type) {
|
|
case "warning":
|
|
setAlertMsg('')
|
|
break;
|
|
}
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Title>비즈니스 로그 조회</Title>
|
|
<FormWrapper>
|
|
<BusinessLogSearchBar
|
|
searchParams={searchParams}
|
|
onSearch={(newParams, executeSearch = true) => {
|
|
if (executeSearch) {
|
|
handleSearch(newParams);
|
|
} else {
|
|
updateSearchParams(newParams);
|
|
}
|
|
}}
|
|
onReset={handleReset}
|
|
/>
|
|
</FormWrapper>
|
|
<ViewTableInfo orderType="asc" pageType="B" total={dataList?.total} total_all={dataList?.total_all} handleOrderBy={handleOrderByChange} handlePageSize={handlePageSizeChange}>
|
|
<DownloadContainer>
|
|
<ExcelDownButton
|
|
data={dataList?.generic_list}
|
|
fileName={t('FILE_BUSINESS_LOG')}
|
|
onLoadingChange={setDownloadState}
|
|
/>
|
|
{downloadState.loading && (
|
|
<CircularProgressWrapper>
|
|
<CircularProgress
|
|
progress={downloadState.progress}
|
|
size={36}
|
|
progressColor="#4A90E2"
|
|
/>
|
|
</CircularProgressWrapper>
|
|
)}
|
|
</DownloadContainer>
|
|
</ViewTableInfo>
|
|
{dataLoading ? <TableSkeleton width='100%' count={15} /> :
|
|
<>
|
|
<TableWrapper>
|
|
<TableStyle ref={tableRef}>
|
|
<thead>
|
|
<tr>
|
|
{tableHeaders.map(header => (
|
|
<th key={header.id} width={header.width}>{header.label}</th>
|
|
))}
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{displayData?.map((item, index) => (
|
|
<Fragment key={index}>
|
|
<tr>
|
|
<td>{item.logTime}</td>
|
|
<td>{item.userGuid}</td>
|
|
<td>{item.accountId}</td>
|
|
<td>{item.userNickname}</td>
|
|
<td>{item.tranId}</td>
|
|
<td>{item.action}</td>
|
|
<td>{item.domain === 'None' ? '-' : item.domain}</td>
|
|
<td>
|
|
<TableActionButton onClick={() => toggleRowExpand(index)}>
|
|
{expandedRows[index] ? '접기' : '상세보기'}
|
|
</TableActionButton>
|
|
</td>
|
|
</tr>
|
|
{expandedRows[index] && (
|
|
<TableDetailRow>
|
|
<td colSpan={tableHeaders.length}>
|
|
<TableDetailContainer>
|
|
<TableDetailFlex>
|
|
<TableDetailColumn>
|
|
{renderActorData(item.header?.Actor)}
|
|
</TableDetailColumn>
|
|
<TableDetailColumn>
|
|
{renderInfosData(item.body?.Infos)}
|
|
</TableDetailColumn>
|
|
</TableDetailFlex>
|
|
</TableDetailContainer>
|
|
</td>
|
|
</TableDetailRow>
|
|
)}
|
|
</Fragment>
|
|
))}
|
|
</tbody>
|
|
</TableStyle>
|
|
</TableWrapper>
|
|
{dataList?.generic_list &&
|
|
<FrontPagination
|
|
data={dataList.generic_list}
|
|
itemsPerPage={itemsPerPage}
|
|
currentPage={currentPage}
|
|
setCurrentPage={setCurrentPage}
|
|
pageLimit={10}
|
|
onPageChange={handleClientPageChange}
|
|
/>}
|
|
<TopButton />
|
|
</>
|
|
}
|
|
|
|
<DynamicModal
|
|
modalType={modalTypes.completed}
|
|
view={alertMsg ? 'view' : 'hidden'}
|
|
modalText={alertMsg}
|
|
handleSubmit={() => handleModalSubmit('warning')}
|
|
/>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default withAuth(authType.businessLogRead)(BusinessLogView);
|
|
|
|
const DownloadContainer = styled.div`
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
`;
|
|
|
|
const CircularProgressWrapper = styled.div`
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
`; |