Merge pull request #2324 from loadchange/develop_1.2.0

Develop 1.2.0
This commit is contained in:
Peter Zhu 2020-01-28 11:22:47 +08:00 committed by GitHub
commit 880ba721b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 285 additions and 146 deletions

View File

@ -30,6 +30,7 @@
"generator-star-spacing": "off",
"wrap-iife": "off",
"arrow-parens": "off",
"indent": "off"
"indent": "off",
"comma-dangle": "off"
}
}

View File

@ -47,6 +47,7 @@
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-prettier": "^3.0.0",
"eslint-plugin-react": "^7.17.0",
"eslint-plugin-react-hooks": "^2.3.0",
"file-loader": "^5.0.2",
"html-webpack-plugin": "^3.2.0",
"husky": "^3.1.0",

View File

@ -125,9 +125,7 @@ class RegionGroup extends React.Component {
? false
: window.location.search.indexOf('hideTopbar=') === -1,
},
() => {
this.setRegionWidth();
}
() => this.setRegionWidth()
);
}

View File

@ -31,3 +31,5 @@ export const USER_LIST = 'USER_LIST';
export const ROLE_LIST = 'ROLE_LIST';
export const PERMISSIONS_LIST = 'PERMISSIONS_LIST';
export const GET_NAMESPACES = 'GET_NAMESPACES';

View File

