Merge branch 'develop' of https://github.com/alibaba/nacos into develop
This commit is contained in:
commit
024cf2a1c3
@ -19,8 +19,7 @@ matrix:
|
|||||||
env: CUSTOM_JDK="oraclejdk8"
|
env: CUSTOM_JDK="oraclejdk8"
|
||||||
|
|
||||||
jdk:
|
jdk:
|
||||||
- openjdk10
|
- openjdk11
|
||||||
- openjdk9
|
|
||||||
- openjdk8
|
- openjdk8
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
|
@ -17,9 +17,9 @@ package com.alibaba.nacos.client.config.utils;
|
|||||||
|
|
||||||
import com.alibaba.nacos.api.common.Constants;
|
import com.alibaba.nacos.api.common.Constants;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ public class MD5 {
|
|||||||
private static int DIGITS_SIZE = 16;
|
private static int DIGITS_SIZE = 16;
|
||||||
private static char[] digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
private static char[] digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||||
|
|
||||||
private static Map<Character, Integer> rDigits = new HashMap<Character, Integer>(16);
|
private static Map<Character, Integer> rDigits = Maps.newHashMapWithExpectedSize(16);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
for (int i = 0; i < digits.length; ++i) {
|
for (int i = 0; i < digits.length; ++i) {
|
||||||
|
@ -217,6 +217,7 @@ public class NamingProxy {
|
|||||||
params.put("ip", instance.getIp());
|
params.put("ip", instance.getIp());
|
||||||
params.put("port", String.valueOf(instance.getPort()));
|
params.put("port", String.valueOf(instance.getPort()));
|
||||||
params.put("weight", String.valueOf(instance.getWeight()));
|
params.put("weight", String.valueOf(instance.getWeight()));
|
||||||
|
params.put("enabled", String.valueOf(instance.isEnabled()));
|
||||||
params.put("ephemeral", String.valueOf(instance.isEphemeral()));
|
params.put("ephemeral", String.valueOf(instance.isEphemeral()));
|
||||||
params.put("metadata", JSON.toJSONString(instance.getMetadata()));
|
params.put("metadata", JSON.toJSONString(instance.getMetadata()));
|
||||||
|
|
||||||
|
@ -351,9 +351,12 @@ const I18N_CONF = {
|
|||||||
},
|
},
|
||||||
ConfigEditor: {
|
ConfigEditor: {
|
||||||
official: 'Official',
|
official: 'Official',
|
||||||
|
production: 'Production',
|
||||||
|
beta: 'BETA',
|
||||||
wrong: 'Error',
|
wrong: 'Error',
|
||||||
submitFailed: 'Cannot be empty, submit failed',
|
submitFailed: 'Cannot be empty, submit failed',
|
||||||
toedittitle: 'Edit Configuration',
|
toedittitle: 'Edit Configuration',
|
||||||
|
newConfigEditor: 'New Config Editor',
|
||||||
toedit: 'Edit Configuration',
|
toedit: 'Edit Configuration',
|
||||||
vdchart: 'Illegal characters not allowed',
|
vdchart: 'Illegal characters not allowed',
|
||||||
recipientFrom: 'Data ID cannot be empty',
|
recipientFrom: 'Data ID cannot be empty',
|
||||||
@ -369,8 +372,12 @@ const I18N_CONF = {
|
|||||||
escExit: 'Press F1 to view in full screen',
|
escExit: 'Press F1 to view in full screen',
|
||||||
releaseBeta: 'Press Esc to exit ',
|
releaseBeta: 'Press Esc to exit ',
|
||||||
release: 'Beta Publish',
|
release: 'Beta Publish',
|
||||||
|
stopPublishBeta: 'Stop Beta',
|
||||||
|
betaPublish: 'Beta Publish:',
|
||||||
|
betaSwitchPrompt: 'Not checked by default.',
|
||||||
publish: 'Publish',
|
publish: 'Publish',
|
||||||
back: 'Back',
|
back: 'Back',
|
||||||
|
codeValErrorPrompt: 'Configuration information may have syntax errors. Are you sure to submit?',
|
||||||
},
|
},
|
||||||
EditorNameSpace: {
|
EditorNameSpace: {
|
||||||
notice: 'Notice',
|
notice: 'Notice',
|
||||||
|
@ -349,10 +349,13 @@ const I18N_CONF = {
|
|||||||
},
|
},
|
||||||
ConfigEditor: {
|
ConfigEditor: {
|
||||||
official: '正式',
|
official: '正式',
|
||||||
|
production: '正式',
|
||||||
|
beta: 'BETA',
|
||||||
wrong: '错误',
|
wrong: '错误',
|
||||||
submitFailed: '不能为空, 提交失败',
|
submitFailed: '不能为空, 提交失败',
|
||||||
toedittitle: '编辑配置',
|
toedittitle: '编辑配置',
|
||||||
toedit: '编辑配置',
|
toedit: '编辑配置',
|
||||||
|
newConfigEditor: '新建配置',
|
||||||
vdchart: '请勿输入非法字符',
|
vdchart: '请勿输入非法字符',
|
||||||
recipientFrom: 'Data ID不能为空',
|
recipientFrom: 'Data ID不能为空',
|
||||||
homeApplication: 'Group不能为空',
|
homeApplication: 'Group不能为空',
|
||||||
@ -360,15 +363,19 @@ const I18N_CONF = {
|
|||||||
groupNotEmpty: '更多高级选项',
|
groupNotEmpty: '更多高级选项',
|
||||||
tags: '标签:',
|
tags: '标签:',
|
||||||
pleaseEnterTag: '请输入标签',
|
pleaseEnterTag: '请输入标签',
|
||||||
targetEnvironment: '归属应用:',
|
targetEnvironment: '归属应用:',
|
||||||
description: '描述:',
|
description: '描述:',
|
||||||
format: '配置格式:',
|
format: '配置格式:',
|
||||||
configcontent: '配置内容',
|
configcontent: '配置内容',
|
||||||
escExit: '按F1显示全屏',
|
escExit: '按F1显示全屏',
|
||||||
releaseBeta: '按Esc退出全屏',
|
releaseBeta: '按Esc退出全屏',
|
||||||
release: '发布Beta',
|
release: '发布Beta',
|
||||||
|
stopPublishBeta: '停止Beta',
|
||||||
|
betaPublish: 'Beta发布:',
|
||||||
|
betaSwitchPrompt: '默认不要勾选。',
|
||||||
publish: '发布',
|
publish: '发布',
|
||||||
back: '返回',
|
back: '返回',
|
||||||
|
codeValErrorPrompt: '配置信息可能有语法错误, 确定提交吗?',
|
||||||
},
|
},
|
||||||
EditorNameSpace: {
|
EditorNameSpace: {
|
||||||
notice: '提示',
|
notice: '提示',
|
||||||
|
@ -0,0 +1,572 @@
|
|||||||
|
/*
|
||||||
|
* 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 React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { getParams } from '../../../globalLib';
|
||||||
|
import request from '../../../utils/request';
|
||||||
|
import validateContent from 'utils/validateContent';
|
||||||
|
import SuccessDialog from '../../../components/SuccessDialog';
|
||||||
|
import DiffEditorDialog from '../../../components/DiffEditorDialog';
|
||||||
|
import './index.scss';
|
||||||
|
import {
|
||||||
|
Balloon,
|
||||||
|
Button,
|
||||||
|
Dialog,
|
||||||
|
Field,
|
||||||
|
Form,
|
||||||
|
Checkbox,
|
||||||
|
Icon,
|
||||||
|
Input,
|
||||||
|
Loading,
|
||||||
|
Radio,
|
||||||
|
Switch,
|
||||||
|
Select,
|
||||||
|
Tab,
|
||||||
|
Message,
|
||||||
|
Grid,
|
||||||
|
ConfigProvider,
|
||||||
|
} from '@alifd/next';
|
||||||
|
|
||||||
|
const { Row, Col } = Grid;
|
||||||
|
|
||||||
|
const LANGUAGE_LIST = [
|
||||||
|
{ value: 'text', label: 'TEXT' },
|
||||||
|
{ value: 'json', label: 'JSON' },
|
||||||
|
{ value: 'xml', label: 'XML' },
|
||||||
|
{ value: 'yaml', label: 'YAML' },
|
||||||
|
{ value: 'html', label: 'HTML' },
|
||||||
|
{ value: 'properties', label: 'Properties' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const TAB_LIST = ['production', 'beta'];
|
||||||
|
|
||||||
|
@ConfigProvider.config
|
||||||
|
class ConfigEditor extends React.Component {
|
||||||
|
static displayName = 'ConfigEditor';
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
locale: PropTypes.object,
|
||||||
|
history: PropTypes.object,
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
loading: false,
|
||||||
|
isBeta: false,
|
||||||
|
isNewConfig: true,
|
||||||
|
betaPublishSuccess: false,
|
||||||
|
betaIps: '',
|
||||||
|
tabActiveKey: '',
|
||||||
|
form: {
|
||||||
|
dataId: '', // 配置 ID
|
||||||
|
group: '', // 分组
|
||||||
|
content: '', // 配置内容
|
||||||
|
appName: '', // 应用名
|
||||||
|
desc: '', // 描述
|
||||||
|
config_tags: [],
|
||||||
|
type: 'text', // 配置格式
|
||||||
|
},
|
||||||
|
tagDataSource: [],
|
||||||
|
openAdvancedSettings: false,
|
||||||
|
};
|
||||||
|
this.successDialog = React.createRef();
|
||||||
|
this.diffEditorDialog = React.createRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const isNewConfig = !getParams('dataId');
|
||||||
|
const group = getParams('group').trim();
|
||||||
|
this.setState({ isNewConfig }, () => {
|
||||||
|
if (!isNewConfig) {
|
||||||
|
this.changeForm(
|
||||||
|
{
|
||||||
|
dataId: getParams('dataId').trim(),
|
||||||
|
group,
|
||||||
|
},
|
||||||
|
() => this.getConfig()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
if (group) {
|
||||||
|
this.setState({ group });
|
||||||
|
}
|
||||||
|
this.initMoacoEditor('text', '');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
initMoacoEditor(language, value) {
|
||||||
|
const container = document.getElementById('container');
|
||||||
|
container.innerHTML = '';
|
||||||
|
this.monacoEditor = null;
|
||||||
|
const options = {
|
||||||
|
value,
|
||||||
|
language: this.state.configType,
|
||||||
|
codeLens: true,
|
||||||
|
selectOnLineNumbers: true,
|
||||||
|
roundedSelection: false,
|
||||||
|
readOnly: false,
|
||||||
|
lineNumbersMinChars: true,
|
||||||
|
theme: 'vs-dark',
|
||||||
|
wordWrapColumn: 120,
|
||||||
|
folding: false,
|
||||||
|
showFoldingControls: 'always',
|
||||||
|
wordWrap: 'wordWrapColumn',
|
||||||
|
cursorStyle: 'line',
|
||||||
|
automaticLayout: true,
|
||||||
|
};
|
||||||
|
if (!window.monaco) {
|
||||||
|
window.importEditor(() => {
|
||||||
|
this.monacoEditor = window.monaco.editor.create(container, options);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.monacoEditor = window.monaco.editor.create(container, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createDiffCodeMirror(leftCode, rightCode) {
|
||||||
|
const target = this.diffEditorDialog.current.getInstance();
|
||||||
|
target.innerHTML = '';
|
||||||
|
this.diffeditor = window.CodeMirror.MergeView(target, {
|
||||||
|
value: leftCode || '',
|
||||||
|
origLeft: null,
|
||||||
|
orig: rightCode || '',
|
||||||
|
lineNumbers: true,
|
||||||
|
mode: this.mode,
|
||||||
|
theme: 'xq-light',
|
||||||
|
highlightDifferences: true,
|
||||||
|
connect: 'align',
|
||||||
|
collapseIdentical: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openDiff(cbName) {
|
||||||
|
this.diffcb = cbName;
|
||||||
|
let leftvalue = this.monacoEditor.getValue();
|
||||||
|
let rightvalue = this.codeVal;
|
||||||
|
leftvalue = leftvalue.replace(/\r\n/g, '\n').replace(/\n/g, '\r\n');
|
||||||
|
rightvalue = rightvalue.replace(/\r\n/g, '\n').replace(/\n/g, '\r\n');
|
||||||
|
this.diffEditorDialog.current.getInstance().openDialog(leftvalue, rightvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
clickTab(tabActiveKey) {
|
||||||
|
this.setState({ tabActiveKey }, () => this.getConfig(tabActiveKey === 'bata'));
|
||||||
|
}
|
||||||
|
|
||||||
|
getCodeVal() {
|
||||||
|
const { locale = {} } = this.props;
|
||||||
|
const { type, content } = this.state.form;
|
||||||
|
const codeVal = this.monacoEditor ? this.monacoEditor.getValue() : content;
|
||||||
|
if (!codeVal) {
|
||||||
|
Message.error({
|
||||||
|
content: locale.submitFailed,
|
||||||
|
align: 'cc cc',
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return codeVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
publish() {
|
||||||
|
const { locale = {} } = this.props;
|
||||||
|
const { type } = this.state.form;
|
||||||
|
if (this.state.isNewConfig) {
|
||||||
|
this.validation();
|
||||||
|
}
|
||||||
|
const content = this.getCodeVal();
|
||||||
|
if (!content) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (validateContent.validate({ content, type })) {
|
||||||
|
return this._publishConfig();
|
||||||
|
} else {
|
||||||
|
Dialog.confirm({
|
||||||
|
content: locale.codeValErrorPrompt,
|
||||||
|
onOk: () => this._publishConfig(),
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_publishConfig(beta = false) {
|
||||||
|
const { locale } = this.props;
|
||||||
|
const { betaIps, isNewConfig } = this.state;
|
||||||
|
const headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
|
||||||
|
if (beta) {
|
||||||
|
headers.betaIps = betaIps;
|
||||||
|
}
|
||||||
|
const data = { ...this.state.form, content: this.getCodeVal() };
|
||||||
|
return request({
|
||||||
|
url: 'v1/cs/configs',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
transformRequest: [
|
||||||
|
function(data) {
|
||||||
|
let ret = '';
|
||||||
|
for (let it in data) {
|
||||||
|
ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&';
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
],
|
||||||
|
headers,
|
||||||
|
}).then(res => {
|
||||||
|
if (res) {
|
||||||
|
if (isNewConfig) {
|
||||||
|
this.setState({ isNewConfig: false });
|
||||||
|
}
|
||||||
|
this.getConfig();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
publishBeta() {
|
||||||
|
return this._publishConfig(true).then(res => {
|
||||||
|
if (res) {
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
betaPublishSuccess: true,
|
||||||
|
tabActiveKey: 'beta',
|
||||||
|
},
|
||||||
|
() => this.getConfig(true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
stopBeta() {
|
||||||
|
const { locale } = this.props;
|
||||||
|
const { dataId, group } = this.state.form;
|
||||||
|
return request
|
||||||
|
.delete('v1/cs/configs', {
|
||||||
|
params: {
|
||||||
|
beta: true,
|
||||||
|
dataId,
|
||||||
|
group,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
isBeta: false,
|
||||||
|
betaPublishSuccess: false,
|
||||||
|
tabActiveKey: '',
|
||||||
|
},
|
||||||
|
() => this.getConfig()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
changeForm(item, cb) {
|
||||||
|
const { form } = this.state;
|
||||||
|
this.setState({ form: { ...form, ...item } }, () => {
|
||||||
|
if (cb) {
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfigTags(tags) {
|
||||||
|
const { tagDataSource } = this.state;
|
||||||
|
const lastTag = tags[tags.length - 1];
|
||||||
|
if (tagDataSource.indexOf(lastTag) < 0) {
|
||||||
|
this.setState({ tagDataSource: [...tagDataSource, lastTag] });
|
||||||
|
}
|
||||||
|
if (tags.length > 5) {
|
||||||
|
tags.pop();
|
||||||
|
}
|
||||||
|
tags.forEach((v, i) => {
|
||||||
|
if (v.indexOf(',') !== -1 || v.indexOf('=') !== -1) {
|
||||||
|
tags.splice(i, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.changeForm({ config_tags: tags });
|
||||||
|
}
|
||||||
|
|
||||||
|
goBack() {
|
||||||
|
const serverId = getParams('serverId') || '';
|
||||||
|
const tenant = getParams('namespace');
|
||||||
|
const searchGroup = getParams('searchGroup') || '';
|
||||||
|
const searchDataId = getParams('searchDataId') || '';
|
||||||
|
this.props.history.push(
|
||||||
|
`/configurationManagement?serverId=${serverId}&group=${searchGroup}&dataId=${searchDataId}&namespace=${tenant}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getConfig(beta = false) {
|
||||||
|
const namespace = getParams('namespace');
|
||||||
|
const { dataId, group } = this.state.form;
|
||||||
|
return request
|
||||||
|
.get('v1/cs/configs', {
|
||||||
|
params: {
|
||||||
|
dataId,
|
||||||
|
group,
|
||||||
|
beta,
|
||||||
|
show: 'all',
|
||||||
|
namespaceId: namespace,
|
||||||
|
tenant: namespace,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
const { type, content, configTags } = res;
|
||||||
|
this.changeForm({ ...res, config_tags: configTags ? configTags.split(',') : [] });
|
||||||
|
this.initMoacoEditor(type, content);
|
||||||
|
this.codeVal = content;
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
validation() {
|
||||||
|
const { locale } = this.props;
|
||||||
|
const { form } = this.state;
|
||||||
|
const { dataId, group } = form;
|
||||||
|
if (!dataId) {
|
||||||
|
this.setState({
|
||||||
|
dataIdError: {
|
||||||
|
validateState: 'error',
|
||||||
|
help: locale.recipientFrom,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!group) {
|
||||||
|
this.setState({
|
||||||
|
groupError: {
|
||||||
|
validateState: 'error',
|
||||||
|
help: locale.homeApplication,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
loading,
|
||||||
|
betaIps,
|
||||||
|
openAdvancedSettings,
|
||||||
|
isBeta,
|
||||||
|
isNewConfig,
|
||||||
|
betaPublishSuccess,
|
||||||
|
form,
|
||||||
|
tagDataSource,
|
||||||
|
tabActiveKey,
|
||||||
|
dataIdError = {},
|
||||||
|
groupError = {},
|
||||||
|
} = this.state;
|
||||||
|
const { locale = {} } = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="config-editor">
|
||||||
|
<Loading
|
||||||
|
shape="flower"
|
||||||
|
style={{ position: 'relative', width: '100%' }}
|
||||||
|
visible={loading}
|
||||||
|
tip="Loading..."
|
||||||
|
color="#333"
|
||||||
|
>
|
||||||
|
<h1 className="func-title">
|
||||||
|
<div>{locale.toedit}</div>
|
||||||
|
</h1>
|
||||||
|
{betaPublishSuccess && (
|
||||||
|
<Tab shape="wrapped" activeKey={tabActiveKey} onChange={key => this.clickTab(key)}>
|
||||||
|
{TAB_LIST.map(key => (
|
||||||
|
<Tab.Item title={locale[key]} key={key}>
|
||||||
|
{locale[key]}
|
||||||
|
</Tab.Item>
|
||||||
|
))}
|
||||||
|
</Tab>
|
||||||
|
)}
|
||||||
|
<Form className="form">
|
||||||
|
<Form.Item label="Data ID:" required {...dataIdError}>
|
||||||
|
<Input
|
||||||
|
value={form.dataId}
|
||||||
|
onChange={dataId =>
|
||||||
|
this.changeForm({ dataId }, () => this.setState({ dataIdError: {} }))
|
||||||
|
}
|
||||||
|
disabled={!isNewConfig}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="Group:" required {...groupError}>
|
||||||
|
<Input
|
||||||
|
value={form.group}
|
||||||
|
onChange={group =>
|
||||||
|
this.changeForm({ group }, () => this.setState({ groupError: {} }))
|
||||||
|
}
|
||||||
|
disabled={!isNewConfig}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label=" ">
|
||||||
|
<div
|
||||||
|
className="switch"
|
||||||
|
onClick={() => this.setState({ openAdvancedSettings: !openAdvancedSettings })}
|
||||||
|
>
|
||||||
|
{openAdvancedSettings ? locale.collapse : locale.groupNotEmpty}
|
||||||
|
</div>
|
||||||
|
</Form.Item>
|
||||||
|
{openAdvancedSettings && (
|
||||||
|
<>
|
||||||
|
<Form.Item label={locale.tags}>
|
||||||
|
<Select
|
||||||
|
size="medium"
|
||||||
|
hasArrow
|
||||||
|
autoWidth
|
||||||
|
mode="tag"
|
||||||
|
filterLocal
|
||||||
|
value={form.config_tags}
|
||||||
|
dataSource={tagDataSource}
|
||||||
|
onChange={config_tags => this.setConfigTags(config_tags)}
|
||||||
|
hasClear
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={locale.targetEnvironment}>
|
||||||
|
<Input value={form.appName} onChange={appName => this.changeForm({ appName })} />
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<Form.Item label={locale.description}>
|
||||||
|
<Input.TextArea
|
||||||
|
value={form.desc}
|
||||||
|
aria-label="TextArea"
|
||||||
|
onChange={desc => this.changeForm({ desc })}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
{!isNewConfig && tabActiveKey !== 'production' && (
|
||||||
|
<Form.Item label={locale.betaPublish}>
|
||||||
|
{!betaPublishSuccess && (
|
||||||
|
<Checkbox checked={isBeta} onChange={isBeta => this.setState({ isBeta })}>
|
||||||
|
{locale.betaSwitchPrompt}
|
||||||
|
</Checkbox>
|
||||||
|
)}
|
||||||
|
{isBeta && (
|
||||||
|
<Input.TextArea
|
||||||
|
aria-label="TextArea"
|
||||||
|
placeholder="127.0.0.1,127.0.0.2"
|
||||||
|
onChange={betaIps => this.setState({ betaIps })}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
)}
|
||||||
|
<Form.Item label={locale.format}>
|
||||||
|
<Radio.Group
|
||||||
|
value={form.type}
|
||||||
|
onChange={type => {
|
||||||
|
this.initMoacoEditor(type, '');
|
||||||
|
this.changeForm({ type });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{LANGUAGE_LIST.map(item => (
|
||||||
|
<Radio value={item.value} key={item.value}>
|
||||||
|
{item.label}
|
||||||
|
</Radio>
|
||||||
|
))}
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={
|
||||||
|
<div className="help-label">
|
||||||
|
<span>{locale.configcontent}</span>
|
||||||
|
<Balloon
|
||||||
|
trigger={<Icon type="help" size="small" />}
|
||||||
|
align="t"
|
||||||
|
style={{ marginRight: 5 }}
|
||||||
|
triggerType="hover"
|
||||||
|
>
|
||||||
|
<p>{locale.escExit}</p>
|
||||||
|
<p>{locale.releaseBeta}</p>
|
||||||
|
</Balloon>
|
||||||
|
<span>:</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div style={{ clear: 'both', height: 300 }} id="container" />
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
<Row>
|
||||||
|
<Col span="24" className="button-list">
|
||||||
|
{isBeta && betaPublishSuccess && tabActiveKey !== 'production' && (
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
type="primary"
|
||||||
|
onClick={() =>
|
||||||
|
this.stopBeta().then(() => {
|
||||||
|
this.successDialog.current.getInstance().openDialog({
|
||||||
|
title: <div>{locale.stopPublishBeta}</div>,
|
||||||
|
isok: true,
|
||||||
|
...form,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{locale.stopPublishBeta}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{isBeta && tabActiveKey !== 'production' && (
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
type="primary"
|
||||||
|
disabled={!betaIps}
|
||||||
|
onClick={() => this.openDiff('publishBeta')}
|
||||||
|
>
|
||||||
|
{locale.release}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
type="primary"
|
||||||
|
disabled={tabActiveKey === 'production'}
|
||||||
|
onClick={() => this.openDiff('publish')}
|
||||||
|
>
|
||||||
|
{locale.publish}
|
||||||
|
</Button>
|
||||||
|
<Button size="large" type="normal" onClick={() => this.goBack()}>
|
||||||
|
{locale.back}
|
||||||
|
</Button>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<DiffEditorDialog
|
||||||
|
ref={this.diffEditorDialog}
|
||||||
|
publishConfig={() => {
|
||||||
|
this[this.diffcb]();
|
||||||
|
let title = locale.toedit;
|
||||||
|
if (isNewConfig) {
|
||||||
|
title = locale.newConfigEditor;
|
||||||
|
}
|
||||||
|
if (this.diffcb === 'publishBeta') {
|
||||||
|
title = locale.betaPublish;
|
||||||
|
}
|
||||||
|
if (this.diffcb === 'publish' && tabActiveKey === 'beta') {
|
||||||
|
title = locale.stopPublishBeta;
|
||||||
|
this.stopBeta();
|
||||||
|
}
|
||||||
|
this.successDialog.current.getInstance().openDialog({
|
||||||
|
title: <div>{title}</div>,
|
||||||
|
isok: true,
|
||||||
|
...form,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<SuccessDialog ref={this.successDialog} />
|
||||||
|
</Loading>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ConfigEditor;
|
@ -11,6 +11,6 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ConfigEditor from './ConfigEditor';
|
import ConfigEditor from './NewConfigEditor';
|
||||||
|
|
||||||
export default ConfigEditor;
|
export default ConfigEditor;
|
||||||
|
@ -10,3 +10,64 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
.config-editor {
|
||||||
|
padding: 10px;
|
||||||
|
.func-title {
|
||||||
|
overflow: hidden;
|
||||||
|
height: 50px;
|
||||||
|
width: 100%;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 9px;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 36px;
|
||||||
|
color: #73777a;
|
||||||
|
}
|
||||||
|
.form {
|
||||||
|
display: table;
|
||||||
|
.next-form-item {
|
||||||
|
display: table-row;
|
||||||
|
.next-form-item-label {
|
||||||
|
white-space: nowrap;
|
||||||
|
word-break: keep-all;
|
||||||
|
}
|
||||||
|
.next-form-item-control,
|
||||||
|
.next-select {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.next-form-item-label,
|
||||||
|
.next-form-item-control {
|
||||||
|
display: table-cell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.next-form-item-control {
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
|
.next-checkbox-label {
|
||||||
|
color: #73777a;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
.next-radio-label {
|
||||||
|
color: #73777a;
|
||||||
|
}
|
||||||
|
.switch {
|
||||||
|
color: #33cde5;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.help-label > * {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.help-label > i {
|
||||||
|
color: #1dc11d;
|
||||||
|
margin: 0 0.25em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.button-list {
|
||||||
|
text-align: right;
|
||||||
|
button {
|
||||||
|
margin-left: 1em;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -866,7 +866,6 @@ class ConfigurationManagement extends React.Component {
|
|||||||
|
|
||||||
processImportAndCloneResult(ret, locale, confirm, isImport) {
|
processImportAndCloneResult(ret, locale, confirm, isImport) {
|
||||||
const resultCode = ret.code;
|
const resultCode = ret.code;
|
||||||
console.log(ret);
|
|
||||||
if (resultCode === 200) {
|
if (resultCode === 200) {
|
||||||
confirm.hide();
|
confirm.hide();
|
||||||
if (ret.data.failData && ret.data.failData.length > 0) {
|
if (ret.data.failData && ret.data.failData.length > 0) {
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -102,6 +102,20 @@ public class NamingMaintainService_ITCase {
|
|||||||
System.out.println(instances.get(0));
|
System.out.println(instances.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateInstanceWithDisable() throws NacosException {
|
||||||
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
|
map.put("netType", "external-update");
|
||||||
|
map.put("version", "2.0");
|
||||||
|
namingService.registerInstance(serviceName, instance);
|
||||||
|
instance.setMetadata(map);
|
||||||
|
instance.setEnabled(false);
|
||||||
|
namingMaintainService.updateInstance(serviceName, instance);
|
||||||
|
List<Instance> instances = namingService.getAllInstances(serviceName, true);
|
||||||
|
|
||||||
|
Assert.assertEquals(instances.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createAndUpdateService() throws NacosException {
|
public void createAndUpdateService() throws NacosException {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user