|
|
|
|
@ -1,7 +1,19 @@
|
|
|
|
|
import React, { useEffect, useState } from 'react' ;
|
|
|
|
|
import { Modal, Form, Select, Grid, Slider, Switch, Input, InputNumber, Message } from '@arco-design/web-react';
|
|
|
|
|
import React, { useEffect, useState, useMemo } from 'react';
|
|
|
|
|
import {
|
|
|
|
|
Modal,
|
|
|
|
|
Form,
|
|
|
|
|
Select,
|
|
|
|
|
Grid,
|
|
|
|
|
Slider,
|
|
|
|
|
Switch,
|
|
|
|
|
Input,
|
|
|
|
|
InputNumber,
|
|
|
|
|
Message,
|
|
|
|
|
Button,
|
|
|
|
|
Spin
|
|
|
|
|
} from '@arco-design/web-react';
|
|
|
|
|
import EditableTable from '@/components/EditableTable';
|
|
|
|
|
import { containerRegister } from '@/api/userContainer';
|
|
|
|
|
import { containerRegister, getContainerLimit } from '@/api/userContainer';
|
|
|
|
|
import { getNetworkMode } from '@/api/componentDeploy';
|
|
|
|
|
|
|
|
|
|
const FormItem = Form.Item;
|
|
|
|
|
@ -124,6 +136,12 @@ const ContainerModal = ({ addItem, visible, envType, setVisible, onSuccess }) =>
|
|
|
|
|
|
|
|
|
|
const [currentNetworkCard, setCurrentNetworkCard] = useState(''); // 当前选择的网卡
|
|
|
|
|
const [currentIp, setCurrentIp] = useState(''); // 当前输入的IP
|
|
|
|
|
const [containerConfig, setContainerConfig] = useState<{
|
|
|
|
|
maxCpuCores: number,
|
|
|
|
|
maxMemoryMiB: number
|
|
|
|
|
}>({ maxCpuCores: 4, maxMemoryMiB: 4096 }); // 容器配置数据
|
|
|
|
|
const [configLoaded, setConfigLoaded] = useState(false); // 容器配置是否已加载
|
|
|
|
|
const [configLoading, setConfigLoading] = useState(false); // 容器配置加载中
|
|
|
|
|
|
|
|
|
|
// 处理取消
|
|
|
|
|
const handleCancel = () => {
|
|
|
|
|
@ -135,6 +153,8 @@ const ContainerModal = ({ addItem, visible, envType, setVisible, onSuccess }) =>
|
|
|
|
|
setSelectedNetworkType([]);
|
|
|
|
|
setCurrentNetworkCard('');
|
|
|
|
|
setCurrentIp('');
|
|
|
|
|
setConfigLoaded(false);
|
|
|
|
|
setConfigLoading(false);
|
|
|
|
|
setVisible(false);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@ -168,7 +188,7 @@ const ContainerModal = ({ addItem, visible, envType, setVisible, onSuccess }) =>
|
|
|
|
|
volumes: directoryMountData, // 目录挂载
|
|
|
|
|
devices: deviceMountData, // 设备挂载
|
|
|
|
|
// 下面是暂时写死的数据,
|
|
|
|
|
'restartPolicy': 'always',
|
|
|
|
|
'restartPolicy': 'always'
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const res: any = await containerRegister(submitData);
|
|
|
|
|
@ -189,6 +209,51 @@ const ContainerModal = ({ addItem, visible, envType, setVisible, onSuccess }) =>
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getContainerConfig = async () => {
|
|
|
|
|
setConfigLoading(true);
|
|
|
|
|
try {
|
|
|
|
|
const res: any = await getContainerLimit(addItem.id);
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
setContainerConfig(res.data);
|
|
|
|
|
setConfigLoaded(true);
|
|
|
|
|
// 设置表单默认值
|
|
|
|
|
form.setFieldsValue({
|
|
|
|
|
cpuCount: 1,
|
|
|
|
|
memory: 2048,
|
|
|
|
|
useGpu: false
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
setConfigLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 动态生成CPU核数的marks
|
|
|
|
|
const cpuMarks = useMemo(() => {
|
|
|
|
|
const max = containerConfig.maxCpuCores;
|
|
|
|
|
const marks: Record<number, string> = {};
|
|
|
|
|
marks[1] = '1核';
|
|
|
|
|
if (max > 1) marks[max] = `${max}核`;
|
|
|
|
|
// 中间值不显示文字
|
|
|
|
|
for (let i = 2; i < max; i++) {
|
|
|
|
|
marks[i] = '';
|
|
|
|
|
}
|
|
|
|
|
return marks;
|
|
|
|
|
}, [containerConfig.maxCpuCores]);
|
|
|
|
|
|
|
|
|
|
// 动态生成内存的marks (按2的幂次方: 1, 2, 4, 8, 16GB)
|
|
|
|
|
const memoryMarks = useMemo(() => {
|
|
|
|
|
const max = containerConfig.maxMemoryMiB;
|
|
|
|
|
const marks: Record<number, string> = {};
|
|
|
|
|
for (let gb = 2; gb <= 128; gb *= 2) {
|
|
|
|
|
const mb = gb * 1024;
|
|
|
|
|
if (mb <= max) {
|
|
|
|
|
marks[mb] = `${gb}GB`;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return marks;
|
|
|
|
|
}, [containerConfig.maxMemoryMiB]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (envType.length > 0) setEnvTypeOptions(envType);
|
|
|
|
|
}, [envType]);
|
|
|
|
|
@ -196,12 +261,7 @@ const ContainerModal = ({ addItem, visible, envType, setVisible, onSuccess }) =>
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (visible) {
|
|
|
|
|
// 设置表单默认值
|
|
|
|
|
form.setFieldsValue({
|
|
|
|
|
cpuCount: 1,
|
|
|
|
|
memory: 2048,
|
|
|
|
|
useGpu: false
|
|
|
|
|
});
|
|
|
|
|
// 不再自动加载,等用户点击按钮
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// 关闭时重置表单和数据
|
|
|
|
|
@ -213,6 +273,8 @@ const ContainerModal = ({ addItem, visible, envType, setVisible, onSuccess }) =>
|
|
|
|
|
setSelectedNetworkType([]);
|
|
|
|
|
setCurrentNetworkCard('');
|
|
|
|
|
setCurrentIp('');
|
|
|
|
|
setConfigLoaded(false);
|
|
|
|
|
setConfigLoading(false);
|
|
|
|
|
}
|
|
|
|
|
}, [visible]);
|
|
|
|
|
|
|
|
|
|
@ -228,195 +290,209 @@ const ContainerModal = ({ addItem, visible, envType, setVisible, onSuccess }) =>
|
|
|
|
|
style={{ width: '80%' }}
|
|
|
|
|
>
|
|
|
|
|
<Form form={form} autoComplete="off" labelCol={{ flex: 'none' }}>
|
|
|
|
|
<>
|
|
|
|
|
<Grid.Row gutter={8}>
|
|
|
|
|
<Grid.Col span={12}>
|
|
|
|
|
<FormItem
|
|
|
|
|
label="CPU核数:"
|
|
|
|
|
field="cpuCount"
|
|
|
|
|
initialValue={1}
|
|
|
|
|
>
|
|
|
|
|
<Slider
|
|
|
|
|
min={1}
|
|
|
|
|
max={4}
|
|
|
|
|
step={1}
|
|
|
|
|
showTicks={true}
|
|
|
|
|
marks={{
|
|
|
|
|
1: '1核',
|
|
|
|
|
2: '',
|
|
|
|
|
3: '',
|
|
|
|
|
4: '4核'
|
|
|
|
|
}}
|
|
|
|
|
style={{
|
|
|
|
|
width: '90%',
|
|
|
|
|
whiteSpace: 'nowrap'
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</FormItem>
|
|
|
|
|
</Grid.Col>
|
|
|
|
|
<Grid.Col span={12}>
|
|
|
|
|
<FormItem
|
|
|
|
|
label="是否使用GPU:"
|
|
|
|
|
field="useGpu"
|
|
|
|
|
initialValue={false}
|
|
|
|
|
triggerPropName="checked"
|
|
|
|
|
>
|
|
|
|
|
<Switch checkedText="ON" uncheckedText="OFF" />
|
|
|
|
|
</FormItem>
|
|
|
|
|
</Grid.Col>
|
|
|
|
|
</Grid.Row>
|
|
|
|
|
<FormItem
|
|
|
|
|
label="最大内存:"
|
|
|
|
|
field="memory"
|
|
|
|
|
initialValue={2048}
|
|
|
|
|
>
|
|
|
|
|
<Slider
|
|
|
|
|
min={64}
|
|
|
|
|
max={4069}
|
|
|
|
|
step={64}
|
|
|
|
|
marks={{
|
|
|
|
|
64: '64MB',
|
|
|
|
|
1024: '1GB',
|
|
|
|
|
2048: '2GB',
|
|
|
|
|
4069: '4GB'
|
|
|
|
|
}}
|
|
|
|
|
showInput={{
|
|
|
|
|
hideControl: false,
|
|
|
|
|
suffix: 'MB',
|
|
|
|
|
style: {
|
|
|
|
|
width: 100
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
style={{ width: '100%' }}
|
|
|
|
|
/>
|
|
|
|
|
</FormItem>
|
|
|
|
|
<Grid.Row gutter={8}>
|
|
|
|
|
<Grid.Col span={8}>
|
|
|
|
|
<FormItem
|
|
|
|
|
label="网络模式:"
|
|
|
|
|
field="networkMode"
|
|
|
|
|
rules={[{ required: true, message: '请选择网络模式' }]}
|
|
|
|
|
style={{ flexWrap: 'nowrap' }}
|
|
|
|
|
>
|
|
|
|
|
<Select
|
|
|
|
|
placeholder="请选择网络模式"
|
|
|
|
|
style={{ width: '80%', minWidth: 120 }}
|
|
|
|
|
onChange={(value) => fetchNetworkMode(value, addItem.id)}
|
|
|
|
|
{/* 容器资源配置区域 - 需要点击按钮获取 */}
|
|
|
|
|
{!configLoaded ? (
|
|
|
|
|
<div style={{
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
padding: '20px 0',
|
|
|
|
|
marginBottom: 16,
|
|
|
|
|
background: '#f7f8fa',
|
|
|
|
|
borderRadius: 4
|
|
|
|
|
}}>
|
|
|
|
|
<Button
|
|
|
|
|
type="primary"
|
|
|
|
|
loading={configLoading}
|
|
|
|
|
onClick={getContainerConfig}
|
|
|
|
|
>
|
|
|
|
|
获取容器配置
|
|
|
|
|
</Button>
|
|
|
|
|
<div style={{ marginTop: 8, color: '#86909c', fontSize: 13 }}>
|
|
|
|
|
点击按钮获取当前环境的容器资源限制
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<>
|
|
|
|
|
<Grid.Row gutter={8}>
|
|
|
|
|
<Grid.Col span={12}>
|
|
|
|
|
<FormItem
|
|
|
|
|
label="CPU核数:"
|
|
|
|
|
field="cpuCount"
|
|
|
|
|
initialValue={1}
|
|
|
|
|
>
|
|
|
|
|
{netType.map((option, index) => (
|
|
|
|
|
<Option key={option.value} value={option.value}>
|
|
|
|
|
{option.label}
|
|
|
|
|
</Option>
|
|
|
|
|
))}
|
|
|
|
|
</Select>
|
|
|
|
|
</FormItem>
|
|
|
|
|
</Grid.Col>
|
|
|
|
|
<Grid.Col span={8}>
|
|
|
|
|
<FormItem
|
|
|
|
|
label="网卡:"
|
|
|
|
|
field="networkType"
|
|
|
|
|
rules={[{ required: true, message: '请选择网卡' }]}
|
|
|
|
|
style={{ flexWrap: 'nowrap' }}
|
|
|
|
|
>
|
|
|
|
|
<Select
|
|
|
|
|
placeholder="请选择网卡"
|
|
|
|
|
style={{ width: '90%', minWidth: 120 }}
|
|
|
|
|
value={currentNetworkCard}
|
|
|
|
|
onChange={value => {
|
|
|
|
|
setCurrentNetworkCard(value);
|
|
|
|
|
form.setFieldValue('networkType', value);
|
|
|
|
|
const selectedCard = networkTypeList.find(item => item.name === value);
|
|
|
|
|
setSelectedNetworkType(selectedCard ? [selectedCard] : []);
|
|
|
|
|
}}
|
|
|
|
|
<Slider
|
|
|
|
|
min={1}
|
|
|
|
|
max={containerConfig.maxCpuCores}
|
|
|
|
|
step={1}
|
|
|
|
|
showTicks={true}
|
|
|
|
|
marks={cpuMarks}
|
|
|
|
|
style={{
|
|
|
|
|
width: '90%',
|
|
|
|
|
whiteSpace: 'nowrap'
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</FormItem>
|
|
|
|
|
</Grid.Col>
|
|
|
|
|
<Grid.Col span={12}>
|
|
|
|
|
<FormItem
|
|
|
|
|
label="是否使用GPU:"
|
|
|
|
|
field="useGpu"
|
|
|
|
|
initialValue={false}
|
|
|
|
|
triggerPropName="checked"
|
|
|
|
|
>
|
|
|
|
|
{networkTypeList.map((option, index) => (
|
|
|
|
|
<Option key={option.type} value={option.name}>
|
|
|
|
|
{option.name}
|
|
|
|
|
</Option>
|
|
|
|
|
))}
|
|
|
|
|
</Select>
|
|
|
|
|
</FormItem>
|
|
|
|
|
</Grid.Col>
|
|
|
|
|
<Grid.Col span={8}>
|
|
|
|
|
<FormItem
|
|
|
|
|
label="IP:"
|
|
|
|
|
field="ip"
|
|
|
|
|
style={{ flexWrap: 'nowrap' }}
|
|
|
|
|
<Switch checkedText="ON" uncheckedText="OFF" />
|
|
|
|
|
</FormItem>
|
|
|
|
|
</Grid.Col>
|
|
|
|
|
</Grid.Row>
|
|
|
|
|
<FormItem
|
|
|
|
|
label="最大内存:"
|
|
|
|
|
field="memory"
|
|
|
|
|
initialValue={2048}
|
|
|
|
|
>
|
|
|
|
|
<Slider
|
|
|
|
|
min={1024}
|
|
|
|
|
max={containerConfig.maxMemoryMiB}
|
|
|
|
|
step={64}
|
|
|
|
|
marks={memoryMarks}
|
|
|
|
|
showInput={{
|
|
|
|
|
hideControl: false,
|
|
|
|
|
suffix: 'MB',
|
|
|
|
|
style: {
|
|
|
|
|
width: 100
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
style={{ width: '100%' }}
|
|
|
|
|
/>
|
|
|
|
|
</FormItem>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{/* 以下配置默认展示 */}
|
|
|
|
|
<Grid.Row gutter={8}>
|
|
|
|
|
<Grid.Col span={8}>
|
|
|
|
|
<FormItem
|
|
|
|
|
label="网络模式:"
|
|
|
|
|
field="networkMode"
|
|
|
|
|
rules={[{ required: true, message: '请选择网络模式' }]}
|
|
|
|
|
style={{ flexWrap: 'nowrap' }}
|
|
|
|
|
>
|
|
|
|
|
<Select
|
|
|
|
|
placeholder="请选择网络模式"
|
|
|
|
|
style={{ width: '80%', minWidth: 120 }}
|
|
|
|
|
onChange={(value) => fetchNetworkMode(value, addItem.id)}
|
|
|
|
|
>
|
|
|
|
|
{netType.map((option, index) => (
|
|
|
|
|
<Option key={option.value} value={option.value}>
|
|
|
|
|
{option.label}
|
|
|
|
|
</Option>
|
|
|
|
|
))}
|
|
|
|
|
</Select>
|
|
|
|
|
</FormItem>
|
|
|
|
|
</Grid.Col>
|
|
|
|
|
<Grid.Col span={8}>
|
|
|
|
|
<FormItem
|
|
|
|
|
label="网卡:"
|
|
|
|
|
field="networkType"
|
|
|
|
|
rules={[{ required: true, message: '请选择网卡' }]}
|
|
|
|
|
style={{ flexWrap: 'nowrap' }}
|
|
|
|
|
>
|
|
|
|
|
<Select
|
|
|
|
|
placeholder="请选择网卡"
|
|
|
|
|
style={{ width: '90%', minWidth: 120 }}
|
|
|
|
|
value={currentNetworkCard}
|
|
|
|
|
onChange={value => {
|
|
|
|
|
setCurrentNetworkCard(value);
|
|
|
|
|
form.setFieldValue('networkType', value);
|
|
|
|
|
const selectedCard = networkTypeList.find(item => item.name === value);
|
|
|
|
|
setSelectedNetworkType(selectedCard ? [selectedCard] : []);
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Input
|
|
|
|
|
style={{ width: '90%', minWidth: 120 }}
|
|
|
|
|
allowClear
|
|
|
|
|
placeholder="请输入IP"
|
|
|
|
|
value={currentIp}
|
|
|
|
|
onChange={(value) => {
|
|
|
|
|
setCurrentIp(value);
|
|
|
|
|
form.setFieldValue('ip', value);
|
|
|
|
|
}}
|
|
|
|
|
onBlur={(e) => {
|
|
|
|
|
const value = e.target.value;
|
|
|
|
|
if (value) {
|
|
|
|
|
// IP地址正则表达式
|
|
|
|
|
const ipRegex = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
|
|
|
if (!ipRegex.test(value)) {
|
|
|
|
|
Message.warning('请输入有效的IP地址');
|
|
|
|
|
}
|
|
|
|
|
{networkTypeList.map((option, index) => (
|
|
|
|
|
<Option key={option.type} value={option.name}>
|
|
|
|
|
{option.name}
|
|
|
|
|
</Option>
|
|
|
|
|
))}
|
|
|
|
|
</Select>
|
|
|
|
|
</FormItem>
|
|
|
|
|
</Grid.Col>
|
|
|
|
|
<Grid.Col span={8}>
|
|
|
|
|
<FormItem
|
|
|
|
|
label="IP:"
|
|
|
|
|
field="ip"
|
|
|
|
|
style={{ flexWrap: 'nowrap' }}
|
|
|
|
|
>
|
|
|
|
|
<Input
|
|
|
|
|
style={{ width: '90%', minWidth: 120 }}
|
|
|
|
|
allowClear
|
|
|
|
|
placeholder="请输入IP"
|
|
|
|
|
value={currentIp}
|
|
|
|
|
onChange={(value) => {
|
|
|
|
|
setCurrentIp(value);
|
|
|
|
|
form.setFieldValue('ip', value);
|
|
|
|
|
}}
|
|
|
|
|
onBlur={(e) => {
|
|
|
|
|
const value = e.target.value;
|
|
|
|
|
if (value) {
|
|
|
|
|
// IP地址正则表达式
|
|
|
|
|
const ipRegex = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
|
|
|
if (!ipRegex.test(value)) {
|
|
|
|
|
Message.warning('请输入有效的IP地址');
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<div style={{
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
color: '#c0c4cc',
|
|
|
|
|
marginTop: 10
|
|
|
|
|
}}>所属子网: {selectedNetworkType.length > 0 ? selectedNetworkType[0]?.subnet : '-'}</div>
|
|
|
|
|
</FormItem>
|
|
|
|
|
</Grid.Col>
|
|
|
|
|
</Grid.Row>
|
|
|
|
|
<FormItem label="端口映射:">
|
|
|
|
|
<EditableTable
|
|
|
|
|
columns={portColumns}
|
|
|
|
|
data={portMappingData}
|
|
|
|
|
onDataChange={(newData) => setPortMappingData(newData)}
|
|
|
|
|
showAddButton={true}
|
|
|
|
|
addButtonText="添加行"
|
|
|
|
|
showDeleteButton={true}
|
|
|
|
|
deleteButtonText="删除"
|
|
|
|
|
tableProps={{
|
|
|
|
|
pagination: { pageSize: 5 },
|
|
|
|
|
scroll: { y: 400 }
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</FormItem>
|
|
|
|
|
<FormItem label="目录挂载:">
|
|
|
|
|
<EditableTable
|
|
|
|
|
columns={directoryColumns}
|
|
|
|
|
data={directoryMountData}
|
|
|
|
|
onDataChange={(newData) => setDirectoryMountData(newData)}
|
|
|
|
|
showAddButton={true}
|
|
|
|
|
addButtonText="添加行"
|
|
|
|
|
showDeleteButton={true}
|
|
|
|
|
deleteButtonText="删除"
|
|
|
|
|
tableProps={{
|
|
|
|
|
pagination: { pageSize: 5 },
|
|
|
|
|
scroll: { y: 400 }
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</FormItem>
|
|
|
|
|
<FormItem label="设备挂载:">
|
|
|
|
|
<EditableTable
|
|
|
|
|
columns={deviceColumns}
|
|
|
|
|
data={deviceMountData}
|
|
|
|
|
onDataChange={(newData) => setDeviceMountData(newData)}
|
|
|
|
|
showAddButton={true}
|
|
|
|
|
addButtonText="添加行"
|
|
|
|
|
showDeleteButton={true}
|
|
|
|
|
deleteButtonText="删除"
|
|
|
|
|
tableProps={{
|
|
|
|
|
pagination: { pageSize: 5 },
|
|
|
|
|
scroll: { y: 400 }
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</FormItem>
|
|
|
|
|
</>
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<div style={{
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
color: '#c0c4cc',
|
|
|
|
|
marginTop: 10
|
|
|
|
|
}}>所属子网: {selectedNetworkType.length > 0 ? selectedNetworkType[0]?.subnet : '-'}</div>
|
|
|
|
|
</FormItem>
|
|
|
|
|
</Grid.Col>
|
|
|
|
|
</Grid.Row>
|
|
|
|
|
<FormItem label="端口映射:">
|
|
|
|
|
<EditableTable
|
|
|
|
|
columns={portColumns}
|
|
|
|
|
data={portMappingData}
|
|
|
|
|
onDataChange={(newData) => setPortMappingData(newData)}
|
|
|
|
|
showAddButton={true}
|
|
|
|
|
addButtonText="添加行"
|
|
|
|
|
showDeleteButton={true}
|
|
|
|
|
deleteButtonText="删除"
|
|
|
|
|
tableProps={{
|
|
|
|
|
pagination: { pageSize: 5 },
|
|
|
|
|
scroll: { y: 400 }
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</FormItem>
|
|
|
|
|
<FormItem label="目录挂载:">
|
|
|
|
|
<EditableTable
|
|
|
|
|
columns={directoryColumns}
|
|
|
|
|
data={directoryMountData}
|
|
|
|
|
onDataChange={(newData) => setDirectoryMountData(newData)}
|
|
|
|
|
showAddButton={true}
|
|
|
|
|
addButtonText="添加行"
|
|
|
|
|
showDeleteButton={true}
|
|
|
|
|
deleteButtonText="删除"
|
|
|
|
|
tableProps={{
|
|
|
|
|
pagination: { pageSize: 5 },
|
|
|
|
|
scroll: { y: 400 }
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</FormItem>
|
|
|
|
|
<FormItem label="设备挂载:">
|
|
|
|
|
<EditableTable
|
|
|
|
|
columns={deviceColumns}
|
|
|
|
|
data={deviceMountData}
|
|
|
|
|
onDataChange={(newData) => setDeviceMountData(newData)}
|
|
|
|
|
showAddButton={true}
|
|
|
|
|
addButtonText="添加行"
|
|
|
|
|
showDeleteButton={true}
|
|
|
|
|
deleteButtonText="删除"
|
|
|
|
|
tableProps={{
|
|
|
|
|
pagination: { pageSize: 5 },
|
|
|
|
|
scroll: { y: 400 }
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</FormItem>
|
|
|
|
|
</Form>
|
|
|
|
|
|
|
|
|
|
</Modal>
|
|
|
|
|
|