diff --git a/console/src/main/resources/static/src/pages/ServiceDetail/EditClusterDialog.js b/console/src/main/resources/static/src/pages/ServiceDetail/EditClusterDialog.js new file mode 100644 index 000000000..e7c6d97bc --- /dev/null +++ b/console/src/main/resources/static/src/pages/ServiceDetail/EditClusterDialog.js @@ -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 ( + this.onConfirm()} + onCancel={() => this.hide()} + onClose={() => this.hide()} + > +
+ + + + + this.onChangeCluster({defaultCheckPort})} + /> + + + this.onChangeCluster({useIPPort4Check})} + /> + + { + type === 'HTTP' + ? (
+
+
+ +
+
+ healthCheckerChange({path})} + /> +
+
+
+
+ +
+
+ healthCheckerChange({headers})} + /> +
+
+
) + : null + } + + this.onChangeCluster({metadataText})} + /> + +
+
+ ) + } +} + +/*****************************此行为标记行, 请勿删和修改此行, 主体代码请写在此行上面的class中, 组件导出语句及其他信息请写在此行下面*****************************/ +export default EditClusterDialog; diff --git a/console/src/main/resources/static/src/pages/ServiceDetail/EditInstanceDialog.js b/console/src/main/resources/static/src/pages/ServiceDetail/EditInstanceDialog.js new file mode 100644 index 000000000..6c7566b2e --- /dev/null +++ b/console/src/main/resources/static/src/pages/ServiceDetail/EditInstanceDialog.js @@ -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 ( + this.onConfirm()} + onCancel={() => this.hide()} + onClose={() => this.hide()} + > +
+ +

1.1.1.1

+
+ +

8080

+
+ + this.onChangeCluster({healthy})} + /> + + + f}/> + + + this.onChangeCluster({metadataText})} + /> + +
+
+ ) + } +} + +/*****************************此行为标记行, 请勿删和修改此行, 主体代码请写在此行上面的class中, 组件导出语句及其他信息请写在此行下面*****************************/ +export default EditInstanceDialog; diff --git a/console/src/main/resources/static/src/pages/ServiceDetail/EditServiceDialog.js b/console/src/main/resources/static/src/pages/ServiceDetail/EditServiceDialog.js new file mode 100644 index 000000000..910f59b0e --- /dev/null +++ b/console/src/main/resources/static/src/pages/ServiceDetail/EditServiceDialog.js @@ -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 ( + this.onConfirm()} + onCancel={() => this.hide()} + onClose={() => this.hide()} + > +
+ +

{name}

+
+ + this.onChangeCluster({protectThreshold})} + /> + + + + + + this.onChangeCluster({metadataText})} + /> + +
+
+ ) + } +} + +/*****************************此行为标记行, 请勿删和修改此行, 主体代码请写在此行上面的class中, 组件导出语句及其他信息请写在此行下面*****************************/ +export default EditServiceDialog; diff --git a/console/src/main/resources/static/src/pages/ServiceDetail/InstanceTable.js b/console/src/main/resources/static/src/pages/ServiceDetail/InstanceTable.js new file mode 100644 index 000000000..d097722bd --- /dev/null +++ b/console/src/main/resources/static/src/pages/ServiceDetail/InstanceTable.js @@ -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 ? ( +
+ + + + + + + ( +
+ + +
+ )}/> +
+ { + instance.count > pageSize + ? ( + this.onChange(clusterName, currentPage)} + /> + ) + : null + } + +
+ ) : null + } +} + +/*****************************此行为标记行, 请勿删和修改此行, 主体代码请写在此行上面的class中, 组件导出语句及其他信息请写在此行下面*****************************/ +export default InstanceTable; diff --git a/console/src/main/resources/static/src/pages/ServiceDetail/ServiceDetail.js b/console/src/main/resources/static/src/pages/ServiceDetail/ServiceDetail.js index 611123a04..332f71986 100644 --- a/console/src/main/resources/static/src/pages/ServiceDetail/ServiceDetail.js +++ b/console/src/main/resources/static/src/pages/ServiceDetail/ServiceDetail.js @@ -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 ( - -
- -

test.com

-
- - - - - - - - - -
-
- ) + openEditServiceDialog() { + this.refs.editServiceDialog.show(this.state.service) } - editClusterDialog() { - const hideDialog = () => this.setState({editClusterDialogVisible: false}) - const {editClusterDialogVisible} = this.state - return ( - -
- - - - - - - - f}/> - - { - this.state.checkType === 'http' - ? ( - - - - - - - -
- ) - : null - } - - - - -
- ) + openClusterDialog(cluster) { + this.refs.editClusterDialog.show(cluster) } - editInstanceDialog() { - const hideDialog = () => this.setState({editInstanceDialogVisible: false}) - const {editInstanceDialogVisible} = this.state - return ( - -
- -

1.1.1.1

-
- -

8080

-
- - - - - f}/> - - - - -
-
- ) - } - - - 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 (

this.openEditServiceDialog()} >{I18N.EDIT_SERVICE}

-
+ -

test.com

+

{service.name}

-

0.5

+

{service.protectThreshold}

-

true

+

{service.healthCheckMode}

-

k1=v1,k2=v2

+

{metadataText}

- - {I18N.EDIT_CLUSTER}} - > - - - - - - - - ( -
- - -
- )}/> -
-
- this.onChange(currentPage)} - /> -
- {this.editServiceDialog()} - {this.editInstanceDialog()} - {this.editClusterDialog()} + { + clusters.map(cluster => ( + this.openClusterDialog(cluster)} + >{I18N.EDIT_CLUSTER} + )} + > + + + )) + }
+ +
); } diff --git a/console/src/main/resources/static/src/pages/ServiceDetail/ServiceDetail.less b/console/src/main/resources/static/src/pages/ServiceDetail/ServiceDetail.less index bc701953a..de659f2ec 100644 --- a/console/src/main/resources/static/src/pages/ServiceDetail/ServiceDetail.less +++ b/console/src/main/resources/static/src/pages/ServiceDetail/ServiceDetail.less @@ -17,6 +17,9 @@ float: right; margin-top: 15px; } + .cluster-card { + margin-bottom: 30px; + } } .service-detail-edit-dialog, .instance-edit-dialog, .cluster-edit-dialog { diff --git a/console/src/main/resources/static/src/pages/ServiceDetail/constant.js b/console/src/main/resources/static/src/pages/ServiceDetail/constant.js index ece527f60..f5d8fa424 100644 --- a/console/src/main/resources/static/src/pages/ServiceDetail/constant.js +++ b/console/src/main/resources/static/src/pages/ServiceDetail/constant.js @@ -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} +} diff --git a/console/src/main/resources/static/src/pages/ServiceManagement/ServiceManagement.js b/console/src/main/resources/static/src/pages/ServiceManagement/ServiceManagement.js index 22aecf912..64462e24d 100644 --- a/console/src/main/resources/static/src/pages/ServiceManagement/ServiceManagement.js +++ b/console/src/main/resources/static/src/pages/ServiceManagement/ServiceManagement.js @@ -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 { ( - + )}/>