add step of creating new cluster
This commit is contained in:
parent
77fc87c3dc
commit
62a61ec2de
|
@ -1,7 +1,7 @@
|
|||
elasticsearch:
|
||||
- name: default
|
||||
enabled: true
|
||||
endpoint: https://192.168.3.98:9200
|
||||
endpoint: http://127.0.0.1:9200
|
||||
basic_auth:
|
||||
username: elastic
|
||||
password: ZBdkVQUUdF1Sir4X4BGB
|
||||
|
@ -29,6 +29,7 @@ elastic:
|
|||
init_template: true
|
||||
template_name: ".infini-search-center"
|
||||
index_prefix: ".infini-search-center_"
|
||||
# load_remote_elasticsearch_configs: true
|
||||
|
||||
search-center:
|
||||
ui_path: .public
|
||||
|
|
|
@ -442,6 +442,12 @@ export default [
|
|||
name: 'cluster',
|
||||
component: './System/Cluster/Index',
|
||||
},
|
||||
{
|
||||
path: '/system/cluster/regist',
|
||||
name: 'registCluster',
|
||||
component: './System/Cluster/Step',
|
||||
hideInMenu: true
|
||||
},
|
||||
{
|
||||
path: '/system/cluster/edit',
|
||||
name: 'editCluster',
|
||||
|
|
|
@ -29,6 +29,8 @@ import { IndexPatternCreationOption } from '../../types';
|
|||
import { CreateButton } from '../../create_button';
|
||||
import { Illustration } from './assets/index_pattern_illustration';
|
||||
import { ManagementAppMountParams } from '../../../../../management/public';
|
||||
import Link from 'umi/link';
|
||||
import Exception from '@/components/Exception';
|
||||
|
||||
interface Props {
|
||||
canSave: boolean;
|
||||
|
@ -53,9 +55,9 @@ export const EmptyIndexPatternPrompt = ({
|
|||
horizontalPosition="center"
|
||||
>
|
||||
<EuiFlexGroup gutterSize="xl" alignItems="center" direction="rowReverse" wrap>
|
||||
<EuiFlexItem grow={1} className="inpEmptyIndexPatternPrompt__illustration">
|
||||
{/* <EuiFlexItem grow={1} className="inpEmptyIndexPatternPrompt__illustration">
|
||||
<Illustration />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexItem> */}
|
||||
<EuiFlexItem grow={2} className="inpEmptyIndexPatternPrompt__text">
|
||||
<EuiText grow={false}>
|
||||
<h2>
|
||||
|
|
|
@ -123,6 +123,7 @@ export default {
|
|||
|
||||
'menu.system': 'SYSTEM',
|
||||
'menu.system.cluster': 'CLUSTERS',
|
||||
'menu.system.registCluster': 'REGIST CLUSTER',
|
||||
'menu.system.editCluster': 'EDIT CLUSTER',
|
||||
'menu.system.settings': 'SETTINGS',
|
||||
'menu.system.settings.global': 'GLOBAL',
|
||||
|
|
|
@ -130,7 +130,8 @@ export default {
|
|||
|
||||
'menu.system': '系统管理',
|
||||
'menu.system.cluster': '集群管理',
|
||||
'menu.system.editCluster': '集群编辑',
|
||||
'menu.system.registCluster': '集群注册',
|
||||
'menu.system.editCluster': '集群修改',
|
||||
'menu.system.settings': '系统设置',
|
||||
'menu.system.settings.global': '全局设置',
|
||||
'menu.system.settings.gateway': '网关设置',
|
||||
|
|
|
@ -146,7 +146,7 @@ const vstyle = {
|
|||
const MonitorDatePicker = ({timeRange, commonlyUsedRanges, onChange, isLoading}) => {
|
||||
// const [recentlyUsedRanges, setRecentlyUsedRanges] = useState([]);
|
||||
const [isPaused, setIsPaused] = useState(true);
|
||||
const [refreshInterval, setRefreshInterval] = useState();
|
||||
const [refreshInterval, setRefreshInterval] = useState(10000);
|
||||
|
||||
const onTimeChange = ({ start, end }) => {
|
||||
onChange({
|
||||
|
|
|
@ -164,8 +164,8 @@ const filterManager = new FilterManager();
|
|||
const storage = new Storage(localStorage);
|
||||
const queryStringManager = new QueryStringManager(storage);
|
||||
const timefilterConfig = {
|
||||
timeDefaults: { from: 'now-15m', to: 'now' },
|
||||
refreshIntervalDefaults: { pause: false, value: 0 },
|
||||
timeDefaults: { from: 'now-1y', to: 'now' },
|
||||
refreshIntervalDefaults: { pause: true, value: 10000 },
|
||||
};
|
||||
const timeHistory = new TimeHistory(storage);
|
||||
const timefilter = new Timefilter(timefilterConfig, timeHistory);
|
||||
|
|
|
@ -53,7 +53,7 @@ class ClusterForm extends React.Component{
|
|||
//console.log(values);
|
||||
let newVals = {
|
||||
name: values.name,
|
||||
endpoint: values.endpoint,
|
||||
host: values.host,
|
||||
basic_auth: {
|
||||
username: values.username,
|
||||
password: values.password,
|
||||
|
@ -61,7 +61,8 @@ class ClusterForm extends React.Component{
|
|||
description: values.description,
|
||||
enabled: values.enabled,
|
||||
monitored: values.monitored,
|
||||
order: values.order,
|
||||
schema: values.isTLS === true ? 'https': 'http',
|
||||
// order: values.order,
|
||||
}
|
||||
if(clusterConfig.editMode === 'NEW') {
|
||||
dispatch({
|
||||
|
@ -125,7 +126,6 @@ class ClusterForm extends React.Component{
|
|||
router.push('/system/cluster');
|
||||
}}>返回</Button>]}
|
||||
>
|
||||
{/* <NewCluster/> */}
|
||||
<Form {...formItemLayout}>
|
||||
<Form.Item label="集群名称">
|
||||
{getFieldDecorator('name', {
|
||||
|
@ -138,20 +138,31 @@ class ClusterForm extends React.Component{
|
|||
],
|
||||
})(<Input autoComplete='off' placeholder="cluster-name" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="集群 URL">
|
||||
{getFieldDecorator('endpoint', {
|
||||
initialValue: editValue.endpoint,
|
||||
<Form.Item label="集群地址">
|
||||
{getFieldDecorator('host', {
|
||||
initialValue: editValue.host,
|
||||
rules: [
|
||||
{
|
||||
type: 'url', //https://github.com/yiminghe/async-validator#type
|
||||
message: 'The input is not valid url!',
|
||||
type: 'string',
|
||||
pattern: /^[\w\.]+\:\d+$/, //(https?:\/\/)?
|
||||
message: '请输入域名或 IP 地址和端口号',
|
||||
},
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input cluster name!',
|
||||
message: '请输入域名或 IP 地址和端口号!',
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="http://127.0.0.1:9200" />)}
|
||||
})(<Input placeholder="127.0.0.1:9200" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="TLS">
|
||||
{getFieldDecorator('isTLS', {
|
||||
initialValue: editValue?.schema === "https",
|
||||
})(
|
||||
<Switch
|
||||
defaultChecked={editValue?.schema === "https"}
|
||||
checkedChildren={<Icon type="check" />}
|
||||
unCheckedChildren={<Icon type="close" />}
|
||||
/>)}
|
||||
</Form.Item>
|
||||
<Form.Item label="是否需要身份验证">
|
||||
<Switch
|
||||
|
@ -177,22 +188,17 @@ class ClusterForm extends React.Component{
|
|||
})(<Input.Password />)}
|
||||
</Form.Item>
|
||||
</div>):''}
|
||||
{/* <Form.Item label="Elasticsearch 版本">
|
||||
{getFieldDecorator('version', {
|
||||
initialValue: editValue.version || '',
|
||||
})(<Input readOnly={true} />)}
|
||||
</Form.Item> */}
|
||||
<Form.Item label="排序权重">
|
||||
{/* <Form.Item label="排序权重">
|
||||
{getFieldDecorator('order', {
|
||||
initialValue: editValue.order || 0,
|
||||
})(<InputNumber />)}
|
||||
</Form.Item>
|
||||
</Form.Item> */}
|
||||
<Form.Item label="描述">
|
||||
{getFieldDecorator('description', {
|
||||
initialValue: editValue.description,
|
||||
})(<Input.TextArea placeholder="集群应用描述" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="是否启用">
|
||||
{/* <Form.Item label="是否启用">
|
||||
{getFieldDecorator('enabled', {
|
||||
valuePropName: 'checked',
|
||||
initialValue: typeof editValue.enabled === 'undefined' ? true: editValue.enabled,
|
||||
|
@ -200,7 +206,7 @@ class ClusterForm extends React.Component{
|
|||
checkedChildren={<Icon type="check" />}
|
||||
unCheckedChildren={<Icon type="close" />}
|
||||
/>)}
|
||||
</Form.Item>
|
||||
</Form.Item> */}
|
||||
<Form.Item label="启用监控">
|
||||
{getFieldDecorator('monitored', {
|
||||
valuePropName: 'checked',
|
||||
|
@ -214,9 +220,6 @@ class ClusterForm extends React.Component{
|
|||
<Button type="primary" onClick={this.handleSubmit}>
|
||||
{editMode === 'NEW' ? '注册': '保存'}
|
||||
</Button>
|
||||
{/* <Button style={{marginLeft:20}}>
|
||||
测试连接
|
||||
</Button> */}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Card>
|
||||
|
|
|
@ -40,14 +40,14 @@ class Index extends React.Component {
|
|||
}
|
||||
}, {
|
||||
title: '部署环境',
|
||||
dataIndex: 'business_department',
|
||||
key: 'business_department',
|
||||
dataIndex: 'deploy_env',
|
||||
key: 'deploy_env',
|
||||
render: ()=>{
|
||||
return 'PROD'
|
||||
}
|
||||
},{
|
||||
title: '程序版本',
|
||||
dataIndex: 'status.version',
|
||||
dataIndex: 'version',
|
||||
key: 'elasticsearch_version',
|
||||
// render: (data)=>{
|
||||
// return
|
||||
|
@ -212,7 +212,7 @@ class Index extends React.Component {
|
|||
onChange={this.handleEnabledChange}
|
||||
defaultChecked
|
||||
/>是否启用</span>
|
||||
<Link to='/system/cluster/edit' onClick={this.handleNewClick}> <Button type="primary" icon="plus">新建集群</Button></Link>
|
||||
<Link to='/system/cluster/regist' onClick={this.handleNewClick}> <Button type="primary" icon="plus">注册集群</Button></Link>
|
||||
</div>
|
||||
</div>
|
||||
<Table
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import { Steps, Button, message } from 'antd';
|
||||
import { Steps, Button, message, Spin, Card } from 'antd';
|
||||
import {connect} from "dva";
|
||||
import { useState, useRef } from 'react';
|
||||
import InitialStep from './steps/initial_step';
|
||||
import {InitialStep, ExtraStep, ResultStep} from './steps';
|
||||
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
|
||||
import styles from './step.less';
|
||||
|
||||
const { Step } = Steps;
|
||||
|
||||
|
@ -10,7 +12,7 @@ const steps = [
|
|||
title: '初始化',
|
||||
},
|
||||
{
|
||||
title: '连接',
|
||||
title: '信息确认',
|
||||
content: 'Second-content',
|
||||
},
|
||||
{
|
||||
|
@ -22,24 +24,100 @@ const steps = [
|
|||
const ClusterStep = ({
|
||||
current,
|
||||
changeStep,
|
||||
dispatch,
|
||||
history,
|
||||
}) => {
|
||||
const initalFormRef = useRef();
|
||||
const formRef = useRef();
|
||||
const [clusterConfig, setClusterConfig] = useState({})
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
// const [clusterInfo, setClusterInfo] = useState({});
|
||||
|
||||
const handleConnect = async ()=>{
|
||||
const result = await formRef.current.validateFields((errors, values) => {
|
||||
if(errors){
|
||||
return false;
|
||||
}
|
||||
return values;
|
||||
|
||||
}).catch((err)=>{
|
||||
return false;
|
||||
});
|
||||
|
||||
if(!result){
|
||||
return false
|
||||
}
|
||||
setIsLoading(true)
|
||||
const res = await dispatch({
|
||||
type: 'clusterConfig/doTryConnect',
|
||||
payload: {
|
||||
basic_auth:{
|
||||
username: result.username,
|
||||
password: result.password,
|
||||
},
|
||||
host: result.host,
|
||||
schema: result.isTLS === true ? 'https': 'http',
|
||||
},
|
||||
});
|
||||
if(res && !res.error){
|
||||
setClusterConfig({
|
||||
...result,
|
||||
...res,
|
||||
});
|
||||
return true;
|
||||
}else{
|
||||
setIsLoading(false)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const handleCommit = async ()=>{
|
||||
const result = await formRef.current.validateFields((errors, values) => {
|
||||
if(errors){
|
||||
return false;
|
||||
}
|
||||
// console.log(values);
|
||||
return values
|
||||
});
|
||||
if(!result){
|
||||
return fasle;
|
||||
}
|
||||
const newVals = {
|
||||
name: result.name,
|
||||
version: clusterConfig.version,
|
||||
host: clusterConfig.host,
|
||||
basic_auth: {
|
||||
username: clusterConfig.username || '',
|
||||
password: clusterConfig.password || '',
|
||||
},
|
||||
description: result.description,
|
||||
enabled: true,
|
||||
monitored: result.monitored,
|
||||
schema: clusterConfig.isTLS ? 'https': 'http'
|
||||
}
|
||||
setIsLoading(true);
|
||||
const res = await dispatch({
|
||||
type: 'clusterConfig/addCluster',
|
||||
payload: newVals,
|
||||
});
|
||||
if(res && !res.error){
|
||||
return true;
|
||||
}else{
|
||||
setIsLoading(false)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const next = async () => {
|
||||
let result
|
||||
if(current === 0){
|
||||
result = await initalFormRef.current.validateFields((errors, values) => {
|
||||
if(errors){
|
||||
return false;
|
||||
}
|
||||
console.log(values)
|
||||
}).catch((err)=>{
|
||||
return false;
|
||||
})
|
||||
result = await handleConnect();
|
||||
}else if(current === 1){
|
||||
result = await handleCommit();
|
||||
}
|
||||
if(!result){
|
||||
return
|
||||
}
|
||||
setIsLoading(false)
|
||||
changeStep(current + 1)
|
||||
};
|
||||
|
||||
|
@ -47,48 +125,97 @@ const ClusterStep = ({
|
|||
changeStep(current - 1)
|
||||
};
|
||||
|
||||
const oneMoreClick = ()=>{
|
||||
setClusterConfig({});
|
||||
changeStep(0);
|
||||
}
|
||||
|
||||
const goToClusterList = ()=>{
|
||||
history.push('/system/cluster');
|
||||
}
|
||||
|
||||
const renderContent = (current)=>{
|
||||
if(current===0){
|
||||
return <InitialStep ref={initalFormRef} />
|
||||
return <InitialStep ref={formRef} initialValue={clusterConfig} />
|
||||
}else if(current === 1){
|
||||
return <></>
|
||||
}else{
|
||||
return null
|
||||
return <ExtraStep initialValue={clusterConfig} ref={formRef}/>
|
||||
}else if(current === 2){
|
||||
return <ResultStep clusterConfig={clusterConfig} oneMoreClick={oneMoreClick}
|
||||
goToClusterList={goToClusterList}
|
||||
/>
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Steps current={current}>
|
||||
{steps.map(item => (
|
||||
<Step key={item.title} title={item.title} />
|
||||
))}
|
||||
</Steps>
|
||||
<div className="steps-content">{renderContent(current)}</div>
|
||||
<div className="steps-action" style={{textAlign:'center'}}>
|
||||
{current < steps.length - 1 && (
|
||||
<Button type="primary" onClick={() => next()}>
|
||||
下一步
|
||||
</Button>
|
||||
)}
|
||||
{current === steps.length - 1 && (
|
||||
<Button type="primary" onClick={() => message.success('Processing complete!')}>
|
||||
完成
|
||||
</Button>
|
||||
)}
|
||||
{current > 0 && (
|
||||
<Button style={{ margin: '0 8px' }} onClick={() => prev()}>
|
||||
上一步
|
||||
</Button>
|
||||
)}
|
||||
|
||||
const content = (
|
||||
<div className={styles.pageHeaderContent}>
|
||||
<p>
|
||||
输入集群地址和身份验证信息分步创建集群。
|
||||
</p>
|
||||
<div className={styles.contentLink}>
|
||||
<a>
|
||||
<img alt="" src="https://gw.alipayobjects.com/zos/rmsportal/MjEImQtenlyueSmVEfUD.svg" />{' '}
|
||||
快速开始
|
||||
</a>
|
||||
<a>
|
||||
<img alt="" src="https://gw.alipayobjects.com/zos/rmsportal/NbuDUAuBlIApFuDvWiND.svg" />{' '}
|
||||
产品简介
|
||||
</a>
|
||||
<a>
|
||||
<img alt="" src="https://gw.alipayobjects.com/zos/rmsportal/ohOEPSYdDTNnyMbGuyLb.svg" />{' '}
|
||||
产品文档
|
||||
</a>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
|
||||
const extraContent = (
|
||||
<div className={styles.extraImg}>
|
||||
<img
|
||||
alt="这是一个标题"
|
||||
src="https://gw.alipayobjects.com/zos/rmsportal/RzwpdLnhmvDJToTdfDPe.png"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
return (
|
||||
<PageHeaderWrapper title="集群注册" content={content} extraContent={extraContent}>
|
||||
<Card>
|
||||
<Spin spinning={isLoading}>
|
||||
<div style={{maxWidth:720, margin:'0 auto'}}>
|
||||
<Steps current={current} style={{marginBottom:24}}>
|
||||
{steps.map(item => (
|
||||
<Step key={item.title} title={item.title} />
|
||||
))}
|
||||
</Steps>
|
||||
<div className="steps-content">{renderContent(current)}</div>
|
||||
<div className="steps-action" style={{textAlign:'center'}}>
|
||||
{current === 1 && (
|
||||
<Button style={{ margin: '0 8px' }} onClick={() => prev()}>
|
||||
上一步
|
||||
</Button>
|
||||
)}
|
||||
{current < steps.length - 1 && (
|
||||
<Button type="primary" onClick={() => next()}>
|
||||
下一步
|
||||
</Button>
|
||||
)}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</Spin>
|
||||
</Card>
|
||||
</PageHeaderWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
const NewCluster = ()=>{
|
||||
const NewCluster = (props)=>{
|
||||
const {dispatch, history} = props;
|
||||
const [current, setCurrent] = useState(0);
|
||||
return <ClusterStep current={current} changeStep={setCurrent} />
|
||||
return <ClusterStep current={current} changeStep={setCurrent}
|
||||
history={history}
|
||||
dispatch={dispatch} />
|
||||
}
|
||||
|
||||
export default connect(({
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import {createClusterConfig, searchClusterConfig, updateClusterConfig,deleteClusterConfig, getClusterStatus} from "@/services/cluster";
|
||||
import {createClusterConfig, searchClusterConfig, updateClusterConfig,deleteClusterConfig,
|
||||
getClusterStatus, tryConnect} from "@/services/cluster";
|
||||
import {message} from "antd";
|
||||
import {formatESSearchResult} from '@/lib/elasticsearch/util';
|
||||
|
||||
|
@ -45,6 +46,9 @@ export default {
|
|||
return false;
|
||||
}
|
||||
let {data, total} = yield select(state => state.clusterConfig);
|
||||
if(!data){
|
||||
return
|
||||
}
|
||||
data.unshift({
|
||||
...res._source,
|
||||
id: res._id,
|
||||
|
@ -147,6 +151,21 @@ export default {
|
|||
}
|
||||
})
|
||||
return res;
|
||||
},
|
||||
*doTryConnect({payload}, {call, put, select}) {
|
||||
let res = yield call(tryConnect, payload)
|
||||
if(res.error){
|
||||
message.error(res.error)
|
||||
return false;
|
||||
}
|
||||
|
||||
yield put({
|
||||
type: 'saveData',
|
||||
payload: {
|
||||
tempClusterInfo: res,
|
||||
}
|
||||
})
|
||||
return res;
|
||||
}
|
||||
},
|
||||
reducers:{
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
.extraImg {
|
||||
margin-top: -60px;
|
||||
text-align: center;
|
||||
width: 195px;
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.pageHeaderContent {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.contentLink {
|
||||
margin-top: 16px;
|
||||
a {
|
||||
margin-right: 32px;
|
||||
img {
|
||||
width: 24px;
|
||||
}
|
||||
}
|
||||
img {
|
||||
vertical-align: middle;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
import {Form, Input, Switch, Icon, InputNumber, Divider, Descriptions} from 'antd';
|
||||
|
||||
@Form.create()
|
||||
export class ExtraStep extends React.Component {
|
||||
state = {
|
||||
}
|
||||
render(){
|
||||
const {form:{getFieldDecorator}, initialValue} = this.props;
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<Descriptions column={2} size="small" bordered>
|
||||
<Descriptions.Item label="集群版本" >
|
||||
{initialValue?.version}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="健康状态" >
|
||||
{initialValue?.status}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="节点数" >
|
||||
{initialValue?.number_of_nodes}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="数据节点数" >
|
||||
{initialValue?.number_of_data_nodes}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="分片数" >
|
||||
{initialValue?.active_shards}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
<Divider/>
|
||||
<Form {...formItemLayout} style={{marginTop:15}} form={this.props.formRef}>
|
||||
<Form.Item label="集群名称" >
|
||||
{getFieldDecorator('name', {
|
||||
initialValue: initialValue?.cluster_name || '',
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input cluster name!',
|
||||
},
|
||||
],
|
||||
})(<Input autoComplete='off' placeholder="cluster-name" />)}
|
||||
</Form.Item>
|
||||
{/* <Form.Item label="Elasticsearch 版本">
|
||||
{getFieldDecorator('version', {
|
||||
initialValue: initialValue?.version || '',
|
||||
})(<Input readOnly={true} />)}
|
||||
</Form.Item> */}
|
||||
{/* <Form.Item label="排序权重">
|
||||
{getFieldDecorator('order', {
|
||||
initialValue: 0,
|
||||
})(<InputNumber />)}
|
||||
</Form.Item> */}
|
||||
<Form.Item label="描述">
|
||||
{getFieldDecorator('description', {
|
||||
initialValue: '',
|
||||
})(<Input.TextArea placeholder="集群应用描述" />)}
|
||||
</Form.Item>
|
||||
{/* <Form.Item label="是否启用">
|
||||
{getFieldDecorator('enabled', {
|
||||
valuePropName: 'checked',
|
||||
initialValue: true,
|
||||
})(<Switch
|
||||
checkedChildren={<Icon type="check" />}
|
||||
unCheckedChildren={<Icon type="close" />}
|
||||
/>)}
|
||||
</Form.Item> */}
|
||||
<Form.Item label="启用监控">
|
||||
{getFieldDecorator('monitored', {
|
||||
valuePropName: 'checked',
|
||||
initialValue: true,
|
||||
})(<Switch
|
||||
checkedChildren={<Icon type="check" />}
|
||||
unCheckedChildren={<Icon type="close" />}
|
||||
/>)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export * from './initial_step';
|
||||
export * from './extra_step';
|
||||
export * from './result_step';
|
|
@ -1,10 +1,12 @@
|
|||
import {Form, Input, Switch, Icon} from 'antd';
|
||||
import {useState} from 'react';
|
||||
|
||||
@Form.create()
|
||||
class InitialStep extends React.Component {
|
||||
state = {
|
||||
needAuth: false,
|
||||
export class InitialStep extends React.Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state = {
|
||||
needAuth: props.initialValue?.username !== undefined,
|
||||
}
|
||||
}
|
||||
handleAuthChange = (val) => {
|
||||
this.setState({
|
||||
|
@ -12,7 +14,7 @@ class InitialStep extends React.Component {
|
|||
})
|
||||
}
|
||||
render(){
|
||||
const {form:{getFieldDecorator}} = this.props;
|
||||
const {form:{getFieldDecorator}, initialValue} = this.props;
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
|
@ -24,34 +26,33 @@ class InitialStep extends React.Component {
|
|||
},
|
||||
};
|
||||
return (
|
||||
<Form {...formItemLayout} style={{marginTop:15}} form={this.props.formRef}>
|
||||
<Form.Item label="集群名称" >
|
||||
{getFieldDecorator('name', {
|
||||
initialValue: '',
|
||||
<Form {...formItemLayout} form={this.props.formRef}>
|
||||
<Form.Item label="集群地址">
|
||||
{getFieldDecorator('host', {
|
||||
initialValue: initialValue?.host || '',
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input cluster name!',
|
||||
},
|
||||
],
|
||||
})(<Input autoComplete='off' placeholder="cluster-name" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="集群 URL">
|
||||
{getFieldDecorator('endpoint', {
|
||||
initialValue: '',
|
||||
rules: [
|
||||
{
|
||||
type: 'url',
|
||||
message: 'The input is not valid url!',
|
||||
type: 'string',
|
||||
pattern: /^[\w\.]+\:\d+$/, //(https?:\/\/)?
|
||||
message: '请输入域名或 IP 地址和端口号',
|
||||
},
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input cluster endpoint!',
|
||||
message: '请输入集群地址!',
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="http://127.0.0.1:9200" />)}
|
||||
})(<Input placeholder="127.0.0.1:9200" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="是否需要身份验证">
|
||||
<Form.Item label="TLS">
|
||||
{getFieldDecorator('isTLS', {
|
||||
initialValue: initialValue?.isTLS || false,
|
||||
})(
|
||||
<Switch
|
||||
checkedChildren={<Icon type="check" />}
|
||||
unCheckedChildren={<Icon type="close" />}
|
||||
/>)}
|
||||
</Form.Item>
|
||||
<Form.Item label="身份验证">
|
||||
<Switch
|
||||
defaultChecked={this.state.needAuth}
|
||||
onChange={this.handleAuthChange}
|
||||
|
@ -62,7 +63,7 @@ class InitialStep extends React.Component {
|
|||
{this.state.needAuth === true ? (<div>
|
||||
<Form.Item label="用户名">
|
||||
{getFieldDecorator('username', {
|
||||
initialValue: '',
|
||||
initialValue: initialValue?.username || '',
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
|
@ -73,7 +74,7 @@ class InitialStep extends React.Component {
|
|||
</Form.Item>
|
||||
<Form.Item label="密码" hasFeedback>
|
||||
{getFieldDecorator('password', {
|
||||
initialValue: '',
|
||||
initialValue: initialValue?.password || '',
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
|
@ -86,6 +87,4 @@ class InitialStep extends React.Component {
|
|||
</Form>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default InitialStep;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
import Result from '@/components/Result';
|
||||
import React, { Fragment } from 'react';
|
||||
import { Button, Row, Col } from 'antd';
|
||||
import styles from './styles.less';
|
||||
|
||||
export const ResultStep = (props)=>{
|
||||
const {clusterConfig, oneMoreClick, goToClusterList} = props;
|
||||
const information = (
|
||||
<div className={styles.information}>
|
||||
<Row>
|
||||
<Col xs={24} sm={8} className={styles.label}>
|
||||
集群名称:
|
||||
</Col>
|
||||
<Col xs={24} sm={16}>
|
||||
{clusterConfig?.cluster_name}
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xs={24} sm={8} className={styles.label}>
|
||||
集群版本:
|
||||
</Col>
|
||||
<Col xs={24} sm={16}>
|
||||
{clusterConfig?.version}
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xs={24} sm={8} className={styles.label}>
|
||||
集群地址:
|
||||
</Col>
|
||||
<Col xs={24} sm={16}>
|
||||
{clusterConfig?.host}
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xs={24} sm={8} className={styles.label}>
|
||||
TLS:
|
||||
</Col>
|
||||
<Col xs={24} sm={16}>
|
||||
{clusterConfig?.isTLS ? '是': '否'}
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
const actions = (
|
||||
<Fragment>
|
||||
<Button type="primary" onClick={oneMoreClick}>
|
||||
再创建一个集群
|
||||
</Button>
|
||||
<Button onClick={goToClusterList}>查看集群列表</Button>
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
return (
|
||||
<Result
|
||||
type="success"
|
||||
title="创建成功"
|
||||
description=""
|
||||
extra={information}
|
||||
actions={actions}
|
||||
className={styles.result}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
@import '~antd/lib/style/themes/default.less';
|
||||
.result {
|
||||
margin: 0 auto;
|
||||
max-width: 560px;
|
||||
padding: 24px 0 8px;
|
||||
}
|
||||
|
||||
.desc {
|
||||
padding: 0 56px;
|
||||
// color: @text-color-secondary;
|
||||
h3 {
|
||||
font-size: 16px;
|
||||
margin: 0 0 12px 0;
|
||||
// color: @text-color-secondary;
|
||||
line-height: 32px;
|
||||
}
|
||||
h4 {
|
||||
margin: 0 0 4px 0;
|
||||
// color: @text-color-secondary;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 12px;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: @screen-md) {
|
||||
.desc {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.information {
|
||||
line-height: 22px;
|
||||
:global {
|
||||
.ant-row:not(:last-child) {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
.label {
|
||||
// color: @heading-color;
|
||||
text-align: right;
|
||||
padding-right: 8px;
|
||||
@media screen and (max-width: @screen-sm) {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.money {
|
||||
font-family: 'Helvetica Neue', sans-serif;
|
||||
font-weight: 500;
|
||||
font-size: 20px;
|
||||
line-height: 14px;
|
||||
}
|
||||
|
||||
.uppercase {
|
||||
font-size: 12px;
|
||||
}
|
|
@ -16,7 +16,7 @@ export async function getClusterMetrics(params) {
|
|||
}
|
||||
|
||||
export async function createClusterConfig(params) {
|
||||
return request(`/elasticsearch`, {
|
||||
return request(`/elasticsearch/`, {
|
||||
method: 'POST',
|
||||
body: params,
|
||||
});
|
||||
|
@ -57,4 +57,12 @@ export async function getClusterStatus(params) {
|
|||
return request(url, {
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
||||
|
||||
export async function tryConnect(params) {
|
||||
let url = `/elasticsearch/try_connect`;
|
||||
return request(url, {
|
||||
method: 'POST',
|
||||
body: params,
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue