feat: Service details page API docking
This commit is contained in:
parent
148c12972b
commit
2f4616aaa5
@ -0,0 +1,131 @@
|
||||
import React from 'react';
|
||||
import {Dialog, Form, Input, Switch, Select} from '@alifd/next';
|
||||
import {I18N, DIALOG_FORM_LAYOUT} from './constant'
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const Option = Select.Option
|
||||
|
||||
/*****************************此行为标记行, 请勿删和修改此行, 文件和组件依赖请写在此行上面, 主体代码请写在此行下面的class中*****************************/
|
||||
class EditClusterDialog extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
editCluster: {},
|
||||
editClusterDialogVisible: false
|
||||
}
|
||||
this.show = this.show.bind(this)
|
||||
}
|
||||
|
||||
show(editCluster) {
|
||||
const {metadata = {}} = editCluster
|
||||
editCluster.metadataText = Object.keys(metadata).map(k => `${k}=${metadata[k]}`).join(',')
|
||||
this.setState({
|
||||
editCluster,
|
||||
editClusterDialogVisible: true
|
||||
}, () => console.log(this.state.editCluster))
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.setState({editClusterDialogVisible: false})
|
||||
}
|
||||
|
||||
onConfirm() {
|
||||
console.log('confirm', this.props, this.state)
|
||||
}
|
||||
|
||||
onChangeCluster(changeVal) {
|
||||
const {editCluster = {}} = this.state
|
||||
this.setState({
|
||||
editCluster: Object.assign({}, editCluster, changeVal)
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const {editCluster = {}, editClusterDialogVisible} = this.state
|
||||
const {
|
||||
healthChecker = {},
|
||||
useIPPort4Check,
|
||||
defaultCheckPort = '80',
|
||||
metadataText = ''
|
||||
} = editCluster
|
||||
const {type, path, headers} = healthChecker
|
||||
const healthCheckerChange = changeVal => this.onChangeCluster({
|
||||
healthChecker: Object.assign({}, healthChecker, changeVal)
|
||||
})
|
||||
return (
|
||||
<Dialog
|
||||
className="cluster-edit-dialog"
|
||||
title={I18N.UPDATE_CLUSTER}
|
||||
visible={editClusterDialogVisible}
|
||||
onOk={() => this.onConfirm()}
|
||||
onCancel={() => this.hide()}
|
||||
onClose={() => this.hide()}
|
||||
>
|
||||
<Form {...DIALOG_FORM_LAYOUT}>
|
||||
<FormItem label={`${I18N.CHECK_TYPE}:`}>
|
||||
<Select
|
||||
className="in-select"
|
||||
defaultValue={type}
|
||||
onChange={type => healthCheckerChange({type})}
|
||||
>
|
||||
<Option value="TCP">TCP</Option>
|
||||
<Option value="HTTP">HTTP</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.CHECK_PORT}:`}>
|
||||
<Input className="in-text"
|
||||
value={defaultCheckPort}
|
||||
onChange={defaultCheckPort => this.onChangeCluster({defaultCheckPort})}
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.USE_IP_PORT_CHECK}:`}>
|
||||
<Switch
|
||||
checked={useIPPort4Check}
|
||||
onChange={useIPPort4Check => this.onChangeCluster({useIPPort4Check})}
|
||||
/>
|
||||
</FormItem>
|
||||
{
|
||||
type === 'HTTP'
|
||||
? (<div>
|
||||
<div className="next-row next-form-item next-left next-medium">
|
||||
<div className="next-col next-col-fixed-12 next-form-item-label">
|
||||
<label>{`${I18N.CHECK_PATH}:`}</label>
|
||||
</div>
|
||||
<div className="next-col next-col-12 next-form-item-control">
|
||||
<Input
|
||||
className="in-text"
|
||||
value={path}
|
||||
onChange={path => healthCheckerChange({path})}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="next-row next-form-item next-left next-medium">
|
||||
<div className="next-col next-col-fixed-12 next-form-item-label">
|
||||
<label>{`${I18N.CHECK_HEADERS}:`}</label>
|
||||
</div>
|
||||
<div className="next-col next-col-12 next-form-item-control">
|
||||
<Input
|
||||
className="in-text"
|
||||
value={headers}
|
||||
onChange={headers => healthCheckerChange({headers})}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>)
|
||||
: null
|
||||
}
|
||||
<FormItem label={`${I18N.METADATA}:`}>
|
||||
<Input
|
||||
className="in-text"
|
||||
value={metadataText}
|
||||
onChange={metadataText => this.onChangeCluster({metadataText})}
|
||||
/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************此行为标记行, 请勿删和修改此行, 主体代码请写在此行上面的class中, 组件导出语句及其他信息请写在此行下面*****************************/
|
||||
export default EditClusterDialog;
|
@ -0,0 +1,83 @@
|
||||
import React from 'react';
|
||||
import {Dialog, Form, Input, Switch} from '@alifd/next';
|
||||
import {I18N, DIALOG_FORM_LAYOUT} from './constant'
|
||||
|
||||
const FormItem = Form.Item;
|
||||
|
||||
/*****************************此行为标记行, 请勿删和修改此行, 文件和组件依赖请写在此行上面, 主体代码请写在此行下面的class中*****************************/
|
||||
class EditInstanceDialog extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
editInstance: {},
|
||||
editInstanceDialogVisible: false
|
||||
}
|
||||
this.show = this.show.bind(this)
|
||||
}
|
||||
|
||||
show(editInstance) {
|
||||
const {metadata = {}} = editInstance
|
||||
if (!Object.keys(metadata).length) {
|
||||
editInstance.metadataText = Object.keys(metadata).map(k => `${k}=${metadata[k]}`).join(',')
|
||||
}
|
||||
this.setState({editInstance, editInstanceDialogVisible: true})
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.setState({editInstanceDialogVisible: false})
|
||||
}
|
||||
|
||||
onConfirm() {
|
||||
console.log('confirm', this.props, this.state)
|
||||
}
|
||||
|
||||
onChangeCluster(changeVal) {
|
||||
const {editInstance = {}} = this.state
|
||||
this.setState({
|
||||
editInstance: Object.assign({}, editInstance, changeVal)
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const {editInstanceDialogVisible, editInstance} = this.state
|
||||
return (
|
||||
<Dialog
|
||||
className="instance-edit-dialog"
|
||||
title={I18N.UPDATE_INSTANCE}
|
||||
visible={editInstanceDialogVisible}
|
||||
onOk={() => this.onConfirm()}
|
||||
onCancel={() => this.hide()}
|
||||
onClose={() => this.hide()}
|
||||
>
|
||||
<Form {...DIALOG_FORM_LAYOUT}>
|
||||
<FormItem label="IP:">
|
||||
<p>1.1.1.1</p>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.PORT}:`}>
|
||||
<p>8080</p>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.WEIGHT}:`}>
|
||||
<Input
|
||||
className="in-text"
|
||||
value={editInstance.healthy}
|
||||
onChange={healthy => this.onChangeCluster({healthy})}
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.WHETHER_ONLINE}:`}>
|
||||
<Switch onChange={f => f}/>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.METADATA}:`}>
|
||||
<Input
|
||||
className="in-text"
|
||||
value={editInstance.metadataText}
|
||||
onChange={metadataText => this.onChangeCluster({metadataText})}
|
||||
/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************此行为标记行, 请勿删和修改此行, 主体代码请写在此行上面的class中, 组件导出语句及其他信息请写在此行下面*****************************/
|
||||
export default EditInstanceDialog;
|
@ -0,0 +1,97 @@
|
||||
import React from 'react';
|
||||
import {Dialog, Form, Input, Select} from '@alifd/next';
|
||||
import {I18N, DIALOG_FORM_LAYOUT} from './constant'
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const Option = Select.Option
|
||||
|
||||
/*****************************此行为标记行, 请勿删和修改此行, 文件和组件依赖请写在此行上面, 主体代码请写在此行下面的class中*****************************/
|
||||
class EditServiceDialog extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
editService: {},
|
||||
editServiceDialogVisible: false
|
||||
}
|
||||
this.show = this.show.bind(this)
|
||||
}
|
||||
|
||||
show(editService) {
|
||||
const {metadata = {}} = editService
|
||||
if (Object.keys(metadata).length) {
|
||||
editService.metadataText = Object.keys(metadata).map(k => `${k}=${metadata[k]}`).join(',')
|
||||
}
|
||||
this.setState({editService, editServiceDialogVisible: true})
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.setState({editServiceDialogVisible: false})
|
||||
}
|
||||
|
||||
onConfirm() {
|
||||
const editService = Object.assign({}, this.state)
|
||||
console.log('confirm', editService)
|
||||
this.hide()
|
||||
}
|
||||
|
||||
onChangeCluster(changeVal) {
|
||||
const {editService = {}} = this.state
|
||||
this.setState({
|
||||
editService: Object.assign({}, editService, changeVal)
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const {editService, editServiceDialogVisible} = this.state
|
||||
const {
|
||||
name,
|
||||
protectThreshold,
|
||||
healthCheckMode,
|
||||
metadataText
|
||||
} = editService
|
||||
return (
|
||||
<Dialog
|
||||
className="service-detail-edit-dialog"
|
||||
title={I18N.UPDATE_SERVICE}
|
||||
visible={editServiceDialogVisible}
|
||||
onOk={() => this.onConfirm()}
|
||||
onCancel={() => this.hide()}
|
||||
onClose={() => this.hide()}
|
||||
>
|
||||
<Form {...DIALOG_FORM_LAYOUT}>
|
||||
<FormItem label={`${I18N.SERVICE_NAME}:`}>
|
||||
<p>{name}</p>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.PROTECT_THRESHOLD}:`}>
|
||||
<Input
|
||||
className="in-text"
|
||||
value={protectThreshold}
|
||||
onChange={protectThreshold => this.onChangeCluster({protectThreshold})}
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.HEALTH_CHECK_PATTERN}:`}>
|
||||
<Select
|
||||
className="in-select"
|
||||
defaultValue={healthCheckMode}
|
||||
onChange={healthCheckMode => this.onChangeCluster({healthCheckMode})}
|
||||
>
|
||||
<Option value="server">{I18N.HEALTH_CHECK_PATTERN_SERVICE}</Option>
|
||||
<Option value="client">{I18N.HEALTH_CHECK_PATTERN_CLIENT}</Option>
|
||||
<Option value="forbidden">{I18N.HEALTH_CHECK_PATTERN_FORBIDDEN}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.METADATA}:`}>
|
||||
<Input
|
||||
className="in-text"
|
||||
value={metadataText}
|
||||
onChange={metadataText => this.onChangeCluster({metadataText})}
|
||||
/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************此行为标记行, 请勿删和修改此行, 主体代码请写在此行上面的class中, 组件导出语句及其他信息请写在此行下面*****************************/
|
||||
export default EditServiceDialog;
|
@ -0,0 +1,93 @@
|
||||
import React from 'react';
|
||||
import {Button, Pagination, Table} from '@alifd/next';
|
||||
import {I18N} from './constant'
|
||||
import EditInstanceDialog from "./EditInstanceDialog";
|
||||
|
||||
|
||||
/*****************************此行为标记行, 请勿删和修改此行, 文件和组件依赖请写在此行上面, 主体代码请写在此行下面的class中*****************************/
|
||||
class InstanceTable extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
loading: false,
|
||||
instance: {count: 0, list: []},
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getInstanceList()
|
||||
}
|
||||
|
||||
getInstanceList() {
|
||||
const {clusterName, serviceName} = this.props
|
||||
if (!clusterName) return
|
||||
const {pageSize, pageNum} = this.state
|
||||
window.request({
|
||||
url: '/nacos/v1/ns/catalog/instanceList',
|
||||
data: {
|
||||
serviceName,
|
||||
clusterName,
|
||||
pgSize: pageSize,
|
||||
startPg: pageNum
|
||||
},
|
||||
beforeSend: () => this.setState({loading: true}),
|
||||
success: res => this.setState({instance: res}),
|
||||
complete: () => this.setState({loading: false})
|
||||
})
|
||||
}
|
||||
|
||||
openInstanceDialog(instance) {
|
||||
this.refs.editInstanceDialog.show(instance)
|
||||
}
|
||||
|
||||
switchState() {
|
||||
}
|
||||
|
||||
render() {
|
||||
const {clusterName} = this.props
|
||||
const {instance = {}, pageSize, loading} = this.state
|
||||
return instance.count ? (
|
||||
<div>
|
||||
<Table dataSource={instance.list} loading={loading}>
|
||||
<Table.Column title="IP" dataIndex="ip"/>
|
||||
<Table.Column title={I18N.PORT} dataIndex="port"/>
|
||||
<Table.Column title={I18N.WEIGHT} dataIndex="weight"/>
|
||||
<Table.Column title={I18N.HEALTHY} dataIndex="healthy"/>
|
||||
<Table.Column title={I18N.METADATA} dataIndex="metadata"/>
|
||||
<Table.Column
|
||||
title={I18N.OPERATION}
|
||||
width={150}
|
||||
cell={(value, index, record) => (
|
||||
<div>
|
||||
<Button
|
||||
type="normal"
|
||||
className="edit-btn"
|
||||
onClick={() => this.openInstanceDialog(record)}
|
||||
>{I18N.EDITOR}</Button>
|
||||
<Button
|
||||
type={record.online ? 'normal' : 'secondary'}
|
||||
onClick={() => this.switchState(index, record)}
|
||||
>{I18N[record.online ? 'OFFLINE' : 'ONLINE']}</Button>
|
||||
</div>
|
||||
)}/>
|
||||
</Table>
|
||||
{
|
||||
instance.count > pageSize
|
||||
? (
|
||||
<Pagination
|
||||
className="pagination"
|
||||
onChange={currentPage => this.onChange(clusterName, currentPage)}
|
||||
/>
|
||||
)
|
||||
: null
|
||||
}
|
||||
<EditInstanceDialog ref="editInstanceDialog"/>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************此行为标记行, 请勿删和修改此行, 主体代码请写在此行上面的class中, 组件导出语句及其他信息请写在此行下面*****************************/
|
||||
export default InstanceTable;
|
@ -1,47 +1,50 @@
|
||||
import React from 'react';
|
||||
import {Button, Card, Dialog, Table, Form, Pagination, Loading, Input, Switch, Select} from '@alifd/next';
|
||||
import {Button, Card, Form, Loading} from '@alifd/next';
|
||||
import EditServiceDialog from './EditServiceDialog'
|
||||
import EditClusterDialog from './EditClusterDialog'
|
||||
import InstanceTable from './InstanceTable'
|
||||
import queryString from 'query-string'
|
||||
import {I18N} from './constant'
|
||||
import './ServiceDetail.less'
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const Option = Select.Option
|
||||
|
||||
const dataSource = () => {
|
||||
const result = [];
|
||||
for (let i = 0; i < 8; i++) {
|
||||
result.push({ip: '1.1.1.1', port: '80', weight: '50', healthy: 'true', metadata: 'k1=v1', online: true});
|
||||
}
|
||||
return result;
|
||||
const pageFormLayout = {
|
||||
labelCol: {fixedSpan: 10},
|
||||
wrapperCol: {span: 14}
|
||||
};
|
||||
|
||||
const dialogFormLayout = {
|
||||
labelCol: {fixedSpan: 12},
|
||||
wrapperCol: {span: 12}
|
||||
}
|
||||
|
||||
/*****************************此行为标记行, 请勿删和修改此行, 文件和组件依赖请写在此行上面, 主体代码请写在此行下面的class中*****************************/
|
||||
class ServiceDetail extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
serviceName: queryString.parse(props.location.search).name,
|
||||
loading: false,
|
||||
tableLoading: false,
|
||||
currentPage: 1,
|
||||
instanceList: [],
|
||||
editServiceDialogVisible: false,
|
||||
editClusterDialogVisible: false,
|
||||
editInstanceDialogVisible: false,
|
||||
checkType: 'tcp'
|
||||
clusters: [],
|
||||
instances: {},
|
||||
service: {},
|
||||
pageSize: 10,
|
||||
pageNum: {}
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
setTimeout(() => this.setState({loading: true}, () => {
|
||||
this.setState({
|
||||
instanceList: dataSource(),
|
||||
loading: false
|
||||
})
|
||||
}), 300)
|
||||
if (!this.state.serviceName) {
|
||||
this.props.history.goBack()
|
||||
return
|
||||
}
|
||||
this.getServiceDetail()
|
||||
}
|
||||
|
||||
getServiceDetail() {
|
||||
const {serviceName} = this.state
|
||||
window.request({
|
||||
url: `/nacos/v1/ns/catalog/serviceDetail?serviceName=${serviceName}`,
|
||||
beforeSend: () => this.openLoading(),
|
||||
success: ({clusters = [], service = {}}) => this.setState({service, clusters}),
|
||||
complete: () => this.closeLoading()
|
||||
})
|
||||
}
|
||||
|
||||
openLoading() {
|
||||
@ -52,162 +55,26 @@ class ServiceDetail extends React.Component {
|
||||
this.setState({loading: false})
|
||||
}
|
||||
|
||||
editServiceDialog() {
|
||||
const hideDialog = () => this.setState({editServiceDialogVisible: false})
|
||||
const {editServiceDialogVisible} = this.state
|
||||
return (
|
||||
<Dialog
|
||||
className="service-detail-edit-dialog"
|
||||
title={I18N.UPDATE_SERVICE}
|
||||
visible={editServiceDialogVisible}
|
||||
onOk={hideDialog}
|
||||
onCancel={hideDialog}
|
||||
onClose={hideDialog}
|
||||
>
|
||||
<Form {...dialogFormLayout}>
|
||||
<FormItem label={`${I18N.SERVICE_NAME}:`}>
|
||||
<p>test.com</p>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.PROTECT_THRESHOLD}:`}>
|
||||
<Input className="in-text" value="0.5"/>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.HEALTH_CHECK_PATTERN}:`}>
|
||||
<Select defaultValue="service" className="in-select">
|
||||
<Option value="service">{I18N.HEALTH_CHECK_PATTERN_SERVICE}</Option>
|
||||
<Option value="client">{I18N.HEALTH_CHECK_PATTERN_CLIENT}</Option>
|
||||
<Option value="forbidden">{I18N.HEALTH_CHECK_PATTERN_FORBIDDEN}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.METADATA}:`}>
|
||||
<Input className="in-text" value="k1=v1,k2=v2"/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Dialog>
|
||||
)
|
||||
openEditServiceDialog() {
|
||||
this.refs.editServiceDialog.show(this.state.service)
|
||||
}
|
||||
|
||||
editClusterDialog() {
|
||||
const hideDialog = () => this.setState({editClusterDialogVisible: false})
|
||||
const {editClusterDialogVisible} = this.state
|
||||
return (
|
||||
<Dialog
|
||||
className="cluster-edit-dialog"
|
||||
title={I18N.UPDATE_CLUSTER}
|
||||
visible={editClusterDialogVisible}
|
||||
onOk={hideDialog}
|
||||
onCancel={hideDialog}
|
||||
onClose={hideDialog}
|
||||
>
|
||||
<Form {...dialogFormLayout}>
|
||||
<FormItem label={`${I18N.CHECK_TYPE}:`}>
|
||||
<Select
|
||||
className="in-select"
|
||||
defaultValue={this.state.checkType}
|
||||
onChange={checkType => this.setState({checkType})}
|
||||
>
|
||||
<Select.Option value="tcp">TCP</Select.Option>
|
||||
<Select.Option value="http">HTTP</Select.Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.CHECK_PORT}:`}>
|
||||
<Input className="in-text" value="80"/>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.USE_IP_PORT_CHECK}:`}>
|
||||
<Switch onChange={f => f}/>
|
||||
</FormItem>
|
||||
{
|
||||
this.state.checkType === 'http'
|
||||
? (
|
||||
<Form {...dialogFormLayout}>
|
||||
<FormItem label={`${I18N.CHECK_PATH}:`}>
|
||||
<Input className="in-text"/>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.CHECK_HEADERS}:`}>
|
||||
<Input className="in-text"/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
)
|
||||
: null
|
||||
}
|
||||
<FormItem label={`${I18N.METADATA}:`}>
|
||||
<Input className="in-text" value="k1=v1,k2=v2"/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Dialog>
|
||||
)
|
||||
openClusterDialog(cluster) {
|
||||
this.refs.editClusterDialog.show(cluster)
|
||||
}
|
||||
|
||||
editInstanceDialog() {
|
||||
const hideDialog = () => this.setState({editInstanceDialogVisible: false})
|
||||
const {editInstanceDialogVisible} = this.state
|
||||
return (
|
||||
<Dialog
|
||||
className="instance-edit-dialog"
|
||||
title={I18N.UPDATE_INSTANCE}
|
||||
visible={editInstanceDialogVisible}
|
||||
onOk={hideDialog}
|
||||
onCancel={hideDialog}
|
||||
onClose={hideDialog}
|
||||
>
|
||||
<Form {...dialogFormLayout}>
|
||||
<FormItem label="IP:">
|
||||
<p>1.1.1.1</p>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.PORT}:`}>
|
||||
<p>8080</p>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.WEIGHT}:`}>
|
||||
<Input className="in-text" value="0.5"/>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.WHETHER_ONLINE}:`}>
|
||||
<Switch onChange={f => f}/>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.METADATA}:`}>
|
||||
<Input className="in-text" value="k1=v1,k2=v2"/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
switchState(index, record) {
|
||||
const {instanceList} = this.state
|
||||
this.setState({tableLoading: true}, () => {
|
||||
setTimeout(() => {
|
||||
instanceList[index].online = !record.online
|
||||
this.setState({
|
||||
instanceList,
|
||||
tableLoading: false
|
||||
})
|
||||
}, 300)
|
||||
})
|
||||
}
|
||||
|
||||
onChange(currentPage) {
|
||||
this.setState({tableLoading: true})
|
||||
setTimeout(() => {
|
||||
this.setState({tableLoading: false, currentPage})
|
||||
}, 200)
|
||||
}
|
||||
|
||||
openEditServiceDialog = () => this.setState({editServiceDialogVisible: true})
|
||||
openClusterDialog = () => this.setState({editClusterDialogVisible: true})
|
||||
openInstanceDialog = () => this.setState({editInstanceDialogVisible: true})
|
||||
|
||||
render() {
|
||||
const {loading, tableLoading, instanceList} = this.state
|
||||
const formItemLayout = {
|
||||
labelCol: {fixedSpan: 10},
|
||||
wrapperCol: {span: 14}
|
||||
};
|
||||
const {serviceName, loading, service = {}, clusters} = this.state
|
||||
const {metadata = {}} = service
|
||||
const metadataText = Object.keys(metadata).map(key => `${key}=${metadata[key]}`).join(',')
|
||||
return (
|
||||
<div className="main-container service-detail">
|
||||
<Loading
|
||||
shape={"flower"}
|
||||
tip={"Loading..."}
|
||||
className="loading"
|
||||
visible={loading} color={"#333"}
|
||||
visible={loading}
|
||||
color={"#333"}
|
||||
>
|
||||
<h1 style={{
|
||||
position: 'relative',
|
||||
@ -217,67 +84,49 @@ class ServiceDetail extends React.Component {
|
||||
<Button
|
||||
type="normal"
|
||||
className="edit-service-btn"
|
||||
onClick={this.openEditServiceDialog}
|
||||
onClick={() => this.openEditServiceDialog()}
|
||||
>{I18N.EDIT_SERVICE}</Button>
|
||||
</h1>
|
||||
|
||||
<Form style={{width: '60%'}} {...formItemLayout}>
|
||||
<Form style={{width: '60%'}} {...pageFormLayout}>
|
||||
<FormItem label={`${I18N.SERVICE_NAME}:`}>
|
||||
<p>test.com</p>
|
||||
<p>{service.name}</p>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.PROTECT_THRESHOLD}:`}>
|
||||
<p>0.5</p>
|
||||
<p>{service.protectThreshold}</p>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.HEALTH_CHECK_PATTERN}:`}>
|
||||
<p>true</p>
|
||||
<p>{service.healthCheckMode}</p>
|
||||
</FormItem>
|
||||
<FormItem label={`${I18N.METADATA}:`}>
|
||||
<p>k1=v1,k2=v2</p>
|
||||
<p>{metadataText}</p>
|
||||
</FormItem>
|
||||
</Form>
|
||||
|
||||
<Card
|
||||
title={`${I18N.CLUSTER}:`}
|
||||
subTitle="DEFAULT"
|
||||
contentHeight="auto"
|
||||
extra={<Button type="normal" onClick={this.openClusterDialog}>{I18N.EDIT_CLUSTER}</Button>}
|
||||
>
|
||||
<Loading
|
||||
shape={"flower"}
|
||||
tip={"Loading..."}
|
||||
className="loading"
|
||||
visible={tableLoading} color={"#333"}
|
||||
>
|
||||
<Table dataSource={instanceList}>
|
||||
<Table.Column title="IP" dataIndex="ip"/>
|
||||
<Table.Column title={I18N.PORT} dataIndex="port"/>
|
||||
<Table.Column title={I18N.WEIGHT} dataIndex="weight"/>
|
||||
<Table.Column title={I18N.HEALTHY} dataIndex="healthy"/>
|
||||
<Table.Column title={I18N.METADATA} dataIndex="metadata"/>
|
||||
<Table.Column title={I18N.OPERATION} width={150} cell={(value, index, record) => (
|
||||
<div>
|
||||
<Button
|
||||
type="normal"
|
||||
className="edit-btn"
|
||||
onClick={this.openInstanceDialog}
|
||||
>{I18N.EDITOR}</Button>
|
||||
<Button
|
||||
type={record.online ? 'normal' : 'secondary'}
|
||||
onClick={() => this.switchState(index, record)}
|
||||
>{I18N[record.online ? 'OFFLINE' : 'ONLINE']}</Button>
|
||||
</div>
|
||||
)}/>
|
||||
</Table>
|
||||
</Loading>
|
||||
<Pagination
|
||||
className="pagination"
|
||||
onChange={currentPage => this.onChange(currentPage)}
|
||||
/>
|
||||
</Card>
|
||||
{this.editServiceDialog()}
|
||||
{this.editInstanceDialog()}
|
||||
{this.editClusterDialog()}
|
||||
{
|
||||
clusters.map(cluster => (
|
||||
<Card
|
||||
key={cluster.name}
|
||||
className="cluster-card"
|
||||
title={`${I18N.CLUSTER}:`}
|
||||
subTitle={cluster.name}
|
||||
contentHeight="auto"
|
||||
extra={(
|
||||
<Button
|
||||
type="normal"
|
||||
onClick={() => this.openClusterDialog(cluster)}
|
||||
>{I18N.EDIT_CLUSTER}</Button>
|
||||
)}
|
||||
>
|
||||
<InstanceTable
|
||||
clusterName={cluster.name}
|
||||
serviceName={serviceName}
|
||||
/>
|
||||
</Card>
|
||||
))
|
||||
}
|
||||
</Loading>
|
||||
<EditServiceDialog ref="editServiceDialog"/>
|
||||
<EditClusterDialog ref="editClusterDialog"/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -17,6 +17,9 @@
|
||||
float: right;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.cluster-card {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.service-detail-edit-dialog, .instance-edit-dialog, .cluster-edit-dialog {
|
||||
|
@ -108,3 +108,8 @@ I18N.UPDATE_INSTANCE = getI18N('update_instance')
|
||||
* 是否上线
|
||||
*/
|
||||
I18N.WHETHER_ONLINE = getI18N('whether_online')
|
||||
|
||||
export const DIALOG_FORM_LAYOUT = {
|
||||
labelCol: {fixedSpan: 12},
|
||||
wrapperCol: {span: 12}
|
||||
}
|
||||
|
@ -23,9 +23,6 @@ class ServiceManagement extends React.Component {
|
||||
this.field = new Field(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
}
|
||||
|
||||
openLoading() {
|
||||
this.setState({loading: true})
|
||||
}
|
||||
@ -116,7 +113,10 @@ class ServiceManagement extends React.Component {
|
||||
<Column title={I18N.COLUMN_IP_COUNT} dataIndex="ipCount"/>
|
||||
<Column title={I18N.COLUMN_HEALTH_STATUS} dataIndex="status"/>
|
||||
<Column title={I18N.COLUMN_OPERATION} align="center" cell={(value, index, record) => (
|
||||
<Button type="normal" disabled>详情</Button>
|
||||
<Button
|
||||
type="normal"
|
||||
onClick={() => this.props.history.push(`/serviceDetail?name=${record.name}`)}
|
||||
>详情</Button>
|
||||
)}/>
|
||||
</Table>
|
||||
</Col>
|
||||
|
Loading…
Reference in New Issue
Block a user