207 lines
5.9 KiB
TypeScript
207 lines
5.9 KiB
TypeScript
import { EditOutlined, EyeOutlined } from '@ant-design/icons';
|
|
import { ProColumns, ProTable } from '@ant-design/pro-components';
|
|
import { useIntl, useModel } from '@umijs/max';
|
|
import { Button, Flex, message } from 'antd';
|
|
import React, { useState } from 'react';
|
|
import CreateOrUpdateFishingLog from './CreateOrUpdateFishingLog';
|
|
import HaulFishList from './HaulFishList';
|
|
|
|
export interface HaulTableProps {
|
|
hauls: API.FishingLog[];
|
|
trip?: API.Trip;
|
|
onReload?: (isTrue: boolean) => void;
|
|
}
|
|
const HaulTable: React.FC<HaulTableProps> = ({ hauls, trip }) => {
|
|
const [editOpen, setEditOpen] = useState(false);
|
|
const [editFishingLogOpen, setEditFishingLogOpen] = useState(false);
|
|
const [currentRow, setCurrentRow] = useState<API.FishingLogInfo[]>([]);
|
|
const [currentFishingLog, setCurrentFishingLog] =
|
|
useState<API.FishingLog | null>(null);
|
|
const intl = useIntl();
|
|
const { getApi } = useModel('getTrip');
|
|
|
|
const fishing_logs_columns: ProColumns<API.FishingLog>[] = [
|
|
{
|
|
title: (
|
|
<div style={{ textAlign: 'center' }}>
|
|
{intl.formatMessage({ id: 'trip.haulTable.no' })}
|
|
</div>
|
|
),
|
|
dataIndex: 'fishing_log_id',
|
|
align: 'center',
|
|
render: (_, __, index) => {
|
|
return `${intl.formatMessage({ id: 'trip.haulTable.haul' })} ${
|
|
hauls.length - index
|
|
}`;
|
|
},
|
|
},
|
|
{
|
|
title: (
|
|
<div style={{ textAlign: 'center' }}>
|
|
{intl.formatMessage({ id: 'trip.haulTable.status' })}
|
|
</div>
|
|
),
|
|
dataIndex: ['status'],
|
|
align: 'center',
|
|
valueEnum: {
|
|
0: {
|
|
text: intl.formatMessage({
|
|
id: 'trip.haulTable.fishing',
|
|
}),
|
|
status: 'Processing',
|
|
},
|
|
1: {
|
|
text: intl.formatMessage({
|
|
id: 'trip.haulTable.endFishing',
|
|
}),
|
|
status: 'Success',
|
|
},
|
|
2: {
|
|
text: intl.formatMessage({
|
|
id: 'trip.haulTable.cancelFishing',
|
|
}),
|
|
status: 'default',
|
|
},
|
|
},
|
|
},
|
|
{
|
|
title: (
|
|
<div style={{ textAlign: 'center' }}>
|
|
{intl.formatMessage({ id: 'trip.haulTable.weather' })}
|
|
</div>
|
|
),
|
|
dataIndex: ['weather_description'],
|
|
align: 'center',
|
|
},
|
|
{
|
|
title: (
|
|
<div style={{ textAlign: 'center' }}>
|
|
{intl.formatMessage({ id: 'trip.haulTable.startTime' })}
|
|
</div>
|
|
),
|
|
dataIndex: ['start_at'],
|
|
align: 'center',
|
|
render: (start_at: any) => {
|
|
if (!start_at) return '-';
|
|
const date = new Date(start_at);
|
|
return date.toLocaleString('vi-VN', {
|
|
day: '2-digit',
|
|
month: '2-digit',
|
|
year: 'numeric',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
second: '2-digit',
|
|
hour12: false,
|
|
});
|
|
},
|
|
},
|
|
{
|
|
title: (
|
|
<div style={{ textAlign: 'center' }}>
|
|
{intl.formatMessage({ id: 'trip.haulTable.endTime' })}
|
|
</div>
|
|
),
|
|
dataIndex: ['end_at'],
|
|
align: 'center',
|
|
render: (end_at: any) => {
|
|
if (end_at === '0001-01-01T00:00:00Z') return '-';
|
|
const date = new Date(end_at);
|
|
return date.toLocaleString('vi-VN', {
|
|
day: '2-digit',
|
|
month: '2-digit',
|
|
year: 'numeric',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
second: '2-digit',
|
|
hour12: false,
|
|
});
|
|
},
|
|
},
|
|
{
|
|
title: intl.formatMessage({ id: 'trip.haulTable.action' }),
|
|
align: 'center',
|
|
hideInSearch: true,
|
|
render: (_, record) => {
|
|
console.log('Rendering action column for record:', record);
|
|
return (
|
|
<Flex align="center" justify="center" gap={5}>
|
|
{/* Nút Edit */}
|
|
<Button
|
|
shape="default"
|
|
size="small"
|
|
icon={<EyeOutlined />}
|
|
onClick={() => {
|
|
if (record.info) {
|
|
setCurrentRow(record.info!); // record là dòng hiện tại trong table
|
|
setEditOpen(true);
|
|
} else {
|
|
message.warning(
|
|
intl.formatMessage({ id: 'trip.haulFishList.noData' }),
|
|
);
|
|
}
|
|
}}
|
|
/>
|
|
{editOpen && currentRow && (
|
|
<HaulFishList
|
|
fishList={currentRow} // truyền luôn cả record nếu cần
|
|
open={editOpen}
|
|
onOpenChange={setEditOpen}
|
|
/>
|
|
)}
|
|
<Button
|
|
shape="default"
|
|
size="small"
|
|
icon={<EditOutlined />}
|
|
onClick={() => {
|
|
setCurrentFishingLog(record);
|
|
setEditFishingLogOpen(true);
|
|
}}
|
|
/>
|
|
</Flex>
|
|
);
|
|
},
|
|
},
|
|
];
|
|
|
|
return (
|
|
<>
|
|
<ProTable<API.FishingLog>
|
|
style={{ width: '90%' }}
|
|
columns={fishing_logs_columns}
|
|
dataSource={hauls.slice().reverse()} // đảo ngược thứ tự hiển thị
|
|
search={false}
|
|
pagination={{
|
|
pageSize: 10,
|
|
showSizeChanger: true,
|
|
showTotal: (total, range) => `${range[0]}-${range[1]} trên ${total}`,
|
|
}}
|
|
options={false}
|
|
bordered
|
|
size="middle"
|
|
scroll={{ x: 600 }}
|
|
/>
|
|
<CreateOrUpdateFishingLog
|
|
trip={trip!}
|
|
isFinished={currentFishingLog?.status === 0 ? false : true}
|
|
fishingLogs={currentFishingLog || undefined}
|
|
isOpen={editFishingLogOpen}
|
|
onOpenChange={setEditFishingLogOpen}
|
|
onFinished={(success) => {
|
|
if (success) {
|
|
message.success(
|
|
intl.formatMessage({ id: 'trip.haulTable.updateSuccess' }),
|
|
);
|
|
getApi();
|
|
} else {
|
|
message.error(
|
|
intl.formatMessage({ id: 'trip.haulTable.updateError' }),
|
|
);
|
|
}
|
|
}}
|
|
/>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default HaulTable;
|