@ -512,6 +512,7 @@ const request = (function(_global) {
if (url.includes('password')) {
return;
}
localStorage.removeItem('token');
const base_url = url.split('#')[0];
window.location = `${base_url}#/login`;
}

View File

@ -22,10 +22,7 @@ import { changeLanguage } from '@/reducers/locale';
import './index.scss';
@withRouter
@connect(
state => ({ ...state.locale }),
{ changeLanguage }
)
@connect(state => ({ ...state.locale }), { changeLanguage })
@ConfigProvider.config
class Header extends React.Component {
static displayName = 'Header';
@ -56,10 +53,15 @@ class Header extends React.Component {
getUsername = () => {
const token = window.localStorage.getItem('token');
if (token) {
const base64Url = token.split('.')[1];
const [, base64Url = ''] = token.split('.');
const base64 = base64Url.replace('-', '+').replace('_', '/');
const parsedToken = JSON.parse(window.atob(base64));
return parsedToken.sub;
try {
const parsedToken = JSON.parse(window.atob(base64));
return parsedToken.sub;
} catch (e) {
delete localStorage.token;
location.reload();
}
}
return '';
};

View File

@ -30,10 +30,12 @@ class MainLayout extends React.Component {
static propTypes = {
locale: PropTypes.object,
location: PropTypes.object,
history: PropTypes.object,
version: PropTypes.any,
getState: PropTypes.func,
functionMode: PropTypes.string,
children: PropTypes.object,
};
componentDidMount() {
@ -97,20 +99,23 @@ class MainLayout extends React.Component {
className="nav-menu"
openMode="single"
>
{MenuData.map((subMenu, idx) =>
subMenu.children ? (
<SubMenu key={String(idx)} label={locale[subMenu.key]}>
{subMenu.children.map((item, i) => (
<Item
key={[idx, i].join('-')}
onClick={() => this.navTo(item.url)}
className={this.isCurrentPath(item.url)}
>
{locale[item.key]}
</Item>
))}
</SubMenu>
) : (
{MenuData.map((subMenu, idx) => {
if (subMenu.children) {
return (
<SubMenu key={String(idx)} label={locale[subMenu.key]}>
{subMenu.children.map((item, i) => (
<Item
key={[idx, i].join('-')}
onClick={() => this.navTo(item.url)}
className={this.isCurrentPath(item.url)}
>
{locale[item.key]}
</Item>
))}
</SubMenu>
);
}
return (
<Item
key={idx}
className={['first-menu', this.isCurrentPath(subMenu.url)]
@ -120,8 +125,8 @@ class MainLayout extends React.Component {
>
{locale[subMenu.key]}
</Item>
)
)}
);
})}
</Menu>
</>
)}

View File

@ -1,3 +1,5 @@
import { isJsonString } from '../utils/nacosutil';
const configurationMenu = {
key: 'configurationManagementVirtual',
children: [
@ -33,8 +35,8 @@ const authorityControlMenu = {
};
export default function(model) {
const { token } = localStorage;
const { globalAdmin } = JSON.parse(token || '{}');
const { token = '{}' } = localStorage;
const { globalAdmin } = isJsonString(token) ? JSON.parse(token) || {} : {};
return [
model === 'naming' ? undefined : configurationMenu,

View File

@ -523,17 +523,25 @@ const I18N_CONF = {
createUser: 'Create user',
username: 'Username',
password: 'Password',
rePassword: 'Repeat',
usernamePlaceholder: 'Please Enter Username',
passwordPlaceholder: 'Please Enter Password',
rePasswordPlaceholder: 'Please Enter Repeat Password',
usernameError: 'User name cannot be empty!',
passwordError: 'Password cannot be empty!',
rePasswordError: 'Repeat Password cannot be empty!',
rePasswordError2: 'Passwords are inconsistent!',
},
PasswordReset: {
resetPassword: 'Password Reset',
username: 'Username',
password: 'Password',
rePassword: 'Repeat',
passwordPlaceholder: 'Please Enter Password',
rePasswordPlaceholder: 'Please Enter Repeat Password',
passwordError: 'Password cannot be empty!',
rePasswordError: 'Repeat Password cannot be empty!',
rePasswordError2: 'Passwords are inconsistent!',
},
RolesManagement: {
roleManagement: 'Role management',
@ -568,12 +576,15 @@ const I18N_CONF = {
role: 'Role',
resource: 'Resource',
action: 'Action',
resourcePlaceholder: 'Please enter Resource',
resourcePlaceholder: 'Please select resources',
rolePlaceholder: 'Please enter Role',
actionPlaceholder: 'Please enter Action',
actionPlaceholder: 'Please select Action',
resourceError: 'Resource cannot be empty!',
roleError: 'Role cannot be empty!',
actionError: 'Action cannot be empty!',
readOnly: 'read only',
writeOnly: 'write only',
readWrite: 'Read and write',
},
};

View File

@ -520,17 +520,25 @@ const I18N_CONF = {
createUser: '创建用户',
username: '用户名',
password: '密码',
rePassword: '确认密码',
usernamePlaceholder: '请输入用户名',
passwordPlaceholder: '请输入密码',
rePasswordPlaceholder: '请输入确认密码',
usernameError: '用户名不能为空',
passwordError: '密码不能为空!',
rePasswordError: '确认密码不能为空!',
rePasswordError2: '两次输入密码不一致!',
},
PasswordReset: {
resetPassword: '密码重置',
username: '用户名',
password: '密码',
rePassword: '确认密码',
passwordError: '密码不能为空',
passwordPlaceholder: '请输入密码',
rePasswordPlaceholder: '请输入确认密码',
rePasswordError: '确认密码不能为空!',
rePasswordError2: '两次输入密码不一致!',
},
RolesManagement: {
roleManagement: '角色管理',
@ -565,12 +573,15 @@ const I18N_CONF = {
role: '角色名',
resource: '资源',
action: '动作',
resourcePlaceholder: '输入资源',
resourcePlaceholder: '选择资源',
rolePlaceholder: '请输入角色名',
actionPlaceholder: '输入动作',
actionPlaceholder: '选择动作',
resourceError: '资源不能为空',
roleError: '角色名不能为空!',
actionError: '动作不能为空!',
readOnly: '只读',
writeOnly: '只写',
readWrite: '读写',
},
};

View File

@ -13,15 +13,19 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Field, Form, Input, Dialog, ConfigProvider } from '@alifd/next';
import { Field, Form, Input, Select, Dialog, ConfigProvider } from '@alifd/next';
import { connect } from 'react-redux';
import { getNamespaces } from '../../../reducers/namespace';
const FormItem = Form.Item;
const { Option } = Select;
const formItemLayout = {
labelCol: { fixedSpan: 4 },
wrapperCol: { span: 19 },
};
@connect(state => ({ namespaces: state.namespace.namespaces }), { getNamespaces })
@ConfigProvider.config
class NewPermissions extends React.Component {
static displayName = 'NewPermissions';
@ -33,6 +37,10 @@ class NewPermissions extends React.Component {
visible: PropTypes.bool,
};
componentDidMount() {
this.props.getNamespaces();
}
check() {
const { locale } = this.props;
const errors = {
@ -55,7 +63,7 @@ class NewPermissions extends React.Component {
render() {
const { getError } = this.field;
const { visible, onOk, onCancel, locale } = this.props;
const { visible, onOk, onCancel, locale, namespaces } = this.props;
return (
<>
<Dialog
@ -76,10 +84,26 @@ class NewPermissions extends React.Component {
<Input name="role" trim placeholder={locale.rolePlaceholder} />
</FormItem>
<FormItem label={locale.resource} required help={getError('resource')}>
<Input name="resource" trim placeholder={locale.resourcePlaceholder} />
<Select
name="resource"
placeholder={locale.resourcePlaceholder}
style={{ width: '100%' }}
>
{namespaces.map(({ namespaceShowName }) => (
<Option value={namespaceShowName}>{namespaceShowName}</Option>
))}
</Select>
</FormItem>
<FormItem label={locale.action} required help={getError('action')}>
<Input name="action" trim placeholder={locale.actionPlaceholder} />
<Select
name="action"
placeholder={locale.actionPlaceholder}
style={{ width: '100%' }}
>
<Option value="r">{locale.readOnly}(r)</Option>
<Option value="w">{locale.writeOnly}(w)</Option>
<Option value="rw">{locale.readWrite}(rw)</Option>
</Select>
</FormItem>
</Form>
</Dialog>

View File

@ -89,9 +89,9 @@ class PermissionsManagement extends React.Component {
title: locale.deletePermission,
content: locale.deletePermissionTip,
onOk: () =>
deletePermission(record).then(() =>
this.setState({ pageNo: 1 }, () => this.getPermissions())
),
deletePermission(record).then(() => {
this.setState({ pageNo: 1 }, () => this.getPermissions());
}),
})
}
>

View File

@ -77,9 +77,12 @@ class RolesManagement extends React.Component {
<Table.Column title={locale.username} dataIndex="username" />
<Table.Column
title={locale.operation}
dataIndex="username"
cell={(value, index, record) => (
<>
dataIndex="role"
cell={(value, index, record) => {
if (value === 'GLOBAL_ADMIN') {
return null;
}
return (
<Button
type="primary"
warning
@ -88,16 +91,16 @@ class RolesManagement extends React.Component {
title: locale.deleteRole,
content: locale.deleteRoleTip,
onOk: () =>
deleteRole(record).then(() =>
this.setState({ pageNo: 1 }, () => this.getRoles())
),
deleteRole(record).then(() => {
this.setState({ pageNo: 1 }, () => this.getRoles());
}),
})
}
>
{locale.deleteRole}
</Button>
</>
)}
);
}}
/>
</Table>
{roles.totalCount > pageSize && (

View File

@ -32,6 +32,8 @@ class NewUser extends React.Component {
static propTypes = {
locale: PropTypes.object,
visible: PropTypes.bool,
onOk: PropTypes.func,
onCancel: PropTypes.func,
};
check() {
@ -39,6 +41,7 @@ class NewUser extends React.Component {
const errors = {
username: locale.usernameError,
password: locale.passwordError,
rePassword: locale.rePasswordError,
};
const vals = Object.keys(errors).map(key => {
const val = this.field.getValue(key);
@ -47,10 +50,15 @@ class NewUser extends React.Component {
}
return val;
});
if (vals.filter(v => v).length === 2) {
return vals;
if (vals.filter(v => v).length !== 3) {
return null;
}
return null;
const [password, rePassword] = ['password', 'rePassword'].map(k => this.field.getValue(k));
if (password !== rePassword) {
this.field.setError('rePassword', locale.rePasswordError2);
return null;
}
return vals;
}
render() {
@ -79,6 +87,13 @@ class NewUser extends React.Component {
<FormItem label={locale.password} required help={getError('password')}>
<Input name="password" htmlType="password" placeholder={locale.passwordPlaceholder} />
</FormItem>
<FormItem label={locale.rePassword} required help={getError('rePassword')}>
<Input
name="rePassword"
htmlType="password"
placeholder={locale.rePasswordPlaceholder}
/>
</FormItem>
</Form>
</Dialog>
</>

View File

@ -36,7 +36,10 @@ class PasswordReset extends React.Component {
check() {
const { locale } = this.props;
const errors = { password: locale.passwordError };
const errors = {
password: locale.passwordError,
rePassword: locale.rePasswordError,
};
const vals = Object.keys(errors).map(key => {
const val = this.field.getValue(key);
if (!val) {
@ -44,10 +47,15 @@ class PasswordReset extends React.Component {
}
return val;
});
if (vals.filter(v => v).length === 1) {
return [this.props.username, ...vals];
if (vals.filter(v => v).length !== 2) {
return null;
}
return null;
const [password, rePassword] = ['password', 'rePassword'].map(k => this.field.getValue(k));
if (password !== rePassword) {
this.field.setError('rePassword', locale.rePasswordError2);
return null;
}
return [this.props.username, ...vals];
}
render() {
@ -76,6 +84,13 @@ class PasswordReset extends React.Component {
<FormItem label={locale.password} required help={getError('password')}>
<Input name="password" htmlType="password" placeholder={locale.passwordPlaceholder} />
</FormItem>
<FormItem label={locale.rePassword} required help={getError('rePassword')}>
<Input
name="rePassword"
htmlType="password"
placeholder={locale.rePasswordPlaceholder}
/>
</FormItem>
</Form>
</Dialog>
</>

View File

@ -101,9 +101,9 @@ class UserManagement extends React.Component {
title: locale.deleteUser,
content: locale.deleteUserTip,
onOk: () =>
deleteUser(username).then(() =>
this.setState({ pageNo: 1 }, () => this.getUsers())
),
deleteUser(username).then(() => {
this.setState({ pageNo: 1 }, () => this.getUsers());
}),
})
}
>

View File

@ -14,6 +14,7 @@
import React from 'react';
import { Button, ConfigProvider, Dialog, Field, Form, Input, Loading, Tab } from '@alifd/next';
import { getParams, request } from '../../../globalLib';
import { generateUrl } from '../../../utils/nacosutil';
import './index.scss';
import PropTypes from 'prop-types';
@ -140,9 +141,12 @@ class ConfigDetail extends React.Component {
goList() {
this.props.history.push(
`/configurationManagement?serverId=${this.serverId}&group=${this.searchGroup}&dataId=${
this.searchDataId
}&namespace=${this.tenant}`
generateUrl('/configurationManagement', {
serverId: this.serverId,
group: this.searchGroup,
dataId: this.searchDataId,
namespace: this.tenant,
})
);
}

View File

@ -14,6 +14,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { getParams } from '../../../globalLib';
import { generateUrl } from '../../../utils/nacosutil';
import request from '../../../utils/request';
import validateContent from 'utils/validateContent';
import SuccessDialog from '../../../components/SuccessDialog';
@ -96,7 +97,7 @@ class ConfigEditor extends React.Component {
dataId: getParams('dataId').trim(),
group,
},
() =>
() => {
this.getConfig(true).then(res => {
if (!res) {
this.getConfig();
@ -107,7 +108,8 @@ class ConfigEditor extends React.Component {
tabActiveKey: 'beta',
betaPublishSuccess: true,
});
})
});
}
);
} else {
if (group) {
@ -315,11 +317,11 @@ class ConfigEditor extends React.Component {
goBack() {
const serverId = getParams('serverId') || '';
const tenant = getParams('namespace');
const searchGroup = getParams('searchGroup') || '';
const searchDataId = getParams('searchDataId') || '';
const namespace = getParams('namespace');
const group = getParams('searchGroup') || '';
const dataId = getParams('searchDataId') || '';
this.props.history.push(
`/configurationManagement?serverId=${serverId}&group=${searchGroup}&dataId=${searchDataId}&namespace=${tenant}`
generateUrl('/configurationManagement', { serverId, group, dataId, namespace })
);
}

View File

@ -14,6 +14,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { getParams, request } from '../../../globalLib';
import { generateUrl } from '../../../utils/nacosutil';
import { Button, ConfigProvider, Dialog, Field, Form, Input } from '@alifd/next';
import './index.scss';
@ -96,11 +97,10 @@ class ConfigRollback extends React.Component {
}
goList() {
const tenant = getParams('namespace');
const namespace = getParams('namespace');
const { serverId, dataId, group } = this;
this.props.history.push(
`/historyRollback?serverId=${this.serverId}&group=${this.group}&dataId=${
this.dataId
}&namespace=${tenant}`
generateUrl('/historyRollback', { serverId, dataId, group, namespace })
);
}

View File

@ -16,6 +16,7 @@ import PropTypes from 'prop-types';
import { Button, Checkbox, ConfigProvider, Dialog, Field, Form, Input, Loading } from '@alifd/next';
import SuccessDialog from '../../../components/SuccessDialog';
import { getParams, request } from '../../../globalLib';
import { generateUrl } from '../../../utils/nacosutil';
import './index.scss';
@ -91,13 +92,9 @@ class ConfigSync extends React.Component {
const { locale = {} } = this.props;
this.tenant = getParams('namespace') || '';
this.serverId = getParams('serverId') || 'center';
let url = `/diamond-ops/configList/detail/serverId/${this.serverId}/dataId/${
this.dataId
}/group/${this.group}/tenant/${this.tenant}?id=`;
let url = `/diamond-ops/configList/detail/serverId/${this.serverId}/dataId/${this.dataId}/group/${this.group}/tenant/${this.tenant}?id=`;
if (this.tenant === 'global' || !this.tenant) {
url = `/diamond-ops/configList/detail/serverId/${this.serverId}/dataId/${this.dataId}/group/${
this.group
}?id=`;
url = `/diamond-ops/configList/detail/serverId/${this.serverId}/dataId/${this.dataId}/group/${this.group}?id=`;
}
request({
url,
@ -168,9 +165,7 @@ class ConfigSync extends React.Component {
request({
type: 'put',
contentType: 'application/json',
url: `/diamond-ops/configList/serverId/${this.serverId}/dataId/${payload.dataId}/group/${
payload.group
}?id=`,
url: `/diamond-ops/configList/serverId/${this.serverId}/dataId/${payload.dataId}/group/${payload.group}?id=`,
data: JSON.stringify(payload),
success(res) {
const _payload = {};
@ -193,7 +188,7 @@ class ConfigSync extends React.Component {
const dataId = this.field.getValue('dataId');
const gruop = this.field.getValue('group');
this.props.history.push(
`/diamond-ops/static/pages/config-sync/index.html?serverId=center&dataId=${dataId}&group=${gruop}`
generateUrl('/diamond-ops/static/pages/config-sync/index.html', { dataId, gruop })
);
}
@ -209,9 +204,8 @@ class ConfigSync extends React.Component {
}
goResult() {
this.props.history.push(
`/consistencyEfficacy?serverId=${this.serverId}&dataId=${this.dataId}&group=${this.group}`
);
const { serverId, dataId, group } = this;
this.props.history.push(generateUrl('/consistencyEfficacy', { serverId, dataId, group }));
}
openLoading() {

View File

@ -133,7 +133,8 @@ class ConfigurationManagement extends React.Component {
<div>
<div style={{ fontSize: '15px', lineHeight: '22px' }}>
{locale.ad}
<a href={'https://survey.aliyun.com/survey/k0BjJ2ARC'} target={'_blank'}>
{/* eslint-disable */}
<a href="https://survey.aliyun.com/survey/k0BjJ2ARC" target="_blank">
{locale.questionnaire2}
</a>
</div>
@ -438,21 +439,12 @@ class ConfigurationManagement extends React.Component {
isPageEnter: e.keyCode && e.keyCode === 13,
currentPage: value,
},
() => {
this.getData(value, false);
}
() => this.getData(value, false)
);
}
handlePageSizeChange(pageSize) {
this.setState(
{
pageSize,
},
() => {
this.changePage(1);
}
);
this.setState({ pageSize }, () => this.changePage(1));
}
onInputUpdate() {}
@ -690,7 +682,7 @@ class ConfigurationManagement extends React.Component {
}
exportData() {
let url = `v1/cs/configs?export=true&group=${this.group}&tenant=${getParams(
const url = `v1/cs/configs?export=true&group=${this.group}&tenant=${getParams(
'namespace'
)}&appName=${this.appName}&ids=&dataId=${this.dataId}`;
window.location.href = url;

View File

@ -46,10 +46,11 @@ class DashboardCard extends React.Component {
</strong>
<strong>
<span>
{/* eslint-disable */}
<a
style={{ marginLeft: 10, color: '#33cde5' }}
href={item.url}
target={'_blank'}
target="_blank"
>
{locale.viewDetails1}
</a>

View File

@ -81,9 +81,7 @@ class HistoryDetail extends React.Component {
goList() {
this.props.history.push(
`/historyRollback?serverId=${this.serverId}&group=${this.group}&dataId=${
this.dataId
}&namespace=${this.tenant}`
`/historyRollback?serverId=${this.serverId}&group=${this.group}&dataId=${this.dataId}&namespace=${this.tenant}`
);
}

View File

@ -133,9 +133,7 @@ class HistoryRollback extends React.Component {
beforeSend() {
self.openLoading();
},
url: `v1/cs/history?search=accurate&dataId=${this.dataId}&group=${
this.group
}&&pageNo=${pageNo}&pageSize=${this.state.pageSize}`,
url: `v1/cs/history?search=accurate&dataId=${this.dataId}&group=${this.group}&&pageNo=${pageNo}&pageSize=${this.state.pageSize}`,
success(data) {
if (data != null) {
self.setState({

View File

@ -16,6 +16,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import SuccessDialog from '../../../components/SuccessDialog';
import { getParams, setParams, request, aliwareIntl } from '../../../globalLib';
import { generateUrl } from '../../../utils/nacosutil';
import {
Balloon,
Button,
@ -192,9 +193,12 @@ class NewConfig extends React.Component {
this.tenant = getParams('namespace') || '';
this.serverId = getParams('serverId') || '';
this.props.history.push(
`/configurationManagement?serverId=${this.serverId}&group=${this.searchGroup}&dataId=${
this.searchDataId
}&namespace=${this.tenant}`
generateUrl('/configurationManagement', {
serverId: this.serverId,
group: this.searchGroup,
dataId: this.searchDataId,
namespace: this.tenant,
})
);
}

View File

@ -24,6 +24,13 @@ class Login extends React.Component {
this.field = new Field(this);
}
componentDidMount() {
if (localStorage.getItem('token')) {
const [baseUrl] = location.href.split('#');
location.href = `${baseUrl}#/`;
}
}
handleSubmit = () => {
const { locale = {} } = this.props;
this.field.validate((errors, values) => {
@ -35,11 +42,11 @@ class Login extends React.Component {
localStorage.setItem('token', JSON.stringify(res));
this.props.history.push('/');
})
.catch(() =>
.catch(() => {
Message.error({
content: locale.invalidUsernameOrPassword,
})
);
});
});
});
};

View File

@ -281,14 +281,6 @@ class NameSpace extends React.Component {
return <div>{name}</div>;
}
renderConfigCount(value, index, record) {
return (
<div>
{value} / {record.quota}
</div>
);
}
render() {
const { locale = {} } = this.props;
const {
@ -329,12 +321,7 @@ class NameSpace extends React.Component {
cell={this.renderName.bind(this)}
/>
<Table.Column title={namespaceNumber} dataIndex="namespace" />
<Table.Column
title={configuration}
dataIndex="configCount"
cell={this.renderConfigCount.bind(this)}
/>
<Table.Column title={configuration} dataIndex="configCount" />
<Table.Column
title={namespaceOperation}
dataIndex="time"
@ -343,7 +330,6 @@ class NameSpace extends React.Component {
</Table>
</div>
</div>
<NewNameSpace ref={this.newnamespace} getNameSpaces={this.getNameSpaces.bind(this)} />
<EditorNameSpace ref={this.editgroup} getNameSpaces={this.getNameSpaces.bind(this)} />
</Loading>

View File

@ -27,6 +27,7 @@ class Password extends React.Component {
static propTypes = {
locale: PropTypes.object,
history: PropTypes.object,
};
constructor(props) {

View File

@ -28,6 +28,7 @@ import {
Switch,
} from '@alifd/next';
import { request } from '../../../globalLib';
import { generateUrl } from '../../../utils/nacosutil';
import RegionGroup from '../../../components/RegionGroup';
import EditServiceDialog from '../ServiceDetail/EditServiceDialog';
import ShowServiceCodeing from 'components/ShowCodeing/ShowServiceCodeing';
@ -293,11 +294,12 @@ class ServiceList extends React.Component {
*/
<div>
<a
onClick={() =>
onClick={() => {
const { name, groupName } = record;
this.props.history.push(
`/serviceDetail?name=${record.name}&groupName=${record.groupName}`
)
}
generateUrl('/serviceDetail', { name, groupName })
);
}}
style={{ marginRight: 5 }}
>
{detail}

View File

@ -37,10 +37,7 @@ const FormItem = Form.Item;
const { Row, Col } = Grid;
const { Column } = Table;
@connect(
state => ({ subscriberData: state.subscribers }),
{ getSubscribers, removeSubscribers }
)
@connect(state => ({ subscriberData: state.subscribers }), { getSubscribers, removeSubscribers })
@ConfigProvider.config
class SubscriberList extends React.Component {
static displayName = 'SubscriberList';

View File

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

View File

@ -0,0 +1,39 @@
/*
* 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_NAMESPACES } from '../constants';
const initialState = {
namespaces: [],
};
const getNamespaces = params => dispatch =>
request.get('v1/console/namespaces', { params }).then(response => {
const { code, data } = response;
dispatch({
type: GET_NAMESPACES,
data: code === 200 ? data : [],
});
});
export default (state = initialState, action) => {
switch (action.type) {
case GET_NAMESPACES:
return { ...state, namespaces: action.data };
default:
return state;
}
};
export { getNamespaces };

View File

@ -46,3 +46,18 @@ export const getParameter = (search, name) => {
const [, value = ''] = hit.split('=');
return value;
};
export const isJsonString = str => {
try {
if (typeof JSON.parse(str) === 'object') {
return true;
}
} catch (e) {}
return false;
};
export const generateUrl = (url, params) => {
return [url, '?', Object.keys(params).map(key => [key, params[key].join('=')].join('&'))].join(
''
);
};

View File

@ -1,6 +1,7 @@
import axios from 'axios';
import qs from 'qs';
import { Message } from '@alifd/next';
import { browserHistory } from 'react-router';
// import { SUCCESS_RESULT_CODE } from '../constants';
const API_GENERAL_ERROR_MESSAGE = 'Request error, please try again later!';
@ -16,6 +17,7 @@ const request = () => {
if (!config.url.includes('auth/users/login')) {
const { accessToken = '' } = JSON.parse(localStorage.token || '{}');
config.params.accessToken = accessToken;
config.headers = Object.assign({}, config.headers, { accessToken });
}
if (['post', 'put'].includes(config.method)) {
config.data = qs.stringify(config.data);
@ -41,11 +43,16 @@ const request = () => {
error => {
if (error.response) {
const { data, status } = error.response;
if (status === 403) {
localStorage.removeItem('token');
const [baseUrl] = location.href.split('#');
location.href = `${baseUrl}#/login`;
return Promise.reject(error);
}
Message.error(data && typeof data === 'string' ? data : `HTTP ERROR: ${status}`);
} else {
Message.error(API_GENERAL_ERROR_MESSAGE);
}
return Promise.reject(error);
}
);

File diff suppressed because one or more lines are too long