fix: ServiceManagement internationalization

This commit is contained in:
王彦民 2018-12-01 22:13:37 +08:00 committed by zhichen
parent 74e72a8664
commit 3a5bec51cd
11 changed files with 337 additions and 367 deletions

View File

@ -39,8 +39,93 @@ const I18N_CONF = {
namespace: 'Namespace',
},
NameSpace: {
namespace: 'Namespaces',
prompt: 'Notice',
namespaceDetails: 'Namespace details',
namespaceName: 'Name',
namespaceID: 'ID:',
configuration: 'Number of Configurations',
description: 'Description',
removeNamespace: 'Remove the namespace',
confirmDelete: 'Sure you want to delete the following namespaces?',
configurationManagement: 'Configurations',
removeSuccess: 'Remove the namespace success',
deletedSuccessfully: 'Deleted successfully',
deletedFailure: 'Delete failed',
namespaceDelete: 'Delete',
details: 'Details',
edit: 'Edit',
namespacePublic: 'public(to retain control)',
pubNoData: 'No results found.',
namespaceAdd: 'Create Namespace',
namespaceNames: 'Namespaces',
namespaceNumber: 'Namespace ID',
namespaceOperation: 'Actions',
},
ServiceList: {
serviceList: 'Service List',
serviceName: 'Service Name',
serviceNamePlaceholder: 'Enter Service Name',
query: 'Search',
pubNoData: 'No results found.',
columnServiceName: 'Service Name',
columnClusterCount: 'Cluster Count',
columnIpCount: 'Instance Count',
columnHealthyInstanceCount: 'Healthy Instance Count',
operation: 'Operation',
detail: 'Details',
deleteAction: 'Delete',
prompt: 'Confirm',
promptDelete: 'Do you want to delete the service?',
create: 'Create Service',
},
EditClusterDialog: {
updateCluster: 'Update Cluster',
checkType: 'Check Type',
checkPort: 'Check Port',
useIpPortCheck: 'Use port of IP',
checkPath: 'Check Path',
checkHeaders: 'Check Headers',
metadata: 'Metadata',
},
ServiceDetail: {
serviceDetails: 'Service Details',
back: 'Back',
editCluster: 'Edit Cluster',
cluster: 'Cluster',
metadata: 'Metadata',
healthCheckPattern: 'Health check pattern',
protectThreshold: 'Protect Threshold',
serviceName: 'Service Name',
editService: 'Edit Service',
},
EditServiceDialog: {
createService: 'Create Service',
updateService: 'Edit Service',
serviceName: 'Service Name',
metadata: 'Metadata',
protectThreshold: 'Protect Threshold',
healthCheckPattern: 'Health check pattern',
healthCheckPatternService: 'Service',
healthCheckPatternClient: 'Client',
healthCheckPatternNone: 'None',
},
InstanceTable: {
operation: 'Operation',
port: 'Port',
weight: 'Weight',
healthy: 'Healthy',
metadata: 'Metadata',
editor: 'Edit',
offline: 'Offline',
online: 'Online',
},
EditInstanceDialog: {
port: 'Port',
weight: 'Weight',
metadata: 'Metadata',
updateInstance: 'Update Instance',
whetherOnline: 'Whether Online',
},
};
export default I18N_CONF;

View File

@ -39,8 +39,93 @@ const I18N_CONF = {
namespace: '命名空间',
},
NameSpace: {
namespace: '命名空间',
prompt: '提示',
namespaceDetails: '命名空间详情',
namespaceName: '命名空间名称',
namespaceID: '命名空间ID',
configuration: '配置数',
description: '描述',
removeNamespace: '删除命名空间',
confirmDelete: '确定要删除以下命名空间吗?',
configurationManagement: '配置列表',
removeSuccess: '删除命名空间成功',
deletedSuccessfully: '删除成功',
deletedFailure: '删除失败',
namespaceDelete: '删除',
details: '详情',
edit: '编辑',
namespacePublic: 'public(保留控件)',
pubNoData: '没有数据',
namespaceAdd: '新建命名空间',
namespaceNames: '命名空间名称',
namespaceNumber: '命名空间ID',
namespaceOperation: '操作',
},
ServiceList: {
serviceList: '服务列表',
serviceName: '服务名称',
serviceNamePlaceholder: '请输入服务名称',
query: '查询',
pubNoData: '没有数据',
columnServiceName: '服务名',
columnClusterCount: '集群数目',
columnIpCount: '实例数',
columnHealthyInstanceCount: '健康实例数',
operation: '操作',
detail: '详情',
deleteAction: '删除',
prompt: '提示',
promptDelete: '确定要删除当前服务吗?',
create: '创建服务',
},
EditClusterDialog: {
updateCluster: '更新集群',
checkType: '检查类型',
checkPort: '检查端口',
useIpPortCheck: '使用IP端口检查',
checkPath: '检查路径',
checkHeaders: '检查头',
metadata: '元数据',
},
ServiceDetail: {
serviceDetails: '服务详情',
back: '返回',
editCluster: '集群配置',
cluster: '集群',
metadata: '元数据',
healthCheckPattern: '健康检查模式',
protectThreshold: '保护阀值',
serviceName: '服务名',
editService: '编辑服务',
},
EditServiceDialog: {
createService: '创建服务',
updateService: '更新服务',
serviceName: '服务名',
metadata: '元数据',
protectThreshold: '保护阀值',
healthCheckPattern: '健康检查模式',
healthCheckPatternService: '服务端',
healthCheckPatternClient: '客户端',
healthCheckPatternNone: '禁止',
},
InstanceTable: {
operation: '操作',
port: '端口',
weight: '权重',
healthy: '健康状态',
metadata: '元数据',
editor: '编辑',
offline: '下线',
online: '上线',
},
EditInstanceDialog: {
port: '端口',
weight: '权重',
metadata: '元数据',
updateInstance: '编辑实例',
whetherOnline: '是否上线',
},
};
export default I18N_CONF;

