feat(sgw): Add new services and utilities for ship, trip, and photo management
This commit is contained in:
243
src/pages/Slave/SGW/Ship/components/FormAdd.tsx
Normal file
243
src/pages/Slave/SGW/Ship/components/FormAdd.tsx
Normal file
@@ -0,0 +1,243 @@
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
ModalForm,
|
||||
ProFormDateTimePicker,
|
||||
ProFormDigit,
|
||||
ProFormSelect,
|
||||
ProFormText,
|
||||
} from '@ant-design/pro-form';
|
||||
import { FormattedMessage, useIntl, useModel } from '@umijs/max';
|
||||
import { Button, Col, FormInstance, Row, Table } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import utc from 'dayjs/plugin/utc';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import FormShareVms from './FormShareVms';
|
||||
|
||||
dayjs.extend(utc);
|
||||
|
||||
interface ShipFormValues extends SgwModel.ShipCreateParams {
|
||||
targets?: SgwModel.SgwThing[];
|
||||
}
|
||||
|
||||
interface FormAddProps {
|
||||
visible: boolean;
|
||||
onVisibleChange: (visible: boolean) => void;
|
||||
onSubmit: (values: ShipFormValues) => Promise<boolean>;
|
||||
}
|
||||
|
||||
const FormAdd: React.FC<FormAddProps> = ({
|
||||
visible,
|
||||
onVisibleChange,
|
||||
onSubmit,
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const formRef = useRef<FormInstance<ShipFormValues>>();
|
||||
const [shareModalVisible, handleShareModalVisible] = useState(false);
|
||||
const [selectedDevices, setSelectedDevices] = useState<SgwModel.SgwThing[]>(
|
||||
[],
|
||||
);
|
||||
const { shipTypes, getShipTypes } = useModel('slave.sgw.useShipTypes');
|
||||
const { homeports } = useModel('slave.sgw.useHomePorts');
|
||||
const { groups, getGroups } = useModel('master.useGroups');
|
||||
useEffect(() => {
|
||||
if (!shipTypes) {
|
||||
getShipTypes();
|
||||
}
|
||||
}, [shipTypes]);
|
||||
useEffect(() => {
|
||||
if (!groups) {
|
||||
getGroups();
|
||||
}
|
||||
}, [groups]);
|
||||
|
||||
console.log('groups', homeports, groups);
|
||||
|
||||
// Lọc homeports theo province_code của groups
|
||||
const groupProvinceCodes = Array.isArray(groups)
|
||||
? groups.map((g: MasterModel.GroupNode) => g.metadata?.code).filter(Boolean)
|
||||
: [];
|
||||
const filteredHomeports = Array.isArray(homeports)
|
||||
? homeports.filter((p: SgwModel.Port) =>
|
||||
groupProvinceCodes.includes(p.province_code),
|
||||
)
|
||||
: [];
|
||||
|
||||
return (
|
||||
<ModalForm
|
||||
formRef={formRef}
|
||||
initialValues={{
|
||||
reg_number: '',
|
||||
ship_type: '',
|
||||
name: '', // Changed from shipname to name
|
||||
targets: [],
|
||||
imo_number: '',
|
||||
mmsi_number: '',
|
||||
ship_length: '',
|
||||
ship_power: '',
|
||||
ship_group_id: '',
|
||||
fishing_license_number: '',
|
||||
fishing_license_expiry_date: null,
|
||||
home_port: '',
|
||||
}}
|
||||
title={intl.formatMessage({
|
||||
id: 'pages.ships.create.title',
|
||||
defaultMessage: 'Tạo tàu mới',
|
||||
})}
|
||||
width="580px"
|
||||
open={visible}
|
||||
onVisibleChange={onVisibleChange}
|
||||
onFinish={async (formValues: ShipFormValues) => {
|
||||
console.log('FormAdd onFinish - formValues:', formValues);
|
||||
console.log('FormAdd onFinish - selectedDevices:', selectedDevices);
|
||||
// Gửi selectedDevices vào targets
|
||||
const rest = formValues;
|
||||
const thing_id = selectedDevices?.[0]?.id;
|
||||
const result = await onSubmit({
|
||||
...rest,
|
||||
thing_id,
|
||||
targets: selectedDevices,
|
||||
});
|
||||
console.log('FormAdd onFinish - result:', result);
|
||||
return result;
|
||||
}}
|
||||
>
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<ProFormText
|
||||
name="reg_number"
|
||||
label="Số đăng ký"
|
||||
rules={[{ required: true, message: 'Nhập số đăng ký' }]}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<ProFormText
|
||||
name="name"
|
||||
label="Tên tàu"
|
||||
rules={[{ required: true, message: 'Nhập tên tàu' }]}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<Col span={12}>
|
||||
<ProFormSelect
|
||||
name="ship_type"
|
||||
label="Loại tàu"
|
||||
options={
|
||||
Array.isArray(shipTypes)
|
||||
? shipTypes.map((t) => ({ label: t.name, value: t.id }))
|
||||
: []
|
||||
}
|
||||
rules={[{ required: true, message: 'Chọn loại tàu' }]}
|
||||
showSearch
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<Col span={12}>
|
||||
<ProFormSelect
|
||||
name="home_port"
|
||||
label="Cảng nhà"
|
||||
options={filteredHomeports.map((p) => ({
|
||||
label: p.name,
|
||||
value: p.id,
|
||||
}))}
|
||||
rules={[{ required: true, message: 'Chọn cảng nhà' }]}
|
||||
showSearch
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<Col span={12}>
|
||||
<ProFormText
|
||||
name="fishing_license_number"
|
||||
label="Số giấy phép"
|
||||
rules={[{ required: true, message: 'Nhập số giấy phép' }]}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<ProFormDateTimePicker
|
||||
name="fishing_license_expiry_date"
|
||||
label={intl.formatMessage({
|
||||
id: 'pages.things.fishing_license_expiry_date',
|
||||
defaultMessage: 'fishing_license_expiry_date',
|
||||
})}
|
||||
rules={[{ required: false }]}
|
||||
transform={(value: string) => {
|
||||
if (!value) return {};
|
||||
return {
|
||||
fishing_license_expiry_date: dayjs(value)
|
||||
.endOf('day')
|
||||
.utc()
|
||||
.format(), // ISO 8601 format: YYYY-MM-DDTHH:mm:ssZ
|
||||
};
|
||||
}}
|
||||
fieldProps={{
|
||||
format: 'YYYY-MM-DD',
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<Col span={12}>
|
||||
<ProFormDigit
|
||||
name="ship_length"
|
||||
label="Chiều dài (m)"
|
||||
min={0}
|
||||
rules={[{ required: true, message: 'Nhập chiều dài tàu' }]}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<ProFormDigit
|
||||
name="ship_power"
|
||||
label="Công suất (CV)"
|
||||
min={0}
|
||||
rules={[{ required: true, message: 'Nhập công suất tàu' }]}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
{/* <Col span={12}>
|
||||
<GroupShipSelect />
|
||||
</Col> */}
|
||||
|
||||
<Col span={24}>
|
||||
<Button
|
||||
type="primary"
|
||||
key="primary"
|
||||
onClick={() => {
|
||||
handleShareModalVisible(true);
|
||||
}}
|
||||
>
|
||||
<PlusOutlined />{' '}
|
||||
<FormattedMessage
|
||||
id="pages.things.share.text"
|
||||
defaultMessage="Share"
|
||||
/>
|
||||
</Button>
|
||||
{/* Hiển thị bảng thiết bị đã chọn */}
|
||||
{selectedDevices.length > 0 && (
|
||||
<Table
|
||||
size="small"
|
||||
pagination={false}
|
||||
dataSource={selectedDevices.map((item, idx) => ({
|
||||
key: idx,
|
||||
device: item.name || item,
|
||||
}))}
|
||||
columns={[
|
||||
{ title: 'Thiết bị', dataIndex: 'device', key: 'device' },
|
||||
]}
|
||||
scroll={{ y: 240 }}
|
||||
style={{ marginTop: 12 }}
|
||||
/>
|
||||
)}
|
||||
<FormShareVms
|
||||
visible={shareModalVisible}
|
||||
onVisibleChange={handleShareModalVisible}
|
||||
groups={groups || []}
|
||||
onSubmit={async (values: { things: SgwModel.SgwThing[] }) => {
|
||||
setSelectedDevices(values.things || []);
|
||||
handleShareModalVisible(false);
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</ModalForm>
|
||||
);
|
||||
};
|
||||
|
||||
export default FormAdd;
|
||||
Reference in New Issue
Block a user