1
This commit is contained in:
parent
298866cf00
commit
5e85c51bc4
687
frontend/src/pages/Deploy/External/index.tsx
vendored
687
frontend/src/pages/Deploy/External/index.tsx
vendored
@ -1,365 +1,344 @@
|
|||||||
import React, { useState } from 'react';
|
import React, {useState} from 'react';
|
||||||
import { Card, Table, Button, Space, Modal, Form, Input, message, Select, InputNumber, Switch, Tag, Tooltip } from 'antd';
|
import {Card, Table, Button, Space, Modal, Form, Input, message, Select, InputNumber, Switch, Tag, Tooltip} from 'antd';
|
||||||
import { PlusOutlined, EditOutlined, DeleteOutlined, SyncOutlined, CheckCircleOutlined, CloseCircleOutlined, LinkOutlined, MinusCircleOutlined } from '@ant-design/icons';
|
import {PlusOutlined, EditOutlined, DeleteOutlined, SyncOutlined, CheckCircleOutlined, CloseCircleOutlined, LinkOutlined, MinusCircleOutlined} from '@ant-design/icons';
|
||||||
import type { ColumnsType } from 'antd/es/table';
|
import type {ColumnsType} from 'antd/es/table';
|
||||||
import { useTableData } from '@/hooks/useTableData';
|
import {useTableData} from '@/hooks/useTableData';
|
||||||
import * as service from './service';
|
import * as service from './service';
|
||||||
import { SystemType, AuthType, SyncStatus, ExternalSystemResponse, ExternalSystemRequest, ExternalSystemQuery } from './types';
|
import {SystemType, AuthType, SyncStatus, ExternalSystemResponse, ExternalSystemRequest, ExternalSystemQuery} from './types';
|
||||||
|
|
||||||
const ExternalPage: React.FC = () => {
|
const ExternalPage: React.FC = () => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [modalVisible, setModalVisible] = useState(false);
|
const [modalVisible, setModalVisible] = useState(false);
|
||||||
const [editingSystem, setEditingSystem] = useState<ExternalSystemResponse | null>(null);
|
const [editingSystem, setEditingSystem] = useState<ExternalSystemResponse | null>(null);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
list,
|
list,
|
||||||
loading,
|
loading,
|
||||||
pagination,
|
pagination,
|
||||||
handleTableChange,
|
handleTableChange,
|
||||||
handleCreate,
|
handleCreate,
|
||||||
handleUpdate,
|
handleUpdate,
|
||||||
handleDelete,
|
handleDelete,
|
||||||
refresh
|
refresh
|
||||||
} = useTableData<ExternalSystemResponse, ExternalSystemQuery, ExternalSystemRequest, ExternalSystemRequest>({
|
} = useTableData<ExternalSystemResponse, ExternalSystemQuery, ExternalSystemRequest, ExternalSystemRequest>({
|
||||||
service: {
|
service: {
|
||||||
list: service.getExternalSystemsPage,
|
list: service.getExternalSystemsPage,
|
||||||
create: service.createExternalSystem,
|
create: service.createExternalSystem,
|
||||||
update: service.updateExternalSystem,
|
update: service.updateExternalSystem,
|
||||||
delete: service.deleteExternalSystem
|
delete: service.deleteExternalSystem
|
||||||
},
|
},
|
||||||
config: {
|
config: {
|
||||||
message: {
|
message: {
|
||||||
createSuccess: '创建系统成功',
|
createSuccess: '创建系统成功',
|
||||||
updateSuccess: '更新系统成功',
|
updateSuccess: '更新系统成功',
|
||||||
deleteSuccess: '删除系统成功'
|
deleteSuccess: '删除系统成功'
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleAdd = () => {
|
|
||||||
setEditingSystem(null);
|
|
||||||
form.resetFields();
|
|
||||||
form.setFieldsValue({
|
|
||||||
enabled: true,
|
|
||||||
sort: 1,
|
|
||||||
authType: AuthType.BASIC
|
|
||||||
});
|
|
||||||
setModalVisible(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleEdit = (record: ExternalSystemResponse) => {
|
|
||||||
setEditingSystem(record);
|
|
||||||
form.setFieldsValue({
|
|
||||||
...record,
|
|
||||||
password: undefined // 不显示密码
|
|
||||||
});
|
|
||||||
setModalVisible(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleTestConnection = async (id: number) => {
|
|
||||||
try {
|
|
||||||
const success = await service.testConnection(id);
|
|
||||||
message.success(success ? '连接成功' : '连接失败');
|
|
||||||
} catch (error) {
|
|
||||||
message.error('测试连接失败');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleStatusChange = async (id: number, enabled: boolean) => {
|
|
||||||
try {
|
|
||||||
await service.updateStatus(id, enabled);
|
|
||||||
message.success('更新状态成功');
|
|
||||||
refresh();
|
|
||||||
} catch (error) {
|
|
||||||
message.error('更新状态失败');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
try {
|
|
||||||
const values = await form.validateFields();
|
|
||||||
let success = false;
|
|
||||||
|
|
||||||
if (editingSystem) {
|
|
||||||
success = await handleUpdate(editingSystem.id, values);
|
|
||||||
} else {
|
|
||||||
success = await handleCreate(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
setModalVisible(false);
|
|
||||||
}
|
|
||||||
} catch (error: any) {
|
|
||||||
// 如果是表单验证错误,不显示错误消息
|
|
||||||
if (!error.errorFields) {
|
|
||||||
// 如果是后端返回的错误,显示后端的错误消息
|
|
||||||
if (error.response?.data) {
|
|
||||||
message.error(error.response.data.message || '操作失败');
|
|
||||||
} else {
|
|
||||||
message.error(error.message || '操作失败');
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const columns: ColumnsType<ExternalSystemResponse> = [
|
const handleAdd = () => {
|
||||||
{
|
setEditingSystem(null);
|
||||||
title: '系统名称',
|
form.resetFields();
|
||||||
dataIndex: 'name',
|
form.setFieldsValue({
|
||||||
width: 200,
|
enabled: true,
|
||||||
},
|
sort: 1,
|
||||||
{
|
authType: AuthType.BASIC
|
||||||
title: '系统类型',
|
});
|
||||||
dataIndex: 'type',
|
setModalVisible(true);
|
||||||
width: 120,
|
};
|
||||||
render: (type: SystemType) => {
|
|
||||||
const typeMap = {
|
|
||||||
[SystemType.JENKINS]: 'Jenkins',
|
|
||||||
[SystemType.GIT]: 'Git',
|
|
||||||
[SystemType.ZENTAO]: '禅道'
|
|
||||||
};
|
|
||||||
return typeMap[type];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '系统地址',
|
|
||||||
dataIndex: 'url',
|
|
||||||
width: 300,
|
|
||||||
render: (url: string) => (
|
|
||||||
<a href={url} target="_blank" rel="noopener noreferrer">
|
|
||||||
{url}
|
|
||||||
</a>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '认证方式',
|
|
||||||
dataIndex: 'authType',
|
|
||||||
width: 120,
|
|
||||||
render: (authType: AuthType) => {
|
|
||||||
const authTypeMap = {
|
|
||||||
[AuthType.BASIC]: '用户名密码',
|
|
||||||
[AuthType.TOKEN]: '令牌',
|
|
||||||
[AuthType.OAUTH]: 'OAuth2'
|
|
||||||
};
|
|
||||||
return authTypeMap[authType];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '同步状态',
|
|
||||||
dataIndex: 'syncStatus',
|
|
||||||
width: 120,
|
|
||||||
render: (status: SyncStatus, record) => {
|
|
||||||
const statusConfig = {
|
|
||||||
[SyncStatus.SUCCESS]: { icon: <CheckCircleOutlined />, color: 'success', text: '成功' },
|
|
||||||
[SyncStatus.FAILED]: { icon: <CloseCircleOutlined />, color: 'error', text: '失败' },
|
|
||||||
[SyncStatus.RUNNING]: { icon: <SyncOutlined spin />, color: 'processing', text: '同步中' },
|
|
||||||
NONE: { icon: <MinusCircleOutlined />, color: 'default', text: '未同步' }
|
|
||||||
};
|
|
||||||
const config = statusConfig[status] || statusConfig.NONE;
|
|
||||||
return (
|
|
||||||
<Tooltip title={record.lastSyncTime || '未同步'}>
|
|
||||||
<Tag icon={config.icon} color={config.color}>
|
|
||||||
{config.text}
|
|
||||||
</Tag>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '最后连接时间',
|
|
||||||
dataIndex: 'lastConnectTime',
|
|
||||||
width: 150,
|
|
||||||
render: (time: string) => time || '-'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '状态',
|
|
||||||
dataIndex: 'enabled',
|
|
||||||
width: 100,
|
|
||||||
render: (enabled: boolean, record) => (
|
|
||||||
<Switch
|
|
||||||
checked={enabled}
|
|
||||||
onChange={(checked) => handleStatusChange(record.id, checked)}
|
|
||||||
checkedChildren="否"
|
|
||||||
unCheckedChildren="是"
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
key: 'action',
|
|
||||||
width: 280,
|
|
||||||
render: (_, record) => (
|
|
||||||
<Space>
|
|
||||||
<Button
|
|
||||||
type="link"
|
|
||||||
icon={<EditOutlined />}
|
|
||||||
onClick={() => handleEdit(record)}
|
|
||||||
>
|
|
||||||
编辑
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
type="link"
|
|
||||||
icon={<LinkOutlined />}
|
|
||||||
onClick={() => handleTestConnection(record.id)}
|
|
||||||
>
|
|
||||||
测试连接
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
type="link"
|
|
||||||
danger
|
|
||||||
icon={<DeleteOutlined />}
|
|
||||||
onClick={() => handleDelete(record.id)}
|
|
||||||
>
|
|
||||||
删除
|
|
||||||
</Button>
|
|
||||||
</Space>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
const handleEdit = (record: ExternalSystemResponse) => {
|
||||||
<div>
|
setEditingSystem(record);
|
||||||
<Card>
|
form.setFieldsValue({
|
||||||
<div style={{ marginBottom: 16 }}>
|
...record,
|
||||||
<Button
|
password: undefined // 不显示密码
|
||||||
type="primary"
|
});
|
||||||
icon={<PlusOutlined />}
|
setModalVisible(true);
|
||||||
onClick={handleAdd}
|
};
|
||||||
>
|
|
||||||
新增系统
|
const handleTestConnection = async (id: number) => {
|
||||||
</Button>
|
try {
|
||||||
|
const success = await service.testConnection(id);
|
||||||
|
message.success(success ? '连接成功' : '连接失败');
|
||||||
|
} catch (error) {
|
||||||
|
message.error('测试连接失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleStatusChange = async (id: number, enabled: boolean) => {
|
||||||
|
try {
|
||||||
|
await service.updateStatus(id, enabled);
|
||||||
|
message.success('更新状态成功');
|
||||||
|
refresh();
|
||||||
|
} catch (error) {
|
||||||
|
message.error('更新状态失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
try {
|
||||||
|
const values = await form.validateFields();
|
||||||
|
let success = false;
|
||||||
|
|
||||||
|
if (editingSystem) {
|
||||||
|
success = await handleUpdate(editingSystem.id, values);
|
||||||
|
} else {
|
||||||
|
success = await handleCreate(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
setModalVisible(false);
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
// 如果是表单验证错误,不显示错误消息
|
||||||
|
if (!error.errorFields) {
|
||||||
|
// 如果是后端返回的错误,显示后端的错误消息
|
||||||
|
if (error.response?.data) {
|
||||||
|
message.error(error.response.data.message || '操作失败');
|
||||||
|
} else {
|
||||||
|
message.error(error.message || '操作失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const columns: ColumnsType<ExternalSystemResponse> = [
|
||||||
|
{
|
||||||
|
title: '系统名称',
|
||||||
|
dataIndex: 'name',
|
||||||
|
width: 200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '系统类型',
|
||||||
|
dataIndex: 'type',
|
||||||
|
width: 120,
|
||||||
|
render: (type: SystemType) => {
|
||||||
|
const typeMap = {
|
||||||
|
[SystemType.JENKINS]: 'Jenkins',
|
||||||
|
[SystemType.GIT]: 'Git',
|
||||||
|
[SystemType.ZENTAO]: '禅道'
|
||||||
|
};
|
||||||
|
return typeMap[type];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '系统地址',
|
||||||
|
dataIndex: 'url',
|
||||||
|
width: 300,
|
||||||
|
render: (url: string) => (
|
||||||
|
<a href={url} target="_blank" rel="noopener noreferrer">
|
||||||
|
{url}
|
||||||
|
</a>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '认证方式',
|
||||||
|
dataIndex: 'authType',
|
||||||
|
width: 120,
|
||||||
|
render: (authType: AuthType) => {
|
||||||
|
const authTypeMap = {
|
||||||
|
[AuthType.BASIC]: '用户名密码',
|
||||||
|
[AuthType.TOKEN]: '令牌',
|
||||||
|
[AuthType.OAUTH]: 'OAuth2'
|
||||||
|
};
|
||||||
|
return authTypeMap[authType];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '最后连接时间',
|
||||||
|
dataIndex: 'lastConnectTime',
|
||||||
|
width: 150,
|
||||||
|
render: (time: string) => time || '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '状态',
|
||||||
|
dataIndex: 'enabled',
|
||||||
|
width: 100,
|
||||||
|
render: (enabled: boolean, record) => (
|
||||||
|
<Switch
|
||||||
|
checked={enabled}
|
||||||
|
onChange={(checked) => handleStatusChange(record.id, checked)}
|
||||||
|
checkedChildren="否"
|
||||||
|
unCheckedChildren="是"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
width: 280,
|
||||||
|
render: (_, record) => (
|
||||||
|
<Space>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
icon={<EditOutlined/>}
|
||||||
|
onClick={() => handleEdit(record)}
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
icon={<LinkOutlined/>}
|
||||||
|
onClick={() => handleTestConnection(record.id)}
|
||||||
|
>
|
||||||
|
测试连接
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
danger
|
||||||
|
icon={<DeleteOutlined/>}
|
||||||
|
onClick={() => handleDelete(record.id)}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Card>
|
||||||
|
<div style={{marginBottom: 16}}>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
icon={<PlusOutlined/>}
|
||||||
|
onClick={handleAdd}
|
||||||
|
>
|
||||||
|
新增系统
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<Table
|
||||||
|
columns={columns}
|
||||||
|
dataSource={list}
|
||||||
|
rowKey="id"
|
||||||
|
loading={loading}
|
||||||
|
pagination={pagination}
|
||||||
|
onChange={handleTableChange}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
title={editingSystem ? '编辑系统' : '新增系统'}
|
||||||
|
open={modalVisible}
|
||||||
|
onOk={handleSubmit}
|
||||||
|
onCancel={() => setModalVisible(false)}
|
||||||
|
width={600}
|
||||||
|
>
|
||||||
|
<Form
|
||||||
|
form={form}
|
||||||
|
layout="vertical"
|
||||||
|
>
|
||||||
|
<Form.Item
|
||||||
|
name="name"
|
||||||
|
label="系统名称"
|
||||||
|
rules={[{required: true, message: '请输入系统名称'}]}
|
||||||
|
>
|
||||||
|
<Input placeholder="请输入系统名称"/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
name="type"
|
||||||
|
label="系统类型"
|
||||||
|
rules={[{required: true, message: '请选择系统类型'}]}
|
||||||
|
>
|
||||||
|
<Select>
|
||||||
|
<Select.Option value={SystemType.JENKINS}>Jenkins</Select.Option>
|
||||||
|
<Select.Option value={SystemType.GIT}>Git</Select.Option>
|
||||||
|
<Select.Option value={SystemType.ZENTAO}>禅道</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
name="url"
|
||||||
|
label="系统地址"
|
||||||
|
rules={[
|
||||||
|
{required: true, message: '请输入系统地址'},
|
||||||
|
{type: 'url', message: '请输入有效的URL'}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input placeholder="请输入系统地址"/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
name="authType"
|
||||||
|
label="认证方式"
|
||||||
|
rules={[{required: true, message: '请选择认证方式'}]}
|
||||||
|
>
|
||||||
|
<Select>
|
||||||
|
<Select.Option value={AuthType.BASIC}>用户名密码</Select.Option>
|
||||||
|
<Select.Option value={AuthType.TOKEN}>令牌</Select.Option>
|
||||||
|
<Select.Option value={AuthType.OAUTH}>OAuth2</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
noStyle
|
||||||
|
shouldUpdate={(prevValues, currentValues) => prevValues.authType !== currentValues.authType}
|
||||||
|
>
|
||||||
|
{({getFieldValue}) => {
|
||||||
|
const authType = getFieldValue('authType');
|
||||||
|
if (authType === AuthType.BASIC) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Form.Item
|
||||||
|
name="username"
|
||||||
|
label="用户名"
|
||||||
|
rules={[{required: true, message: '请输入用户名'}]}
|
||||||
|
>
|
||||||
|
<Input placeholder="请输入用户名"/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name="password"
|
||||||
|
label="密码"
|
||||||
|
rules={[{required: !editingSystem, message: '请输入密码'}]}
|
||||||
|
>
|
||||||
|
<Input.Password placeholder={editingSystem ? '不修改请留空' : '请输入密码'}/>
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (authType === AuthType.TOKEN) {
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
name="token"
|
||||||
|
label="访问令牌"
|
||||||
|
rules={[{required: !editingSystem, message: '请输入访问令牌'}]}
|
||||||
|
>
|
||||||
|
<Input.Password placeholder={editingSystem ? '不修改请留空' : '请输入访问令牌'}/>
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}}
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
name="sort"
|
||||||
|
label="显示排序"
|
||||||
|
rules={[{required: true, message: '请输入显示排序'}]}
|
||||||
|
>
|
||||||
|
<InputNumber style={{width: '100%'}} min={0} placeholder="请输入显示排序"/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
name="remark"
|
||||||
|
label="备注"
|
||||||
|
>
|
||||||
|
<Input.TextArea rows={4} placeholder="请输入备注"/>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
name="enabled"
|
||||||
|
label="是否禁用"
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch checkedChildren="否" unCheckedChildren="是"/>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
<Table
|
);
|
||||||
columns={columns}
|
|
||||||
dataSource={list}
|
|
||||||
rowKey="id"
|
|
||||||
loading={loading}
|
|
||||||
pagination={pagination}
|
|
||||||
onChange={handleTableChange}
|
|
||||||
/>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Modal
|
|
||||||
title={editingSystem ? '编辑系统' : '新增系统'}
|
|
||||||
open={modalVisible}
|
|
||||||
onOk={handleSubmit}
|
|
||||||
onCancel={() => setModalVisible(false)}
|
|
||||||
width={600}
|
|
||||||
>
|
|
||||||
<Form
|
|
||||||
form={form}
|
|
||||||
layout="vertical"
|
|
||||||
>
|
|
||||||
<Form.Item
|
|
||||||
name="name"
|
|
||||||
label="系统名称"
|
|
||||||
rules={[{ required: true, message: '请输入系统名称' }]}
|
|
||||||
>
|
|
||||||
<Input placeholder="请输入系统名称" />
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<Form.Item
|
|
||||||
name="type"
|
|
||||||
label="系统类型"
|
|
||||||
rules={[{ required: true, message: '请选择系统类型' }]}
|
|
||||||
>
|
|
||||||
<Select>
|
|
||||||
<Select.Option value={SystemType.JENKINS}>Jenkins</Select.Option>
|
|
||||||
<Select.Option value={SystemType.GIT}>Git</Select.Option>
|
|
||||||
<Select.Option value={SystemType.ZENTAO}>禅道</Select.Option>
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<Form.Item
|
|
||||||
name="url"
|
|
||||||
label="系统地址"
|
|
||||||
rules={[
|
|
||||||
{ required: true, message: '请输入系统地址' },
|
|
||||||
{ type: 'url', message: '请输入有效的URL' }
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Input placeholder="请输入系统地址" />
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<Form.Item
|
|
||||||
name="authType"
|
|
||||||
label="认证方式"
|
|
||||||
rules={[{ required: true, message: '请选择认证方式' }]}
|
|
||||||
>
|
|
||||||
<Select>
|
|
||||||
<Select.Option value={AuthType.BASIC}>用户名密码</Select.Option>
|
|
||||||
<Select.Option value={AuthType.TOKEN}>令牌</Select.Option>
|
|
||||||
<Select.Option value={AuthType.OAUTH}>OAuth2</Select.Option>
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<Form.Item
|
|
||||||
noStyle
|
|
||||||
shouldUpdate={(prevValues, currentValues) => prevValues.authType !== currentValues.authType}
|
|
||||||
>
|
|
||||||
{({ getFieldValue }) => {
|
|
||||||
const authType = getFieldValue('authType');
|
|
||||||
if (authType === AuthType.BASIC) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form.Item
|
|
||||||
name="username"
|
|
||||||
label="用户名"
|
|
||||||
rules={[{ required: true, message: '请输入用户名' }]}
|
|
||||||
>
|
|
||||||
<Input placeholder="请输入用户名" />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
name="password"
|
|
||||||
label="密码"
|
|
||||||
rules={[{ required: !editingSystem, message: '请输入密码' }]}
|
|
||||||
>
|
|
||||||
<Input.Password placeholder={editingSystem ? '不修改请留空' : '请输入密码'} />
|
|
||||||
</Form.Item>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (authType === AuthType.TOKEN) {
|
|
||||||
return (
|
|
||||||
<Form.Item
|
|
||||||
name="token"
|
|
||||||
label="访问令牌"
|
|
||||||
rules={[{ required: !editingSystem, message: '请输入访问令牌' }]}
|
|
||||||
>
|
|
||||||
<Input.Password placeholder={editingSystem ? '不修改请留空' : '请输入访问令牌'} />
|
|
||||||
</Form.Item>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}}
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<Form.Item
|
|
||||||
name="sort"
|
|
||||||
label="显示排序"
|
|
||||||
rules={[{ required: true, message: '请输入显示排序' }]}
|
|
||||||
>
|
|
||||||
<InputNumber style={{ width: '100%' }} min={0} placeholder="请输入显示排序" />
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<Form.Item
|
|
||||||
name="remark"
|
|
||||||
label="备注"
|
|
||||||
>
|
|
||||||
<Input.TextArea rows={4} placeholder="请输入备注" />
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<Form.Item
|
|
||||||
name="enabled"
|
|
||||||
label="是否禁用"
|
|
||||||
valuePropName="checked"
|
|
||||||
>
|
|
||||||
<Switch checkedChildren="否" unCheckedChildren="是" />
|
|
||||||
</Form.Item>
|
|
||||||
</Form>
|
|
||||||
</Modal>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ExternalPage;
|
export default ExternalPage;
|
||||||
5
frontend/src/pages/Deploy/External/types.ts
vendored
5
frontend/src/pages/Deploy/External/types.ts
vendored
@ -1,5 +1,4 @@
|
|||||||
import { BaseResponse } from '@/types/base/response';
|
import {BaseQuery, BaseResponse} from "@/types/base";
|
||||||
import {BaseQuery} from "@/types/base";
|
|
||||||
|
|
||||||
// 系统类型枚举
|
// 系统类型枚举
|
||||||
export enum SystemType {
|
export enum SystemType {
|
||||||
@ -41,8 +40,6 @@ export interface ExternalSystemResponse extends BaseResponse {
|
|||||||
username?: string;
|
username?: string;
|
||||||
password?: string;
|
password?: string;
|
||||||
token?: string;
|
token?: string;
|
||||||
syncStatus: SyncStatus;
|
|
||||||
lastSyncTime?: string;
|
|
||||||
lastConnectTime?: string;
|
lastConnectTime?: string;
|
||||||
config?: string;
|
config?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user