This commit is contained in:
LoadChange 2020-03-15 18:19:35 +08:00 committed by Asa
parent 76ca05edc1
commit 51ce42593b
7 changed files with 339 additions and 290 deletions

View File

@ -33,3 +33,5 @@ export const ROLE_LIST = 'ROLE_LIST';
export const PERMISSIONS_LIST = 'PERMISSIONS_LIST';
export const GET_NAMESPACES = 'GET_NAMESPACES';
export const GET_CONFIGURATION = 'GET_CONFIGURATION';

View File

@ -482,8 +482,13 @@ const request = (function(_global) {
// 处理后置中间件
config = handleMiddleWare.apply(this, [config, ...args, middlewareBackList]);
const { accessToken = '' } = JSON.parse(localStorage.token || '{}');
let token = {};
try {
token = JSON.parse(localStorage.token || '{}');
} catch (e) {
console.log(e);
}
const { accessToken = '' } = token;
const [url, paramsStr = ''] = config.url.split('?');
const params = paramsStr.split('&');
params.push(`accessToken=${accessToken}`);

View File

@ -39,15 +39,20 @@ import ShowCodeing from 'components/ShowCodeing';
import DeleteDialog from 'components/DeleteDialog';
import DashboardCard from './DashboardCard';
import { getParams, setParams, request, aliwareIntl } from '@/globalLib';
import axios from 'axios';
import { connect } from 'react-redux';
import { getConfigs } from '../../../reducers/configuration';
import './index.scss';
import { LANGUAGE_KEY } from '../../../constants';
const { Panel } = Collapse;
const { Row, Col } = Grid;
const configsTableSelected = new Map();
@connect(
state => ({
configurations: state.configuration.configurations,
}),
{ getConfigs }
)
@ConfigProvider.config
class ConfigurationManagement extends React.Component {
static displayName = 'ConfigurationManagement';
@ -273,12 +278,22 @@ class ConfigurationManagement extends React.Component {
const self = this;
this.tenant = getParams('namespace') || ''; // 为当前实例保存tenant参数
this.serverId = getParams('serverId') || '';
const params = {
dataId: this.dataId,
group: this.group,
appName: this.appName,
config_tags: this.state.config_tags.join(','),
pageNo,
pageSize: this.state.pageSize,
};
let urlPrefix = '';
if (this.dataId.indexOf('*') !== -1 || this.group.indexOf('*') !== -1) {
urlPrefix = 'v1/cs/configs?search=blur';
params.search = 'blur';
} else {
urlPrefix = 'v1/cs/configs?search=accurate';
params.search = 'accurate';
}
this.setState({ loading: true });
this.props.getConfigs(params).then(() => this.setState({ loading: false }));
request({
url: `${urlPrefix}&dataId=${this.dataId}&group=${this.group}&appName=${
@ -430,7 +445,7 @@ class ConfigurationManagement extends React.Component {
changePage(value, e) {
this.setState(
{
isPageEnter: e.keyCode && e.keyCode === 13,
isPageEnter: e && e.keyCode && e.keyCode === 13,
currentPage: value,
},
() => this.getData(value, false)
@ -498,6 +513,7 @@ class ConfigurationManagement extends React.Component {
setConfigTags(value) {
this.setState({
config_tags: value,
tagLst: value,
});
}
@ -615,7 +631,7 @@ class ConfigurationManagement extends React.Component {
<Collapse style={{ width: '500px' }}>
{'failedItems' in res.data && res.data.failedItems.length > 0 ? (
<Panel title={locale.failedEntry + res.data.failedItems.length}>
<Table dataSource={res.data.failedItems} fixedHeader maxBodyHeight={400}>
<Table dataSource={res.data.failedItems} fixedHeader>
<Table.Column title={'Data ID'} dataIndex={'dataId'} />
<Table.Column title={'Group'} dataIndex={'group'} />
</Table>
@ -625,7 +641,7 @@ class ConfigurationManagement extends React.Component {
)}
{'succeededItems' in res.data && res.data.succeededItems.length > 0 ? (
<Panel title={locale.successfulEntry + res.data.succeededItems.length}>
<Table dataSource={res.data.succeededItems} fixedHeader maxBodyHeight={400}>
<Table dataSource={res.data.succeededItems} fixedHeader>
<Table.Column title={'Data ID'} dataIndex={'dataId'} />
<Table.Column title={'Group'} dataIndex={'group'} />
</Table>
@ -635,7 +651,7 @@ class ConfigurationManagement extends React.Component {
)}
{'unprocessedItems' in res.data && res.data.unprocessedItems.length > 0 ? (
<Panel title={locale.unprocessedEntry + res.data.unprocessedItems.length}>
<Table dataSource={res.data.unprocessedItems} fixedHeader maxBodyHeight={400}>
<Table dataSource={res.data.unprocessedItems} fixedHeader>
<Table.Column title={'Data ID'} dataIndex={'dataId'} />
<Table.Column title={'Group'} dataIndex={'group'} />
</Table>
@ -844,7 +860,7 @@ class ConfigurationManagement extends React.Component {
title: locale.cloningConfiguration,
footer: false,
content: (
<div>
<>
<div style={{ marginBottom: 10 }}>
<span style={{ color: '#999', marginRight: 5 }}>{locale.source}</span>
<span style={{ color: '#49D2E7' }}>{self.state.nownamespace_name} </span>|{' '}
@ -962,25 +978,19 @@ class ConfigurationManagement extends React.Component {
</Button>
</div>
<div style={{ marginBottom: 10 }}>
<span style={{ color: '#00AA00', 'font-weight': 'bold' }}>
<span style={{ color: '#00AA00', fontWeight: 'bold' }}>
{locale.cloneEditableTitle}
</span>
</div>
<div>
<Table dataSource={editableTableData}>
<Table.Column
title="Data Id"
dataIndex="dataId"
cell={renderEditableTableCellDataId}
/>
<Table.Column
title="Group"
dataIndex="group"
cell={renderEditableTableCellGroup}
/>
</Table>
</div>
</div>
<Table dataSource={editableTableData}>
<Table.Column
title="Data Id"
dataIndex="dataId"
cell={renderEditableTableCellDataId}
/>
<Table.Column title="Group" dataIndex="group" cell={renderEditableTableCellGroup} />
</Table>
</>
),
});
},
@ -1167,272 +1177,259 @@ class ConfigurationManagement extends React.Component {
}
render() {
const { locale = {} } = this.props;
const { locale = {}, configurations = {} } = this.props;
return (
<>
<BatchHandle ref={ref => (this.batchHandle = ref)} />
<Loading
shape={'flower'}
style={{ position: 'relative', width: '100%', overflow: 'auto' }}
visible={this.state.loading}
tip={'Loading...'}
color={'#333'}
>
<div className={this.state.hasdash ? 'dash-page-container' : ''}>
<div
className={this.state.hasdash ? 'dash-left-container' : ''}
style={{ position: 'relative' }}
>
<div style={{ display: this.inApp ? 'none' : 'block', marginTop: -15 }}>
<RegionGroup
namespaceCallBack={this.cleanAndGetData.bind(this)}
setNowNameSpace={this.setNowNameSpace.bind(this)}
/>
</div>
<div
style={{
display: this.inApp ? 'none' : 'block',
position: 'relative',
width: '100%',
overflow: 'hidden',
height: '40px',
}}
>
<h3
style={{
height: 30,
width: '100%',
lineHeight: '30px',
padding: 0,
margin: 0,
paddingLeft: 10,
borderLeft: '3px solid #09c',
color: '#ccc',
fontSize: '12px',
}}
>
<span style={{ fontSize: '14px', color: '#000', marginRight: 8 }}>
{locale.configurationManagement8}
</span>
<span style={{ fontSize: '14px', color: '#000', marginRight: 8 }}>|</span>
<span style={{ fontSize: '14px', color: '#000', marginRight: 8 }}>
{this.state.nownamespace_name}
</span>
<span style={{ fontSize: '14px', color: '#000', marginRight: 18 }}>
{this.state.nownamespace_id}
</span>
{locale.queryResults}
<strong style={{ fontWeight: 'bold' }}> {this.state.total} </strong>
{locale.articleMeetRequirements}
</h3>
<div
style={{ position: 'absolute', textAlign: 'right', zIndex: 2, right: 0, top: 0 }}
/>
</div>
<div
style={{
position: 'relative',
marginTop: 10,
height: this.state.isAdvancedQuery ? 'auto' : 42,
overflow: 'hidden',
}}
>
<Form inline>
<Form.Item label={'Data ID:'}>
<Input
htmlType={'text'}
placeholder={locale.fuzzyd}
style={{ width: 200 }}
value={this.state.dataId}
onChange={this.getDataId.bind(this)}
/>
</Form.Item>
<Form.Item label={'Group:'}>
<Select.AutoComplete
style={{ width: 200 }}
size={'medium'}
placeholder={locale.fuzzyg}
dataSource={this.state.groups}
value={this.state.group}
onChange={this.setGroup.bind(this)}
hasClear
/>
</Form.Item>
<Form.Item label={''}>
<Button
type={'primary'}
style={{ marginRight: 10 }}
onClick={this.selectAll.bind(this)}
data-spm-click={'gostr=/aliyun;locaid=dashsearch'}
>
{locale.query}
</Button>
</Form.Item>
<Form.Item
style={
this.inApp
? { display: 'none' }
: { verticalAlign: 'middle', marginTop: 0, marginLeft: 10 }
}
>
<div
style={{ color: '#33cde5', fontSize: 12, cursor: 'pointer' }}
onClick={this.changeAdvancedQuery}
>
<span style={{ marginRight: 5, lineHeight: '28px' }}>
{locale.advancedQuery9}
</span>
<Icon
type={
this.state.isAdvancedQuery ? 'arrow-up-filling' : 'arrow-down-filling'
}
size={'xs'}
/>
</div>
</Form.Item>
<Form.Item label={''}>
<Button
type={'primary'}
style={{ marginRight: 10 }}
onClick={this.exportData.bind(this)}
data-spm-click={'gostr=/aliyun;locaid=configsExport'}
>
{locale.export}
</Button>
</Form.Item>
<Form.Item label={''}>
<Button
type={'primary'}
style={{ marginRight: 10 }}
onClick={this.importData.bind(this)}
data-spm-click={'gostr=/aliyun;locaid=configsExport'}
>
{locale.import}
</Button>
</Form.Item>
<br />
<Form.Item
style={this.inApp ? { display: 'none' } : {}}
label={locale.application0}
>
<Input
htmlType={'text'}
placeholder={locale.app1}
style={{ width: 200 }}
value={this.state.appName}
onChange={this.setAppName.bind(this)}
/>
</Form.Item>
<Form.Item label={locale.tags}>
<Select
style={{ width: 200 }}
size={'medium'}
hasArrow
mode="tag"
filterLocal={false}
placeholder={locale.pleaseEnterTag}
dataSource={this.state.tagLst}
value={this.state.config_tags}
onChange={this.setConfigTags.bind(this)}
hasClear
/>
</Form.Item>
</Form>
<div style={{ position: 'absolute', right: 10, top: 4 }}>
<Icon
type={'add'}
size={'medium'}
style={{
color: 'black',
marginRight: 0,
verticalAlign: 'middle',
cursor: 'pointer',
backgroundColor: '#eee',
border: '1px solid #ddd',
padding: '3px 6px',
}}
onClick={this.chooseEnv.bind(this)}
/>
</div>
</div>
<div>
<Table
dataSource={this.state.dataSource}
locale={{ empty: locale.pubNoData }}
fixedHeader
maxBodyHeight={400}
ref={'dataTable'}
rowSelection={this.state.rowSelection}
>
<Table.Column title={'Data Id'} dataIndex={'dataId'} />
<Table.Column title={'Group'} dataIndex={'group'} />
{!this.inApp ? (
<Table.Column title={locale.application} dataIndex={'appName'} />
) : (
<div />
)}
<Table.Column title={locale.operation} cell={this.renderCol.bind(this)} />
</Table>
{this.state.dataSource.length > 0 && (
<div style={{ marginTop: 10, overflow: 'hidden' }}>
<div style={{ float: 'left' }}>
<Button
type={'primary'}
warning
style={{ marginRight: 10 }}
onClick={this.multipleSelectionDeletion.bind(this)}
data-spm-click={'gostr=/aliyun;locaid=configsDelete'}
>
{locale.deleteAction}
</Button>
<Button
type={'primary'}
style={{ marginRight: 10 }}
onClick={this.exportSelectedData.bind(this)}
data-spm-click={'gostr=/aliyun;locaid=configsExport'}
>
{locale.exportSelected}
</Button>
<Button
type={'primary'}
style={{ marginRight: 10 }}
onClick={this.cloneSelectedDataConfirm.bind(this)}
data-spm-click={'gostr=/aliyun;locaid=configsClone'}
>
{locale.clone}
</Button>
</div>
<div style={{ float: 'right' }}>
<Pagination
style={{ float: 'right' }}
pageSizeList={[10, 20, 30]}
pageSizeSelector={'dropdown'}
onPageSizeChange={this.handlePageSizeChange.bind(this)}
current={this.state.currentPage}
total={this.state.total}
pageSize={this.state.pageSize}
onChange={this.changePage.bind(this)}
/>
</div>
</div>
)}
</div>
<ShowCodeing ref={this.showcode} />
<DeleteDialog ref={this.deleteDialog} />
<div className={this.state.hasdash ? 'dash-page-container' : ''}>
<div
className={this.state.hasdash ? 'dash-left-container' : ''}
style={{ position: 'relative' }}
>
<div style={{ display: this.inApp ? 'none' : 'block', marginTop: -15 }}>
<RegionGroup
namespaceCallBack={this.cleanAndGetData.bind(this)}
setNowNameSpace={this.setNowNameSpace.bind(this)}
/>
</div>
{this.state.hasdash && (
<div
className={'dash-right-container'}
style={{ overflow: 'auto', height: window.innerHeight - 40 }}
<div
style={{
display: this.inApp ? 'none' : 'block',
position: 'relative',
width: '100%',
overflow: 'hidden',
height: '40px',
}}
>
<h3
style={{
height: 30,
width: '100%',
lineHeight: '30px',
padding: 0,
margin: 0,
paddingLeft: 10,
borderLeft: '3px solid #09c',
color: '#ccc',
fontSize: '12px',
}}
>
{this.state.contentList.map((v, i) => (
<DashboardCard data={v} height={'auto'} key={`show${i}`} />
))}
<span style={{ fontSize: '14px', color: '#000', marginRight: 8 }}>
{locale.configurationManagement8}
</span>
<span style={{ fontSize: '14px', color: '#000', marginRight: 8 }}>|</span>
<span style={{ fontSize: '14px', color: '#000', marginRight: 8 }}>
{this.state.nownamespace_name}
</span>
<span style={{ fontSize: '14px', color: '#000', marginRight: 18 }}>
{this.state.nownamespace_id}
</span>
{locale.queryResults}
<strong style={{ fontWeight: 'bold' }}> {configurations.totalCount} </strong>
{locale.articleMeetRequirements}
</h3>
<div
style={{ position: 'absolute', textAlign: 'right', zIndex: 2, right: 0, top: 0 }}
/>
</div>
<div
style={{
position: 'relative',
marginTop: 10,
height: this.state.isAdvancedQuery ? 'auto' : 42,
overflow: 'hidden',
}}
>
<Form inline>
<Form.Item label={'Data ID:'}>
<Input
htmlType={'text'}
placeholder={locale.fuzzyd}
style={{ width: 200 }}
value={this.state.dataId}
onChange={this.getDataId.bind(this)}
/>
</Form.Item>
<Form.Item label={'Group:'}>
<Select.AutoComplete
style={{ width: 200 }}
size={'medium'}
placeholder={locale.fuzzyg}
dataSource={this.state.groups}
value={this.state.group}
onChange={this.setGroup.bind(this)}
hasClear
/>
</Form.Item>
<Form.Item label={''}>
<Button
type={'primary'}
style={{ marginRight: 10 }}
onClick={this.selectAll.bind(this)}
data-spm-click={'gostr=/aliyun;locaid=dashsearch'}
>
{locale.query}
</Button>
</Form.Item>
<Form.Item
style={
this.inApp
? { display: 'none' }
: { verticalAlign: 'middle', marginTop: 0, marginLeft: 10 }
}
>
<div
style={{ color: '#33cde5', fontSize: 12, cursor: 'pointer' }}
onClick={this.changeAdvancedQuery}
>
<span style={{ marginRight: 5, lineHeight: '28px' }}>
{locale.advancedQuery9}
</span>
<Icon
type={this.state.isAdvancedQuery ? 'arrow-up-filling' : 'arrow-down-filling'}
size={'xs'}
/>
</div>
</Form.Item>
<Form.Item label={''}>
<Button
type={'primary'}
style={{ marginRight: 10 }}
onClick={this.exportData.bind(this)}
data-spm-click={'gostr=/aliyun;locaid=configsExport'}
>
{locale.export}
</Button>
</Form.Item>
<Form.Item label={''}>
<Button
type={'primary'}
style={{ marginRight: 10 }}
onClick={this.importData.bind(this)}
data-spm-click={'gostr=/aliyun;locaid=configsExport'}
>
{locale.import}
</Button>
</Form.Item>
<br />
<Form.Item
style={this.inApp ? { display: 'none' } : {}}
label={locale.application0}
>
<Input
htmlType={'text'}
placeholder={locale.app1}
style={{ width: 200 }}
value={this.state.appName}
onChange={this.setAppName.bind(this)}
/>
</Form.Item>
<Form.Item label={locale.tags}>
<Select
style={{ width: 200 }}
size="medium"
hasArrow
mode="tag"
placeholder={locale.pleaseEnterTag}
dataSource={this.state.tagLst}
value={this.state.config_tags}
onChange={this.setConfigTags.bind(this)}
showSearch
onSearch={val => {
const { tagLst } = this.state;
if (!tagLst.includes(val)) {
this.setState({ tagLst: tagLst.concat(val) });
}
}}
hasClear
/>
</Form.Item>
</Form>
<div style={{ position: 'absolute', right: 10, top: 4 }}>
<Icon
type="add"
size="medium"
style={{
color: 'black',
marginRight: 0,
verticalAlign: 'middle',
cursor: 'pointer',
backgroundColor: '#eee',
border: '1px solid #ddd',
padding: '3px 6px',
}}
onClick={this.chooseEnv.bind(this)}
/>
</div>
</div>
<Table
className="configuration-table"
dataSource={configurations.pageItems}
locale={{ empty: locale.pubNoData }}
ref="dataTable"
loading={this.state.loading}
rowSelection={this.state.rowSelection}
>
<Table.Column title={'Data Id'} dataIndex={'dataId'} />
<Table.Column title={'Group'} dataIndex={'group'} />
{!this.inApp && <Table.Column title={locale.application} dataIndex="appName" />}
<Table.Column title={locale.operation} cell={this.renderCol.bind(this)} />
</Table>
{configurations.totalCount && (
<>
<div style={{ float: 'left' }}>
<Button
type={'primary'}
warning
style={{ marginRight: 10 }}
onClick={this.multipleSelectionDeletion.bind(this)}
data-spm-click={'gostr=/aliyun;locaid=configsDelete'}
>
{locale.deleteAction}
</Button>
<Button
type={'primary'}
style={{ marginRight: 10 }}
onClick={this.exportSelectedData.bind(this)}
data-spm-click={'gostr=/aliyun;locaid=configsExport'}
>
{locale.exportSelected}
</Button>
<Button
type={'primary'}
style={{ marginRight: 10 }}
onClick={this.cloneSelectedDataConfirm.bind(this)}
data-spm-click={'gostr=/aliyun;locaid=configsClone'}
>
{locale.clone}
</Button>
</div>
<Pagination
style={{ float: 'right' }}
pageSizeList={[10, 20, 30]}
pageSizePosition="start"
pageSizeSelector="dropdown"
popupProps={{ align: 'bl tl' }}
onPageSizeChange={val => this.handlePageSizeChange(val)}
current={this.state.currentPage}
total={configurations.totalCount}
pageSize={this.state.pageSize}
onChange={this.changePage.bind(this)}
/>
</>
)}
<ShowCodeing ref={this.showcode} />
<DeleteDialog ref={this.deleteDialog} />
</div>
</Loading>
{this.state.hasdash && (
<div className="dash-right-container">
{this.state.contentList.map((v, i) => (
<DashboardCard data={v} height={'auto'} key={`show${i}`} />
))}
</div>
)}
</div>
</>
);
}

View File

@ -11,6 +11,9 @@
* limitations under the License.
*/
.next-pagination-size-selector{
.next-pagination-size-selector {
position: static !important;
}
.configuration-table {
margin-bottom: 20px;
}

View File

@ -0,0 +1,35 @@
/*
* 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 request from '../utils/request';
import { GET_CONFIGURATION } from '../constants';
const initialState = {
configurations: [],
};
const getConfigs = params => dispatch =>
request
.get('v1/cs/configs', { params })
.then(data => dispatch({ type: GET_CONFIGURATION, data }));
export default (state = initialState, action) => {
switch (action.type) {
case GET_CONFIGURATION:
return { ...state, configurations: action.data };
default:
return state;
}
};
export { getConfigs };

View File

@ -16,5 +16,6 @@ import base from './base';
import subscribers from './subscribers';
import authority from './authority';
import namespace from './namespace';
import configuration from './configuration';
export default { locale, base, subscribers, authority, namespace };
export default { locale, base, subscribers, authority, namespace, configuration };

View File

@ -17,7 +17,13 @@ const request = () => {
config.params = {};
}
if (!url.includes('auth/users/login')) {
const { accessToken = '' } = JSON.parse(localStorage.token || '{}');
let token = {};
try {
token = JSON.parse(localStorage.token || '{}');
} catch (e) {
console.log(e);
}
const { accessToken = '' } = token;
config.params.accessToken = accessToken;
config.headers = Object.assign({}, headers, { accessToken });
}