Commit 34f49bfd authored by ddcat1115's avatar ddcat1115

Merge branch 'master' into v2

parents f1874684 6844c413
......@@ -5,11 +5,7 @@ class Authorized extends React.Component {
render() {
const { children, authority, noMatch = null } = this.props;
const childrenRender = typeof children === 'undefined' ? null : children;
return CheckPermissions(
authority,
childrenRender,
noMatch
);
return CheckPermissions(authority, childrenRender, noMatch);
}
}
......
......@@ -4,16 +4,28 @@ import Authorized from './Authorized';
class AuthorizedRoute extends React.Component {
render() {
const { component: Component, render, authority,
redirectPath, ...rest } = this.props;
const {
component: Component,
render,
authority,
redirectPath,
...rest
} = this.props;
return (
<Authorized
authority={authority}
noMatch={<Route {...rest} render={() => <Redirect to={{ pathname: redirectPath }} />} />}
noMatch={
<Route
{...rest}
render={() => <Redirect to={{ pathname: redirectPath }} />}
/>
}
>
<Route
{...rest}
render={props => (Component ? <Component {...props} /> : render(props))}
render={props =>
(Component ? <Component {...props} /> : render(props))
}
/>
</Authorized>
);
......
......@@ -3,7 +3,11 @@ import PromiseRender from './PromiseRender';
import { CURRENT } from './index';
function isPromise(obj) {
return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
return (
!!obj &&
(typeof obj === 'object' || typeof obj === 'function') &&
typeof obj.then === 'function'
);
}
/**
......@@ -38,9 +42,7 @@ const checkPermissions = (authority, currentAuthority, target, Exception) => {
// Promise 处理
if (isPromise(authority)) {
return () => (
<PromiseRender ok={target} error={Exception} promise={authority} />
);
return <PromiseRender ok={target} error={Exception} promise={authority} />;
}
// Function 处理
......
......@@ -3,25 +3,37 @@ import { Spin } from 'antd';
export default class PromiseRender extends React.PureComponent {
state = {
component: false,
component: null,
};
async componentDidMount() {
componentDidMount() {
const ok = this.checkIsInstantiation(this.props.ok);
const error = this.checkIsInstantiation(this.props.error);
this.props.promise
.then(() => {
this.setState({
component: this.props.ok,
component: ok,
});
})
.catch(() => {
this.setState({
component: this.props.error,
component: error,
});
});
}
// Determine whether the incoming component has been instantiated
// AuthorizedRoute is already instantiated
// Authorized render is already instantiated, children is no instantiated
// Secured is not instantiated
checkIsInstantiation = (target) => {
if (!React.isValidElement(target)) {
return target;
}
return () => target;
};
render() {
const C = this.state.component;
return C ? (
<C {...this.props} />
const Component = this.state.component;
return Component ? (
<Component {...this.props} />
) : (
<div
style={{
......
......@@ -9,6 +9,17 @@ const Exception403 = () => (
<Exception type="403" style={{ minHeight: 500, height: '80%' }} />
);
// Determine whether the incoming component has been instantiated
// AuthorizedRoute is already instantiated
// Authorized render is already instantiated, children is no instantiated
// Secured is not instantiated
const checkIsInstantiation = (target) => {
if (!React.isValidElement(target)) {
return target;
}
return () => target;
};
/**
* 用于判断是否拥有权限访问此view权限
* authority 支持传入 string ,funtion:()=>boolean|Promise
......@@ -38,11 +49,8 @@ const authorize = (authority, error) => {
throw new Error('authority is required');
}
return function decideAuthority(targer) {
return CheckPermissions(
authority,
targer,
classError || Exception403
);
const component = CheckPermissions(authority, targer, classError || Exception403);
return checkIsInstantiation(component);
};
};
......
......@@ -26,7 +26,16 @@ export default class Pie extends Component {
componentWillReceiveProps(nextProps) {
if (this.props.data !== nextProps.data) {
this.getLengendData();
// because of charts data create when rendered
// so there is a trick for get rendered time
this.setState(
{
legendData: [...this.state.legendData],
},
() => {
this.getLengendData();
}
);
}
}
......
import React, { PureComponent } from 'react';
import { Layout, Menu, Icon, Spin, Tag, Dropdown, Avatar, Divider } from 'antd';
import { Menu, Icon, Spin, Tag, Dropdown, Avatar, Divider } from 'antd';
import moment from 'moment';
import groupBy from 'lodash/groupBy';
import Debounce from 'lodash-decorators/debounce';
......@@ -8,8 +8,6 @@ import NoticeIcon from '../NoticeIcon';
import HeaderSearch from '../HeaderSearch';
import styles from './index.less';
const { Header } = Layout;
export default class GlobalHeader extends PureComponent {
componentWillUnmount() {
this.triggerResizeEvent.cancel();
......@@ -68,7 +66,7 @@ export default class GlobalHeader extends PureComponent {
);
const noticeData = this.getNoticeData();
return (
<Header className={styles.header}>
<div className={styles.header}>
{isMobile && (
[
(
......@@ -135,7 +133,7 @@ export default class GlobalHeader extends PureComponent {
</Dropdown>
) : <Spin size="small" style={{ marginLeft: 8 }} />}
</div>
</Header>
</div>
);
}
}
@import "~antd/lib/style/themes/default.less";
.header {
height: 64px;
padding: 0 12px 0 0;
background: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
......
......@@ -16,7 +16,7 @@ import Authorized from '../utils/Authorized';
import { getMenuData } from '../common/menu';
import logo from '../assets/logo.svg';
const { Content } = Layout;
const { Content, Header, Footer } = Layout;
const { AuthorizedRoute } = Authorized;
/**
......@@ -164,18 +164,20 @@ class BasicLayout extends React.PureComponent {
onCollapse={this.handleMenuCollapse}
/>
<Layout>
<GlobalHeader
logo={logo}
currentUser={currentUser}
fetchingNotices={fetchingNotices}
notices={notices}
collapsed={collapsed}
isMobile={this.state.isMobile}
onNoticeClear={this.handleNoticeClear}
onCollapse={this.handleMenuCollapse}
onMenuClick={this.handleMenuClick}
onNoticeVisibleChange={this.handleNoticeVisibleChange}
/>
<Header style={{ padding: 0 }}>
<GlobalHeader
logo={logo}
currentUser={currentUser}
fetchingNotices={fetchingNotices}
notices={notices}
collapsed={collapsed}
isMobile={this.state.isMobile}
onNoticeClear={this.handleNoticeClear}
onCollapse={this.handleMenuCollapse}
onMenuClick={this.handleMenuClick}
onNoticeVisibleChange={this.handleNoticeVisibleChange}
/>
</Header>
<Content style={{ margin: '24px 24px 0', height: '100%' }}>
<Switch>
{
......@@ -201,29 +203,31 @@ class BasicLayout extends React.PureComponent {
<Route render={NotFound} />
</Switch>
</Content>
<GlobalFooter
links={[{
key: 'Pro 首页',
title: 'Pro 首页',
href: 'http://pro.ant.design',
blankTarget: true,
}, {
key: 'github',
title: <Icon type="github" />,
href: 'https://github.com/ant-design/ant-design-pro',
blankTarget: true,
}, {
key: 'Ant Design',
title: 'Ant Design',
href: 'http://ant.design',
blankTarget: true,
}]}
copyright={
<div>
Copyright <Icon type="copyright" /> 2018 蚂蚁金服体验技术部出品
</div>
}
/>
<Footer style={{ padding: 0 }}>
<GlobalFooter
links={[{
key: 'Pro 首页',
title: 'Pro 首页',
href: 'http://pro.ant.design',
blankTarget: true,
}, {
key: 'github',
title: <Icon type="github" />,
href: 'https://github.com/ant-design/ant-design-pro',
blankTarget: true,
}, {
key: 'Ant Design',
title: 'Ant Design',
href: 'http://ant.design',
blankTarget: true,
}]}
copyright={
<div>
Copyright <Icon type="copyright" /> 2018 蚂蚁金服体验技术部出品
</div>
}
/>
</Footer>
</Layout>
</Layout>
);
......
import React from 'react';
import { routerRedux, Switch } from 'dva/router';
import { routerRedux, Route, Switch } from 'dva/router';
import { LocaleProvider, Spin } from 'antd';
import zhCN from 'antd/lib/locale-provider/zh_CN';
import dynamic from 'dva/dynamic';
......@@ -21,10 +21,9 @@ function RouterConfig({ history, app }) {
<LocaleProvider locale={zhCN}>
<ConnectedRouter history={history}>
<Switch>
<AuthorizedRoute
<Route
path="/user"
render={props => <UserLayout {...props} />}
redirectPath="/"
component={UserLayout}
/>
<AuthorizedRoute
path="/"
......
......@@ -107,7 +107,6 @@ export default class Monitor extends PureComponent {
<Col xl={12} lg={24} sm={24} xs={24}>
<Card
title="各品类占比"
style={{ marginBottom: 24 }}
bordered={false}
className={styles.pieCard}
>
......@@ -147,7 +146,7 @@ export default class Monitor extends PureComponent {
</Row>
</Card>
</Col>
<Col xl={6} lg={12} sm={24} xs={24} style={{ marginBottom: 24 }}>
<Col xl={6} lg={12} sm={24} xs={24}>
<Card title="热门搜索" loading={loading} bordered={false} bodyStyle={{ overflow: 'hidden' }}>
<TagCloud
data={tags}
......@@ -155,7 +154,7 @@ export default class Monitor extends PureComponent {
/>
</Card>
</Col>
<Col xl={6} lg={12} sm={24} xs={24} style={{ marginBottom: 24 }}>
<Col xl={6} lg={12} sm={24} xs={24}>
<Card title="资源剩余" bodyStyle={{ textAlign: 'center', fontSize: 0 }} bordered={false}>
<WaterWave
height={161}
......
......@@ -268,7 +268,7 @@ class AdvancedForm extends PureComponent {
</Row>
</Form>
</Card>
<Card title="成员管理" className={styles.card} bordered={false}>
<Card title="成员管理" bordered={false}>
{getFieldDecorator('members', {
initialValue: tableData,
})(<TableForm />)}
......
......@@ -23,17 +23,6 @@ export default class TableForm extends PureComponent {
}
index = 0;
cacheOriginData = {};
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
this.props.dispatch({
type: 'form/submit',
payload: values,
});
}
});
}
toggleEditable=(e, key) => {
e.preventDefault();
const newData = this.state.data.map(item => ({ ...item }));
......@@ -83,12 +72,7 @@ export default class TableForm extends PureComponent {
this.setState({
loading: true,
});
// save field when blur input
setTimeout(() => {
if (document.activeElement.tagName === 'INPUT' &&
document.activeElement !== e.target) {
return;
}
if (this.clickedCancel) {
this.clickedCancel = false;
return;
......@@ -121,6 +105,7 @@ export default class TableForm extends PureComponent {
delete this.cacheOriginData[key];
}
this.setState({ data: newData });
this.clickedCancel = false;
}
render() {
const columns = [{
......@@ -135,7 +120,6 @@ export default class TableForm extends PureComponent {
value={text}
autoFocus
onChange={e => this.handleFieldChange(e, 'name', record.key)}
onBlur={e => this.saveRow(e, record.key)}
onKeyPress={e => this.handleKeyPress(e, record.key)}
placeholder="成员姓名"
/>
......@@ -154,7 +138,6 @@ export default class TableForm extends PureComponent {
<Input
value={text}
onChange={e => this.handleFieldChange(e, 'workId', record.key)}
onBlur={e => this.saveRow(e, record.key)}
onKeyPress={e => this.handleKeyPress(e, record.key)}
placeholder="工号"
/>
......@@ -173,7 +156,6 @@ export default class TableForm extends PureComponent {
<Input
value={text}
onChange={e => this.handleFieldChange(e, 'department', record.key)}
onBlur={e => this.saveRow(e, record.key)}
onKeyPress={e => this.handleKeyPress(e, record.key)}
placeholder="所属部门"
/>
......@@ -192,7 +174,7 @@ export default class TableForm extends PureComponent {
if (record.isNew) {
return (
<span>
<a>保存</a>
<a onClick={e => this.saveRow(e, record.key)}>添加</a>
<Divider type="vertical" />
<Popconfirm title="是否要删除此行?" onConfirm={() => this.remove(record.key)}>
<a>删除</a>
......@@ -202,7 +184,7 @@ export default class TableForm extends PureComponent {
}
return (
<span>
<a>保存</a>
<a onClick={e => this.saveRow(e, record.key)}>保存</a>
<Divider type="vertical" />
<a onClick={e => this.cancel(e, record.key)}>取消</a>
</span>
......
......@@ -5,7 +5,6 @@
}
.tabsCard {
margin-bottom: 24px;
:global {
.ant-card-head {
padding: 0 16px;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment