Files
cod-fe/src/components/Global/TableList.jsx

218 lines
6.7 KiB
JavaScript

import React, { memo, useState, useEffect, useRef } from 'react';
import { Table, Pagination, Row, Col, Card, Grid, Button, Typography, Tag, Segmented } from 'antd';
import { MacCommandOutlined, TableOutlined } from '@ant-design/icons';
import CardList from './CardList';
const { Text } = Typography;
const TableList = memo(function TableList({
getData,
queryParams,
columns,
triger,
mobile,
rowSelection = null,
header = 'name',
showPreviewModal,
showEditModal,
showDeleteDialog,
cardColor,
fieldColor,
firstLoad = true,
columnDynamic = false,
cardComponent, // New prop for custom card component
onStockUpdate, // Prop to pass to card component
onGetData, // Callback to execute when data is received
}) {
const [gridLoading, setGridLoading] = useState(false);
const [data, setData] = useState([]);
const [pagination, setPagination] = useState({
current_page: 1,
current_limit: 10,
total_limit: 0,
total_page: 1,
});
const [columnsDynamic, setColumnsDynamic] = useState(columns);
const [viewMode, setViewMode] = useState('table');
const { useBreakpoint } = Grid;
const [renderCount, setRenderCount] = useState(firstLoad ? 1 : 0);
useEffect(() => {
if (renderCount < 1) {
setRenderCount(renderCount + 1);
return;
} else {
filter(1, pagination.current_limit);
}
}, [triger]);
const filter = async (currentPage, pageSize) => {
setGridLoading(true);
const paging = {
page: Number(currentPage),
limit: Number(pageSize),
};
const param = new URLSearchParams({ ...paging, ...queryParams });
const resData = await getData(param);
if (columnDynamic && resData) {
const columnsApi = resData[columnDynamic] ?? '';
// Pisahkan string menjadi array kolom
const colArray = columnsApi.split(',').map((c) => c.trim());
// Kolom default datetime di awal
const defaultColumns = [
{
title: 'No',
key: 'no',
width: '5%',
align: 'center',
render: (_, __, index) => index + 1,
},
{
title: 'Datetime',
dataIndex: 'datetime',
key: 'datetime',
width: '15%',
// render: (value) => dayjs(value).format('YYYY-MM-DD HH:mm:ss'),
},
];
// Buat kolom numerik dengan format 4 angka di belakang koma
const numericColumns = colArray.map((colName) => ({
title: colName,
dataIndex: colName,
key: colName,
align: 'right',
width: 'auto',
render: (value) => {
if (typeof value === 'number') {
return value.toFixed(4);
}
return value ?? '-';
},
}));
// Gabungkan default + API columns
setColumnsDynamic([...defaultColumns, ...numericColumns]);
}
const fetchedData = resData?.data ?? [];
// Panggil callback jika disediakan
if (onGetData && typeof onGetData === 'function') {
onGetData(fetchedData);
}
setData(fetchedData);
const pagingData = resData?.paging;
if (pagingData) {
setPagination((prev) => ({
...prev,
current_page: pagingData.current_page || 1,
current_limit: pagingData.current_limit || 10,
total_limit: pagingData.total_limit || 0,
total_page: pagingData.total_page || 1,
}));
}
setGridLoading(false);
if (resData) {
setTimeout(() => {
setGridLoading(false);
}, 900);
} else {
setGridLoading(false);
return;
}
};
const handlePaginationChange = (page, pageSize) => {
setPagination((prev) => ({
...prev,
current: page,
limit: pageSize,
}));
filter(page, pageSize);
};
const screens = useBreakpoint();
const isMobile = !screens.md; // kalau kurang dari md (768px) dianggap mobile
// Use the custom card component if provided, otherwise default to CardList
const CardViewComponent = cardComponent || CardList;
return (
<div>
<Segmented
options={[
{ value: 'table', icon: <TableOutlined /> },
{ value: 'card', icon: <MacCommandOutlined /> },
]}
value={viewMode}
onChange={setViewMode}
/>
{(isMobile && mobile) || viewMode === 'card' ? (
<CardViewComponent
cardColor={cardColor}
fieldColor={fieldColor}
data={data}
column={columnsDynamic}
header={header}
showPreviewModal={showPreviewModal}
showEditModal={showEditModal}
showDeleteDialog={showDeleteDialog}
onStockUpdate={onStockUpdate}
/>
) : (
<Row gutter={24} style={{ marginTop: '16px' }}>
<Table
rowSelection={rowSelection || null}
columns={columnsDynamic}
dataSource={data.map((item, index) => ({ ...item, key: index }))}
pagination={false}
loading={gridLoading}
scroll={{ y: 520 }}
size="small"
/>
</Row>
)}
{/* PAGINATION */}
<Row justify="space-between" align="middle">
<Col>
<div>
Menampilkan {pagination.current_limit} data halaman{' '}
{pagination.current_page} dari total {pagination.total_limit} data
</div>
</Col>
<Col>
<Pagination
showSizeChanger
onChange={handlePaginationChange}
onShowSizeChange={handlePaginationChange}
current={pagination.current_page}
pageSize={pagination.current_limit}
total={pagination.total_limit}
/>
</Col>
</Row>
</div>
);
});
export default TableList;