|
|
|
@ -10,12 +10,15 @@ import {
|
|
|
|
TableColumnProps,
|
|
|
|
TableColumnProps,
|
|
|
|
Message,
|
|
|
|
Message,
|
|
|
|
Modal,
|
|
|
|
Modal,
|
|
|
|
Notification
|
|
|
|
Notification,
|
|
|
|
|
|
|
|
Tag
|
|
|
|
} from '@arco-design/web-react';
|
|
|
|
} from '@arco-design/web-react';
|
|
|
|
import { getComponentClassify } from '@/api/componentClassify';
|
|
|
|
import { getComponentClassify } from '@/api/componentClassify';
|
|
|
|
import { IconSearch } from '@arco-design/web-react/icon';
|
|
|
|
import { IconSearch } from '@arco-design/web-react/icon';
|
|
|
|
|
|
|
|
import ContainerModal from './containerModal';
|
|
|
|
import AddModal from './addModal';
|
|
|
|
import AddModal from './addModal';
|
|
|
|
import { getEnvConfigList, deleteEnvConfig, testEnv } from '@/api/componentDeployEnv';
|
|
|
|
import { getEnvConfigList, deleteEnvConfig, testEnv } from '@/api/componentDeployEnv';
|
|
|
|
|
|
|
|
import { startContainer, stopContainer } from '@/api/userContainer';
|
|
|
|
|
|
|
|
|
|
|
|
const Option = Select.Option;
|
|
|
|
const Option = Select.Option;
|
|
|
|
|
|
|
|
|
|
|
|
@ -23,11 +26,13 @@ const ComponentEnv = () => {
|
|
|
|
const [envType, setEnvType] = useState([]); // 环境类型
|
|
|
|
const [envType, setEnvType] = useState([]); // 环境类型
|
|
|
|
const [architectureType, setArchitectureType] = useState(['x86_64', 'aarch64']); // 结构类型
|
|
|
|
const [architectureType, setArchitectureType] = useState(['x86_64', 'aarch64']); // 结构类型
|
|
|
|
const [visible, setVisible] = useState(false);
|
|
|
|
const [visible, setVisible] = useState(false);
|
|
|
|
|
|
|
|
const [visible1, setVisible1] = useState(false);
|
|
|
|
const [data, setData] = useState([]);
|
|
|
|
const [data, setData] = useState([]);
|
|
|
|
const [editingRecord, setEditingRecord] = useState(null);
|
|
|
|
const [editingRecord, setEditingRecord] = useState(null);
|
|
|
|
const [selectedEnvType, setSelectedEnvType] = useState(null); // 选中的环境类型
|
|
|
|
const [selectedEnvType, setSelectedEnvType] = useState(null); // 选中的环境类型
|
|
|
|
const [selectedArch, setSelectedArch] = useState(null); // 选中的架构类型
|
|
|
|
const [selectedArch, setSelectedArch] = useState(null); // 选中的架构类型
|
|
|
|
const [searchText, setSearchText] = useState(''); // 搜索文本
|
|
|
|
const [searchText, setSearchText] = useState(''); // 搜索文本
|
|
|
|
|
|
|
|
const [addItem, setAddItem] = useState(null); // 点击环境配置按钮时记录当前信息
|
|
|
|
|
|
|
|
|
|
|
|
const columns: TableColumnProps[] = [
|
|
|
|
const columns: TableColumnProps[] = [
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -58,12 +63,49 @@ const ComponentEnv = () => {
|
|
|
|
title: '实例数量',
|
|
|
|
title: '实例数量',
|
|
|
|
dataIndex: 'instanceCount'
|
|
|
|
dataIndex: 'instanceCount'
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
title: '用户容器状态',
|
|
|
|
|
|
|
|
dataIndex: 'isEnable',
|
|
|
|
|
|
|
|
render: (_, record: any) => (
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
|
|
|
{record.isEnable === 'NOT_EXIST' && (
|
|
|
|
|
|
|
|
<Tag color="gray">
|
|
|
|
|
|
|
|
未注册
|
|
|
|
|
|
|
|
</Tag>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
{record.isEnable === 'RUNNING' && (
|
|
|
|
|
|
|
|
<Tag color="green">
|
|
|
|
|
|
|
|
运行
|
|
|
|
|
|
|
|
</Tag>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
{record.isEnable === 'STOPPED' && (
|
|
|
|
|
|
|
|
<Tag color="red">
|
|
|
|
|
|
|
|
停止
|
|
|
|
|
|
|
|
</Tag>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
|
title: '操作',
|
|
|
|
title: '操作',
|
|
|
|
width: 230,
|
|
|
|
width: 230,
|
|
|
|
align: 'center',
|
|
|
|
align: 'center',
|
|
|
|
render: (_, record: any) => (
|
|
|
|
render: (_, record: any) => (
|
|
|
|
<Space>
|
|
|
|
<Space>
|
|
|
|
|
|
|
|
{record.isEnable === 'NOT_EXIST' && (
|
|
|
|
|
|
|
|
<Button type="text" onClick={(record) => {
|
|
|
|
|
|
|
|
setAddItem(record);
|
|
|
|
|
|
|
|
setVisible1(true);
|
|
|
|
|
|
|
|
}}>容器配置</Button>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
{record.isEnable === 'RUNNING' && (
|
|
|
|
|
|
|
|
<Button type="text" status="danger" onClick={() => {
|
|
|
|
|
|
|
|
handleStop(record.id);
|
|
|
|
|
|
|
|
}}>停止</Button>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
{record.isEnable === 'STOPPED' && (
|
|
|
|
|
|
|
|
<Button type="text" onClick={() => handleStart(record.id)}>启动</Button>
|
|
|
|
|
|
|
|
)}
|
|
|
|
<Button type="text" onClick={() => handleTestEnv(record)}>环境测试</Button>
|
|
|
|
<Button type="text" onClick={() => handleTestEnv(record)}>环境测试</Button>
|
|
|
|
<Button type="text" onClick={() => handleConfigEnv(record)}>环境配置</Button>
|
|
|
|
<Button type="text" onClick={() => handleConfigEnv(record)}>环境配置</Button>
|
|
|
|
<Button type="text" status="danger" onClick={() => handleDeleteEnv(record)}>删除</Button>
|
|
|
|
<Button type="text" status="danger" onClick={() => handleDeleteEnv(record)}>删除</Button>
|
|
|
|
@ -72,6 +114,42 @@ const ComponentEnv = () => {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
];
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleStop = async (id) => {
|
|
|
|
|
|
|
|
const loadingMessage = Message.loading('正在停止容器,请稍候...');
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const res: any = await stopContainer(id);
|
|
|
|
|
|
|
|
loadingMessage();
|
|
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
|
|
Message.success('停止成功');
|
|
|
|
|
|
|
|
getEnvList();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
Message.error('停止失败: ' + res.message);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
loadingMessage();
|
|
|
|
|
|
|
|
Message.error('停止失败: ' + error.message);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleStart = async (id) => {
|
|
|
|
|
|
|
|
const loadingMessage = Message.loading('正在启动容器,请稍候...');
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const res: any = await startContainer(id);
|
|
|
|
|
|
|
|
loadingMessage();
|
|
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
|
|
Message.success('启动成功');
|
|
|
|
|
|
|
|
getEnvList();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
Message.error('启动失败: ' + res.message);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
loadingMessage();
|
|
|
|
|
|
|
|
Message.error('启动失败: ' + error.message);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 环境测试处理函数
|
|
|
|
// 环境测试处理函数
|
|
|
|
const handleTestEnv = async (record: any) => {
|
|
|
|
const handleTestEnv = async (record: any) => {
|
|
|
|
Message.info(`正在测试环境 ${record.name}...`);
|
|
|
|
Message.info(`正在测试环境 ${record.name}...`);
|
|
|
|
@ -166,96 +244,107 @@ const ComponentEnv = () => {
|
|
|
|
}, []);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div className={styles['component-env']}>
|
|
|
|
<>
|
|
|
|
<div className={styles['component-env-header']}>
|
|
|
|
<div className={styles['component-env']}>
|
|
|
|
<div className={styles['component-env-header-left']}>
|
|
|
|
<div className={styles['component-env-header']}>
|
|
|
|
<Space size={20}>
|
|
|
|
<div className={styles['component-env-header-left']}>
|
|
|
|
<div className={styles['handle-row-item']}>
|
|
|
|
<Space size={20}>
|
|
|
|
<span>环境类型:</span>
|
|
|
|
<div className={styles['handle-row-item']}>
|
|
|
|
<Select
|
|
|
|
<span>环境类型:</span>
|
|
|
|
placeholder="选择环境类型"
|
|
|
|
<Select
|
|
|
|
style={{ width: 154 }}
|
|
|
|
placeholder="选择环境类型"
|
|
|
|
allowClear
|
|
|
|
style={{ width: 154 }}
|
|
|
|
value={selectedEnvType}
|
|
|
|
allowClear
|
|
|
|
onChange={(value) => {
|
|
|
|
value={selectedEnvType}
|
|
|
|
setSelectedEnvType(value);
|
|
|
|
onChange={(value) => {
|
|
|
|
getEnvList(value, 'type');
|
|
|
|
setSelectedEnvType(value);
|
|
|
|
}}
|
|
|
|
getEnvList(value, 'type');
|
|
|
|
>
|
|
|
|
}}
|
|
|
|
{envType.map((option, index) => (
|
|
|
|
>
|
|
|
|
<Option key={option.id} value={option.id}>
|
|
|
|
{envType.map((option, index) => (
|
|
|
|
{option.classifyName}
|
|
|
|
<Option key={option.id} value={option.id}>
|
|
|
|
</Option>
|
|
|
|
{option.classifyName}
|
|
|
|
))}
|
|
|
|
</Option>
|
|
|
|
</Select>
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
</Select>
|
|
|
|
<div className={styles['handle-row-item']}>
|
|
|
|
</div>
|
|
|
|
<span>架构类型:</span>
|
|
|
|
<div className={styles['handle-row-item']}>
|
|
|
|
<Select
|
|
|
|
<span>架构类型:</span>
|
|
|
|
placeholder="选择架构类型"
|
|
|
|
<Select
|
|
|
|
style={{ width: 154 }}
|
|
|
|
placeholder="选择架构类型"
|
|
|
|
allowClear
|
|
|
|
style={{ width: 154 }}
|
|
|
|
value={selectedArch}
|
|
|
|
allowClear
|
|
|
|
onChange={(value) => {
|
|
|
|
value={selectedArch}
|
|
|
|
setSelectedArch(value);
|
|
|
|
onChange={(value) => {
|
|
|
|
getEnvList(value, 'arch');
|
|
|
|
setSelectedArch(value);
|
|
|
|
}}
|
|
|
|
getEnvList(value, 'arch');
|
|
|
|
>
|
|
|
|
}}
|
|
|
|
{architectureType.map((option, index) => (
|
|
|
|
>
|
|
|
|
<Option key={option} value={option}>
|
|
|
|
{architectureType.map((option, index) => (
|
|
|
|
{option}
|
|
|
|
<Option key={option} value={option}>
|
|
|
|
</Option>
|
|
|
|
{option}
|
|
|
|
))}
|
|
|
|
</Option>
|
|
|
|
</Select>
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
</Select>
|
|
|
|
</Space>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</Space>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div className={styles['component-env-header-right']}>
|
|
|
|
<div className={styles['component-env-header-right']}>
|
|
|
|
<Space split={<Divider type="vertical" />}>
|
|
|
|
<Space split={<Divider type="vertical" />}>
|
|
|
|
<div>
|
|
|
|
<div>
|
|
|
|
<Input
|
|
|
|
<Input
|
|
|
|
prefix={<IconSearch />}
|
|
|
|
prefix={<IconSearch />}
|
|
|
|
placeholder={'搜索'}
|
|
|
|
placeholder={'搜索'}
|
|
|
|
style={{ width: 236, marginRight: 5 }}
|
|
|
|
style={{ width: 236, marginRight: 5 }}
|
|
|
|
value={searchText}
|
|
|
|
value={searchText}
|
|
|
|
onChange={(value) => setSearchText(value)}
|
|
|
|
onChange={(value) => setSearchText(value)}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
|
|
style={{ borderRadius: 4 }}
|
|
|
|
|
|
|
|
onClick={() => getEnvList(searchText, 'name')}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
搜索
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<Button
|
|
|
|
<Button
|
|
|
|
type="primary"
|
|
|
|
type="primary"
|
|
|
|
style={{ borderRadius: 4 }}
|
|
|
|
style={{ borderRadius: 4 }}
|
|
|
|
onClick={() => getEnvList(searchText, 'name')}
|
|
|
|
onClick={() => {
|
|
|
|
|
|
|
|
setEditingRecord(null);
|
|
|
|
|
|
|
|
setVisible(true);
|
|
|
|
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
搜索
|
|
|
|
+ 新增
|
|
|
|
</Button>
|
|
|
|
</Button>
|
|
|
|
</div>
|
|
|
|
</Space>
|
|
|
|
<Button
|
|
|
|
</div>
|
|
|
|
type="primary"
|
|
|
|
|
|
|
|
style={{ borderRadius: 4 }}
|
|
|
|
|
|
|
|
onClick={() => {
|
|
|
|
|
|
|
|
setEditingRecord(null);
|
|
|
|
|
|
|
|
setVisible(true);
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
+ 新增
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
</Space>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<Table columns={columns} data={data} />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<AddModal
|
|
|
|
|
|
|
|
visible={visible}
|
|
|
|
|
|
|
|
envType={envType}
|
|
|
|
|
|
|
|
setVisible={setVisible}
|
|
|
|
|
|
|
|
onOk={(value) => {
|
|
|
|
|
|
|
|
setEditingRecord(value);
|
|
|
|
|
|
|
|
getEnvList(); // 新增完成后刷新列表
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
record={editingRecord}
|
|
|
|
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<Table columns={columns} data={data} />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<AddModal
|
|
|
|
<ContainerModal
|
|
|
|
visible={visible}
|
|
|
|
addItem={addItem}
|
|
|
|
envType={envType}
|
|
|
|
envType={envType}
|
|
|
|
setVisible={setVisible}
|
|
|
|
visible={visible1}
|
|
|
|
onOk={(value) => {
|
|
|
|
setVisible={setVisible1}
|
|
|
|
setEditingRecord(value);
|
|
|
|
onSuccess={getEnvList}
|
|
|
|
getEnvList(); // 新增完成后刷新列表
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
record={editingRecord}
|
|
|
|
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|