View File

@ -17,12 +17,10 @@ import RegionGroup from '../../components/RegionGroup';
import DeleteDialog from '../../components/DeleteDialog';
import NewNameSpace from '../../components/NewNameSpace';
import EditorNameSpace from '../../components/EditorNameSpace';
import { getParams, setParams, request, aliwareIntl } from '../../globalLib';
import { connect } from 'react-redux';
import { getParams, setParams, request } from '../../globalLib';
import './index.scss';
@connect(state => ({ ...state.locale }))
@ConfigProvider.config
class NameSpace extends React.Component {
static displayName = 'NameSpace';
@ -44,7 +42,6 @@ class NameSpace extends React.Component {
const { locale = {} } = this.props;
const { prompt } = locale;
const self = this;
// let serverId = getParams('serverId') || 'center';
self.openLoading();
setTimeout(() => {
request({
@ -104,7 +101,7 @@ class NameSpace extends React.Component {
detailNamespace(record) {
const { locale = {} } = this.props;
const { namespaceDetails } = locale;
const { namespaceDetails, namespaceName, namespaceID, configuration, description } = locale;
const { namespace } = record; // 获取ak,sk
request({
url: `v1/console/namespaces?show=all&namespaceId=${namespace}`,
@ -121,29 +118,21 @@ class NameSpace extends React.Component {
<div>
<div style={{ marginTop: '10px' }}>
<p>
<span style={{ color: '#999', marginRight: 5 }}>
{aliwareIntl.get('nacos.page.namespace.namespace_name')}
</span>
<span style={{ color: '#999', marginRight: 5 }}>{`${namespaceName}:`}</span>
<span style={{ color: '#c7254e' }}>{res.namespaceShowName}</span>
</p>
<p>
<span style={{ color: '#999', marginRight: 5 }}>
{aliwareIntl.get('nacos.page.namespace.namespace_ID')}
</span>
<span style={{ color: '#999', marginRight: 5 }}>{`${namespaceID}:`}</span>
<span style={{ color: '#c7254e' }}>{res.namespace}</span>
</p>
<p>
<span style={{ color: '#999', marginRight: 5 }}>
{aliwareIntl.get('com.alibaba.nacos.page.namespace.configuration')}
</span>
<span style={{ color: '#999', marginRight: 5 }}>{`${configuration}:`}</span>
<span style={{ color: '#c7254e' }}>
{res.configCount} / {res.quota}
</span>
</p>
<p>
<span style={{ color: '#999', marginRight: 5 }}>
{aliwareIntl.get('nacos.page.configdetail.Description')}
</span>
<span style={{ color: '#999', marginRight: 5 }}>{`${description}:`}</span>
<span style={{ color: '#c7254e' }}>{res.namespaceDesc}</span>
</p>
</div>
@ -159,31 +148,32 @@ class NameSpace extends React.Component {
}
removeNamespace(record) {
// let serverId = getParams('serverId') || 'center';
const { locale = {} } = this.props;
const {
removeNamespace,
confirmDelete,
namespaceName,
namespaceID,
configurationManagement,
removeSuccess,
deletedSuccessfully,
deletedFailure,
} = locale;
Dialog.confirm({
title: aliwareIntl.get('nacos.page.namespace.remove_the_namespace'),
title: removeNamespace,
content: (
<div style={{ marginTop: '-20px' }}>
<h3>
{aliwareIntl.get(
'nacos.page.namespace.sure_you_want_to_delete_the_following_namespaces?'
)}
</h3>
<h3>{confirmDelete}</h3>
<p>
<span style={{ color: '#999', marginRight: 5 }}>
{aliwareIntl.get('nacos.page.namespace.namespace_name')}
</span>
<span style={{ color: '#999', marginRight: 5 }}>{`${namespaceName}:`}</span>
<span style={{ color: '#c7254e' }}>{record.namespaceShowName}</span>
</p>
<p>
<span style={{ color: '#999', marginRight: 5 }}>
{aliwareIntl.get('nacos.page.namespace.namespace_ID')}
</span>
<span style={{ color: '#999', marginRight: 5 }}>{`${namespaceID}:`}</span>
<span style={{ color: '#c7254e' }}>{record.namespace}</span>
</p>
</div>
),
language: aliwareIntl.currentLanguageCode || 'zh-cn',
onOk: () => {
const url = `v1/console/namespaces?namespaceId=${record.namespace}`;
request({
@ -191,27 +181,16 @@ class NameSpace extends React.Component {
type: 'delete',
success: res => {
const _payload = {};
_payload.title = aliwareIntl.get(
'com.alibaba.nacos.page.configurationManagement.configuration_management'
);
_payload.title = configurationManagement;
if (res === true) {
const urlnamespace = getParams('namespace');
if (record.namespace === urlnamespace) {
setParams('namespace', this.state.defaultNamespace);
}
Dialog.confirm({
language: aliwareIntl.currentLanguageCode || 'zh-cn',
content: aliwareIntl.get('nacos.page.namespace._Remove_the_namespace_success'),
title: aliwareIntl.get('nacos.page.namespace.deleted_successfully'),
});
Dialog.confirm({ content: removeSuccess, title: deletedSuccessfully });
} else {
Dialog.confirm({
language: aliwareIntl.currentLanguageCode || 'zh-cn',
content: res.message,
title: '删除失败',
});
Dialog.confirm({ content: res.message, title: deletedFailure });
}
this.getNameSpaces();
},
});
@ -245,33 +224,31 @@ class NameSpace extends React.Component {
}
renderOption(value, index, record) {
const { locale = {} } = this.props;
const { namespaceDelete, details, edit } = locale;
let _delinfo = (
<a onClick={this.removeNamespace.bind(this, record)} style={{ marginRight: 10 }}>
{aliwareIntl.get('com.alibaba.nacos.page.namespace.delete')}
{namespaceDelete}
</a>
);
if (record.type === 1 || record.type === 0) {
_delinfo = (
<span style={{ marginRight: 10, cursor: 'not-allowed' }} disabled>
{aliwareIntl.get('com.alibaba.nacos.page.namespace.delete')}
{namespaceDelete}
</span>
);
}
const _detailinfo = (
<a onClick={this.detailNamespace.bind(this, record)} style={{ marginRight: 10 }}>
{aliwareIntl.get('nacos.page.namespace.details')}
{details}
</a>
);
let _editinfo = (
<a onClick={this.openToEdit.bind(this, record)}>
{aliwareIntl.get('com.alibaba.nacos.page.namespace.edit')}
</a>
);
let _editinfo = <a onClick={this.openToEdit.bind(this, record)}>{edit}</a>;
if (record.type === 0 || record.type === 1) {
_editinfo = (
<span style={{ marginRight: 10, cursor: 'not-allowed' }} disabled>
{aliwareIntl.get('com.alibaba.nacos.page.namespace.edit')}
{edit}
</span>
);
}
@ -289,9 +266,11 @@ class NameSpace extends React.Component {
}
renderName(value, index, record) {
const { locale = {} } = this.props;
const { namespacePublic } = locale;
let name = record.namespaceShowName;
if (record.type === 0) {
name = aliwareIntl.get('com.alibaba.nacos.page.namespace.public');
name = namespacePublic;
}
return <div>{name}</div>;
}
@ -305,14 +284,19 @@ class NameSpace extends React.Component {
}
render() {
const pubnodedata = aliwareIntl.get('pubnodata');
const locale = {
empty: pubnodedata,
};
const { locale = {} } = this.props;
const {
pubNoData,
namespace,
namespaceAdd,
namespaceNames,
namespaceNumber,
configuration,
namespaceOperation,
} = locale;
return (
<div style={{ padding: 10 }} className="clearfix">
<RegionGroup left={aliwareIntl.get('nacos.page.namespace.Namespace')} />
<RegionGroup left={namespace} />
<div className="fusion-demo">
<Loading
shape="flower"
@ -328,32 +312,25 @@ class NameSpace extends React.Component {
style={{ marginRight: 0, marginTop: 10 }}
onClick={this.addNameSpace.bind(this)}
>
{aliwareIntl.get('com.alibaba.nacos.page.namespace.add')}
{namespaceAdd}
</Button>
</div>
<div>
<Table
dataSource={this.state.dataSource}
locale={locale}
language={aliwareIntl.currentLanguageCode}
>
<Table dataSource={this.state.dataSource} locale={{ empty: pubNoData }}>
<Table.Column
title={aliwareIntl.get('com.alibaba.nacos.page.namespace.namespace_names')}
title={namespaceNames}
dataIndex="namespaceShowName"
cell={this.renderName.bind(this)}
/>
<Table.Column title={namespaceNumber} dataIndex="namespace" />
<Table.Column
title={aliwareIntl.get('nacos.page.namespace.namespace_number')}
dataIndex="namespace"
/>
<Table.Column
title={aliwareIntl.get('com.alibaba.nacos.page.namespace.configuration')}
title={configuration}
dataIndex="configCount"
cell={this.renderConfigCount.bind(this)}
/>
<Table.Column
title={aliwareIntl.get('com.alibaba.nacos.page.namespace.operation')}
title={namespaceOperation}
dataIndex="time"
cell={this.renderOption.bind(this)}
/>
@ -362,8 +339,8 @@ class NameSpace extends React.Component {
</div>
<DeleteDialog ref="delete" />
<NewNameSpace ref={'newnamespace'} getNameSpaces={this.getNameSpaces.bind(this)} />
<EditorNameSpace ref={'editgroup'} getNameSpaces={this.getNameSpaces.bind(this)} />
<NewNameSpace ref="newnamespace" getNameSpaces={this.getNameSpaces.bind(this)} />
<EditorNameSpace ref="editgroup" getNameSpaces={this.getNameSpaces.bind(this)} />
</Loading>
</div>
</div>

View File

@ -13,10 +13,13 @@
import React from 'react';
import { request } from '../../../globalLib';
import { Dialog, Form, Input, Switch, Select, Message } from '@alifd/next';
import { I18N, DIALOG_FORM_LAYOUT } from './constant';
import { Dialog, Form, Input, Switch, Select, Message, ConfigProvider } from '@alifd/next';
import { DIALOG_FORM_LAYOUT } from './constant';
@ConfigProvider.config
class EditClusterDialog extends React.Component {
static displayName = 'EditClusterDialog';
constructor(props) {
super(props);
this.state = {
@ -85,6 +88,8 @@ class EditClusterDialog extends React.Component {
}
render() {
const { locale = {} } = this.props;
const { updateCluster, checkType, checkPort, useIpPortCheck, checkPath, checkHeaders } = locale;
const { editCluster = {}, editClusterDialogVisible } = this.state;
const {
healthChecker = {},
@ -100,14 +105,14 @@ class EditClusterDialog extends React.Component {
return (
<Dialog
className="cluster-edit-dialog"
title={I18N.UPDATE_CLUSTER}
title={updateCluster}
visible={editClusterDialogVisible}
onOk={() => this.onConfirm()}
onCancel={() => this.hide()}
onClose={() => this.hide()}
>
<Form {...DIALOG_FORM_LAYOUT}>
<Form.Item label={`${I18N.CHECK_TYPE}:`}>
<Form.Item label={`${checkType}:`}>
<Select
className="in-select"
defaultValue={type}
@ -117,14 +122,14 @@ class EditClusterDialog extends React.Component {
<Select.Option value="HTTP">HTTP</Select.Option>
</Select>
</Form.Item>
<Form.Item label={`${I18N.CHECK_PORT}:`}>
<Form.Item label={`${checkPort}:`}>
<Input
className="in-text"
value={defaultCheckPort}
onChange={defaultCheckPort => this.onChangeCluster({ defaultCheckPort })}
/>
</Form.Item>
<Form.Item label={`${I18N.USE_IP_PORT_CHECK}:`}>
<Form.Item label={`${useIpPortCheck}:`}>
<Switch
checked={useIPPort4Check}
onChange={useIPPort4Check => this.onChangeCluster({ useIPPort4Check })}
@ -134,7 +139,7 @@ class EditClusterDialog extends React.Component {
<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>
<label>{`${checkPath}:`}</label>
</div>
<div className="next-col next-col-12 next-form-item-control">
<Input
@ -146,7 +151,7 @@ class EditClusterDialog extends React.Component {
</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>
<label>{`${checkHeaders}:`}</label>
</div>
<div className="next-col next-col-12 next-form-item-control">
<Input
@ -158,7 +163,7 @@ class EditClusterDialog extends React.Component {
</div>
</div>
) : null}
<Form.Item label={`${I18N.METADATA}:`}>
<Form.Item label={`${locale.metadata}:`}>
<Input
className="in-text"
value={metadataText}

View File

@ -13,10 +13,13 @@
import React from 'react';
import { request } from '../../../globalLib';
import { Dialog, Form, Input, Switch, Message } from '@alifd/next';
import { I18N, DIALOG_FORM_LAYOUT } from './constant';
import { Dialog, Form, Input, Switch, Message, ConfigProvider } from '@alifd/next';
import { DIALOG_FORM_LAYOUT } from './constant';
@ConfigProvider.config
class EditInstanceDialog extends React.Component {
static displayName = 'EditInstanceDialog';
constructor(props) {
super(props);
this.state = {
@ -70,11 +73,12 @@ class EditInstanceDialog extends React.Component {
}
render() {
const { locale = {} } = this.props;
const { editInstanceDialogVisible, editInstance } = this.state;
return (
<Dialog
className="instance-edit-dialog"
title={I18N.UPDATE_INSTANCE}
title={locale.updateInstance}
visible={editInstanceDialogVisible}
onOk={() => this.onConfirm()}
onCancel={() => this.hide()}
@ -84,23 +88,23 @@ class EditInstanceDialog extends React.Component {
<Form.Item label="IP:">
<p>{editInstance.ip}</p>
</Form.Item>
<Form.Item label={`${I18N.PORT}:`}>
<Form.Item label={`${locale.port}:`}>
<p>{editInstance.port}</p>
</Form.Item>
<Form.Item label={`${I18N.WEIGHT}:`}>
<Form.Item label={`${locale.weight}:`}>
<Input
className="in-text"
value={editInstance.weight}
onChange={weight => this.onChangeCluster({ weight })}
/>
</Form.Item>
<Form.Item label={`${I18N.WHETHER_ONLINE}:`}>
<Form.Item label={`${locale.whetherOnline}:`}>
<Switch
checked={editInstance.enabled}
onChange={enabled => this.onChangeCluster({ enabled })}
/>
</Form.Item>
<Form.Item label={`${I18N.METADATA}:`}>
<Form.Item label={`${locale.metadata}:`}>
<Input
className="in-text"
value={editInstance.metadataText}

View File

@ -13,10 +13,13 @@
import React from 'react';
import { request } from '../../../globalLib';
import { Dialog, Form, Input, Select, Message } from '@alifd/next';
import { I18N, DIALOG_FORM_LAYOUT } from './constant';
import { Dialog, Form, Input, Select, Message, ConfigProvider } from '@alifd/next';
import { DIALOG_FORM_LAYOUT } from './constant';
@ConfigProvider.config
class EditServiceDialog extends React.Component {
static displayName = 'EditServiceDialog';
constructor(props) {
super(props);
this.state = {
@ -77,19 +80,20 @@ class EditServiceDialog extends React.Component {
}
render() {
const { locale = {} } = this.props;
const { isCreate, editService, editServiceDialogVisible } = this.state;
const { name, protectThreshold, healthCheckMode, metadataText } = editService;
return (
<Dialog
className="service-detail-edit-dialog"
title={isCreate ? I18N.CREATE_SERVICE : I18N.UPDATE_SERVICE}
title={isCreate ? locale.createService : locale.updateService}
visible={editServiceDialogVisible}
onOk={() => this.onConfirm()}
onCancel={() => this.hide()}
onClose={() => this.hide()}
>
<Form {...DIALOG_FORM_LAYOUT}>
<Form.Item label={`${I18N.SERVICE_NAME}:`}>
<Form.Item label={`${locale.serviceName}:`}>
{!isCreate ? (
<p>{name}</p>
) : (
@ -100,25 +104,25 @@ class EditServiceDialog extends React.Component {
/>
)}
</Form.Item>
<Form.Item label={`${I18N.PROTECT_THRESHOLD}:`}>
<Form.Item label={`${locale.protectThreshold}:`}>
<Input
className="in-text"
value={protectThreshold}
onChange={protectThreshold => this.onChangeCluster({ protectThreshold })}
/>
</Form.Item>
<Form.Item label={`${I18N.HEALTH_CHECK_PATTERN}:`}>
<Form.Item label={`${locale.healthCheckPattern}:`}>
<Select
className="in-select"
defaultValue={healthCheckMode}
onChange={healthCheckMode => this.onChangeCluster({ healthCheckMode })}
>
<Select.Option value="server">{I18N.HEALTH_CHECK_PATTERN_SERVICE}</Select.Option>
<Select.Option value="client">{I18N.HEALTH_CHECK_PATTERN_CLIENT}</Select.Option>
<Select.Option value="none">{I18N.HEALTH_CHECK_PATTERN_NONE}</Select.Option>
<Select.Option value="server">{locale.healthCheckPatternService}</Select.Option>
<Select.Option value="client">{locale.healthCheckPatternClient}</Select.Option>
<Select.Option value="none">{locale.healthCheckPatternNone}</Select.Option>
</Select>
</Form.Item>
<Form.Item label={`${I18N.METADATA}:`}>
<Form.Item label={`${locale.metadata}:`}>
<Input
className="in-text"
value={metadataText}

View File

@ -14,11 +14,14 @@
import React from 'react';
import PropTypes from 'prop-types';
import { request } from '../../../globalLib';
import { Button, Pagination, Table } from '@alifd/next';
import { I18N, HEALTHY_COLOR_MAPPING } from './constant';
import { Button, ConfigProvider, Pagination, Table } from '@alifd/next';
import { HEALTHY_COLOR_MAPPING } from './constant';
import EditInstanceDialog from './EditInstanceDialog';
@ConfigProvider.config
class InstanceTable extends React.Component {
static displayName = 'InstanceTable';
static propTypes = {
clusterName: PropTypes.string,
serviceName: PropTypes.string,
@ -26,6 +29,7 @@ class InstanceTable extends React.Component {
constructor(props) {
super(props);
this.editInstanceDialog = React.createRef();
this.state = {
loading: false,
instance: { count: 0, list: [] },
@ -65,7 +69,7 @@ class InstanceTable extends React.Component {
}
openInstanceDialog(instance) {
this.refs.editInstanceDialog.show(instance);
this.editInstanceDialog.current.getInstance().show(instance);
}
switchState(index, record) {
@ -92,22 +96,23 @@ class InstanceTable extends React.Component {
rowColor = ({ healthy }) => ({ className: `row-bg-${HEALTHY_COLOR_MAPPING[`${healthy}`]}` });
render() {
const { locale = {} } = this.props;
const { clusterName, serviceName } = this.props;
const { instance, pageSize, loading } = this.state;
return instance.count ? (
<div>
<Table dataSource={instance.list} loading={loading} getRowProps={this.rowColor}>
<Table.Column width={138} title="IP" dataIndex="ip" />
<Table.Column width={100} title={I18N.PORT} dataIndex="port" />
<Table.Column width={100} title={I18N.WEIGHT} dataIndex="weight" />
<Table.Column width={100} title={locale.port} dataIndex="port" />
<Table.Column width={100} title={locale.weight} dataIndex="weight" />
<Table.Column
width={100}
title={I18N.HEALTHY}
title={locale.healthy}
dataIndex="healthy"
cell={val => `${val}`}
/>
<Table.Column
title={I18N.METADATA}
title={locale.metadata}
dataIndex="metadata"
cell={metadata =>
Object.keys(metadata).map(k => (
@ -118,7 +123,7 @@ class InstanceTable extends React.Component {
}
/>
<Table.Column
title={I18N.OPERATION}
title={locale.operation}
width={160}
cell={(value, index, record) => (
<div>
@ -127,13 +132,13 @@ class InstanceTable extends React.Component {
className="edit-btn"
onClick={() => this.openInstanceDialog(record)}
>
{I18N.EDITOR}
{locale.editor}
</Button>
<Button
type={record.enabled ? 'normal' : 'secondary'}
onClick={() => this.switchState(index, record)}
>
{I18N[record.enabled ? 'OFFLINE' : 'ONLINE']}
{locale[record.enabled ? 'offline' : 'online']}
</Button>
</div>
)}
@ -148,7 +153,7 @@ class InstanceTable extends React.Component {
/>
) : null}
<EditInstanceDialog
ref="editInstanceDialog"
ref={this.editInstanceDialog}
serviceName={serviceName}
clusterName={clusterName}
openLoading={() => this.openLoading()}

View File

@ -12,13 +12,12 @@
*/
import React from 'react';
import { request } from '../../../globalLib';
import { Button, Card, Form, Loading } from '@alifd/next';
import { request } from '@/globalLib';
import { Button, Card, ConfigProvider, Form, Loading } from '@alifd/next';
import EditServiceDialog from './EditServiceDialog';
import EditClusterDialog from './EditClusterDialog';
import InstanceTable from './InstanceTable';
import { getParameter } from 'utils/nacosutil';
import { I18N } from './constant';
import './ServiceDetail.scss';
const FormItem = Form.Item;
@ -27,9 +26,14 @@ const pageFormLayout = {
wrapperCol: { span: 14 },
};
@ConfigProvider.config
class ServiceDetail extends React.Component {
static displayName = 'ServiceDetail';
constructor(props) {
super(props);
this.editServiceDialog = React.createRef();
this.editClusterDialog = React.createRef();
this.state = {
serviceName: getParameter(props.location.search, 'name'),
loading: false,
@ -69,14 +73,15 @@ class ServiceDetail extends React.Component {
}
openEditServiceDialog() {
this.refs.editServiceDialog.show(this.state.service);
this.editServiceDialog.current.getInstance().show(this.state.service);
}
openClusterDialog(cluster) {
this.refs.editClusterDialog.show(cluster);
this.editClusterDialog.current.getInstance().show(cluster);
}
render() {
const { locale = {} } = this.props;
const { serviceName, loading, service = {}, clusters } = this.state;
const { metadata = {} } = service;
const metadataText = Object.keys(metadata)
@ -97,34 +102,34 @@ class ServiceDetail extends React.Component {
width: '100%',
}}
>
{I18N.SERVICE_DETAILS}
{locale.serviceDetails}
<Button
type="primary"
className="header-btn"
onClick={() => this.props.history.goBack()}
>
{I18N.BACK}
{locale.back}
</Button>
<Button
type="normal"
className="header-btn"
onClick={() => this.openEditServiceDialog()}
>
{I18N.EDIT_SERVICE}
{locale.editService}
</Button>
</h1>
<Form style={{ width: '60%' }} {...pageFormLayout}>
<FormItem label={`${I18N.SERVICE_NAME}:`}>
<FormItem label={`${locale.serviceName}:`}>
<p>{service.name}</p>
</FormItem>
<FormItem label={`${I18N.PROTECT_THRESHOLD}:`}>
<FormItem label={`${locale.protectThreshold}:`}>
<p>{service.protectThreshold}</p>
</FormItem>
<FormItem label={`${I18N.HEALTH_CHECK_PATTERN}:`}>
<FormItem label={`${locale.healthCheckPattern}:`}>
<p>{service.healthCheckMode}</p>
</FormItem>
<FormItem label={`${I18N.METADATA}:`}>
<FormItem label={`${locale.metadata}:`}>
<p>{metadataText}</p>
</FormItem>
</Form>
@ -132,12 +137,12 @@ class ServiceDetail extends React.Component {
<Card
key={cluster.name}
className="cluster-card"
title={`${I18N.CLUSTER}:`}
title={`${locale.cluster}:`}
subTitle={cluster.name}
contentHeight="auto"
extra={
<Button type="normal" onClick={() => this.openClusterDialog(cluster)}>
{I18N.EDIT_CLUSTER}
{locale.editCluster}
</Button>
}
>
@ -146,13 +151,13 @@ class ServiceDetail extends React.Component {
))}
</Loading>
<EditServiceDialog
ref="editServiceDialog"
ref={this.editServiceDialog}
openLoading={() => this.openLoading()}
closeLoading={() => this.closeLoading()}
getServiceDetail={() => this.getServiceDetail()}
/>
<EditClusterDialog
ref="editClusterDialog"
ref={this.editClusterDialog}
openLoading={() => this.openLoading()}
closeLoading={() => this.closeLoading()}
getServiceDetail={() => this.getServiceDetail()}

View File

@ -11,128 +11,6 @@
* limitations under the License.
*/
import { aliwareIntl } from '../../../globalLib';
const getI18N = (key, prefix = 'com.alibaba.nacos.page.serviceDetail.') =>
aliwareIntl.get(prefix + key);
export const I18N = {};
/**
* 服务列表
*/
I18N.SERVICE_DETAILS = getI18N('service_details');
/**
* 编辑服务
*/
I18N.EDIT_SERVICE = getI18N('edit_service');
/**
* 返回
*/
I18N.BACK = getI18N('back');
/**
* 服务名
*/
I18N.SERVICE_NAME = getI18N('service_name');
/**
* 保护阀值
*/
I18N.PROTECT_THRESHOLD = getI18N('protect_threshold');
/**
* 健康检查模式
*/
I18N.HEALTH_CHECK_PATTERN = getI18N('health_check_pattern');
/**
* 健康检查模式 - 服务端
*/
I18N.HEALTH_CHECK_PATTERN_SERVICE = getI18N('health_check_pattern.service');
/**
* 健康检查模式 - 客户端
*/
I18N.HEALTH_CHECK_PATTERN_CLIENT = getI18N('health_check_pattern.client');
/**
* 健康检查模式 - 禁止
*/
I18N.HEALTH_CHECK_PATTERN_NONE = getI18N('health_check_pattern.none');
/**
* 元数据
*/
I18N.METADATA = getI18N('metadata');
/**
* 更新服务
*/
I18N.UPDATE_SERVICE = getI18N('update_service');
/**
* 创建服务
*/
I18N.CREATE_SERVICE = getI18N('create_service');
/**
* 集群
*/
I18N.CLUSTER = getI18N('cluster');
/**
* 端口
*/
I18N.PORT = getI18N('port');
/**
* 权重
*/
I18N.WEIGHT = getI18N('weight');
/**
* 健康状态
*/
I18N.HEALTHY = getI18N('healthy');
/**
* 操作
*/
I18N.OPERATION = getI18N('operation');
/**
* 编辑
*/
I18N.EDITOR = getI18N('editor');
/**
* 上线
*/
I18N.ONLINE = getI18N('online');
/**
* 下线
*/
I18N.OFFLINE = getI18N('offline');
/**
* 集群配置
*/
I18N.EDIT_CLUSTER = getI18N('edit_cluster');
/**
* 检查类型
*/
I18N.CHECK_TYPE = getI18N('check_type');
/**
* 检查端口
*/
I18N.CHECK_PORT = getI18N('check_port');
/**
* 使用IP端口检查
*/
I18N.USE_IP_PORT_CHECK = getI18N('use_ip_port_check');
/**
* 检查路径
*/
I18N.CHECK_PATH = getI18N('check_path');
/**
* 检查头
*/
I18N.CHECK_HEADERS = getI18N('check_headers');
/**
* 更新集群
*/
I18N.UPDATE_CLUSTER = getI18N('update_cluster');
/**
* 编辑实例
*/
I18N.UPDATE_INSTANCE = getI18N('update_instance');
/**
* 是否上线
*/
I18N.WHETHER_ONLINE = getI18N('whether_online');
export const DIALOG_FORM_LAYOUT = {
labelCol: { fixedSpan: 12 },
wrapperCol: { span: 12 },

View File

@ -12,9 +12,6 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
import RegionGroup from '../../../components/RegionGroup/index';
import { request, aliwareIntl } from '../../../globalLib';
import {
Button,
Field,
@ -26,22 +23,25 @@ import {
Table,
Dialog,
Message,
ConfigProvider,
} from '@alifd/next';
import { request } from '../../../globalLib';
import RegionGroup from '../../../components/RegionGroup';
import EditServiceDialog from '../ServiceDetail/EditServiceDialog';
import { I18N, STATUS_COLOR_MAPPING } from './constant';
import './ServiceList.scss';
const FormItem = Form.Item;
const { Row, Col } = Grid;
const { Column } = Table;
@ConfigProvider.config
class ServiceList extends React.Component {
static propTypes = {
history: PropTypes.object,
};
static displayName = 'ServiceList';
constructor(props) {
super(props);
this.editServiceDialog = React.createRef();
this.state = {
loading: false,
total: 0,
@ -62,7 +62,7 @@ class ServiceList extends React.Component {
}
openEditServiceDialog() {
this.refs.editServiceDialog.show(this.state.service);
this.editServiceDialog.current.show(this.state.service);
}
queryServiceList() {
@ -92,9 +92,11 @@ class ServiceList extends React.Component {
};
deleteService(serviceName) {
const { locale = {} } = this.props;
const { prompt, promptDelete } = locale;
Dialog.confirm({
title: I18N.PROMPT,
content: I18N.PROMPT_DELETE,
title: prompt,
content: promptDelete,
onOk: () => {
request({
method: 'DELETE',
@ -118,11 +120,22 @@ class ServiceList extends React.Component {
rowColor = row => ({ className: !row.healthyInstanceCount ? 'row-bg-red' : '' });
render() {
const { locale = {} } = this.props;
const {
pubNoData,
serviceList,
serviceName,
serviceNamePlaceholder,
query,
create,
operation,
detail,
deleteAction,
} = locale;
const { keyword } = this.state;
const { init, getValue } = this.field;
this.init = init;
this.getValue = getValue;
const locale = { empty: I18N.PUBNODEDATA };
return (
<div className="main-container service-management">
@ -133,13 +146,13 @@ class ServiceList extends React.Component {
tip="Loading..."
color="#333"
>
<RegionGroup left={I18N.SERVICE_LIST} namespaceCallBack={this.getQueryLater} />
<RegionGroup left={serviceList} namespaceCallBack={this.getQueryLater} />
<Row className="demo-row" style={{ marginBottom: 10, padding: 0 }}>
<Col span="24">
<Form inline field={this.field}>
<FormItem label={I18N.SERVICE_NAME}>
<FormItem label={serviceName}>
<Input
placeholder={I18N.ENTER_SERVICE_NAME}
placeholder={serviceNamePlaceholder}
style={{ width: 200 }}
value={keyword}
onChange={keyword => this.setState({ keyword })}
@ -151,12 +164,12 @@ class ServiceList extends React.Component {
onClick={() => this.setState({ currentPage: 1 }, () => this.queryServiceList())}
style={{ marginRight: 10 }}
>
{I18N.QUERY}
{query}
</Button>
</FormItem>
<FormItem label="" style={{ float: 'right' }}>
<Button type="secondary" onClick={() => this.openEditServiceDialog()}>
{I18N.CREATE}
{create}
</Button>
</FormItem>
</Form>
@ -168,19 +181,18 @@ class ServiceList extends React.Component {
dataSource={this.state.dataSource}
fixedHeader
maxBodyHeight={530}
locale={locale}
language={aliwareIntl.currentLanguageCode}
locale={{ empty: pubNoData }}
getRowProps={row => this.rowColor(row)}
>
<Column title={I18N.COLUMN_SERVICE_NAME} dataIndex="name" />
<Column title={I18N.COLUMN_CLUSTER_COUNT} dataIndex="clusterCount" />
<Column title={I18N.COLUMN_IP_COUNT} dataIndex="ipCount" />
<Column title={locale.columnServiceName} dataIndex="name" />
<Column title={locale.columnClusterCount} dataIndex="clusterCount" />
<Column title={locale.columnIpCount} dataIndex="ipCount" />
<Column
title={I18N.COLUMN_HEALTHY_INSTANCE_COUNT}
title={locale.columnHealthyInstanceCount}
dataIndex="healthyInstanceCount"
/>
<Column
title={I18N.COLUMN_OPERATION}
title={operation}
align="center"
cell={(value, index, record) => (
<div>
@ -190,14 +202,14 @@ class ServiceList extends React.Component {
this.props.history.push(`/serviceDetail?name=${record.name}`)
}
>
{I18N.DETAIL}
{detail}
</Button>
<Button
style={{ marginLeft: 12 }}
type="normal"
onClick={() => this.deleteService(record.name)}
>
{I18N.DELETE}
{deleteAction}
</Button>
</div>
)}
@ -214,13 +226,12 @@ class ServiceList extends React.Component {
onChange={currentPage =>
this.setState({ currentPage }, () => this.queryServiceList())
}
language={aliwareIntl.currentLanguageCode}
/>
</div>
)}
</Loading>
<EditServiceDialog
ref="editServiceDialog"
ref={this.editServiceDialog}
openLoading={() => this.openLoading()}
closeLoading={() => this.closeLoading()}
queryServiceList={() => this.setState({ currentPage: 1 }, () => this.queryServiceList())}

View File

@ -1,89 +0,0 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { aliwareIntl } from '../../../globalLib';
const getI18N = (key, prefix = 'com.alibaba.nacos.page.serviceManagement.') =>
aliwareIntl.get(prefix + key);
export const I18N = {};
/**
* 服务列表
*/
I18N.SERVICE_LIST = getI18N('service_list');
/**
* 服务名称
*/
I18N.SERVICE_NAME = getI18N('service_name');
/**
* 请输入服务名称
*/
I18N.ENTER_SERVICE_NAME = getI18N('please_enter_the_service_name');
/**
* 查询
*/
I18N.QUERY = getI18N('query');
/**
* 查询
*/
I18N.PUBNODEDATA = getI18N('pubnodata', '');
/**
* 服务名
*/
I18N.COLUMN_SERVICE_NAME = getI18N('table.column.service_name');
/**
* 集群数目
*/
I18N.COLUMN_CLUSTER_COUNT = getI18N('table.column.cluster_count');
/**
* IP数目
*/
I18N.COLUMN_IP_COUNT = getI18N('table.column.ip_count');
/**
* 健康实例数
*/
I18N.COLUMN_HEALTHY_INSTANCE_COUNT = getI18N('table.column.healthy_instance_count');
/**
* 操作
*/
I18N.COLUMN_OPERATION = getI18N('table.column.operation');
/**
* 详情
*/
I18N.DETAIL = getI18N('detail');
/**
* 删除
*/
I18N.DELETE = getI18N('delete');
/**
* 提示
*/
I18N.PROMPT = getI18N('prompt');
/**
* 提示
*/
I18N.PROMPT_DELETE = getI18N('prompt_delete');
/**
* 删除
*/
I18N.DELETE = getI18N('delete');
/**
* 创建服务
*/
I18N.CREATE = getI18N('create');
export const STATUS_COLOR_MAPPING = {
: 'green',
: 'light-green',
: 'orange',
: 'red',
};