Commit 8f0262b2 authored by 陈帅's avatar 陈帅

Merge branch 'master' into v2

parents 17827d5e c26ff428
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
node_modules
**/node_modules
# roadhog-api-doc ignore
/src/utils/request-temp.js
_roadhog-api-doc
......
......@@ -13,6 +13,7 @@
"function-parentheses-newline-inside": null,
"function-max-empty-lines": null,
"function-whitespace-after": null,
"no-missing-end-of-source-newline": null,
"number-leading-zero": null,
"number-no-trailing-zeros": null,
"rule-empty-line-before": null,
......
English | [简体中文](./README.zh-CN.md)
[Русский](./README.ru-RU.md) | English | [简体中文](./README.zh-CN.md)
# Ant Design Pro
......@@ -86,10 +86,14 @@ $ pro new
More instructions at [documentation](http://pro.ant.design/docs/getting-started).
## Compatibility
## Browsers support
Modern browsers and IE11.
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera |
| --------- | --------- | --------- | --------- | --------- |
| IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions
## Contributing
Any type of contribution is welcome, here are some examples of how you may contribute to this project:
......
Русский | [English](./README.md) | [简体中文](./README.zh-CN.md)
# Ant Design Pro
[![](https://img.shields.io/travis/ant-design/ant-design-pro/master.svg?style=flat-square)](https://travis-ci.org/ant-design/ant-design-pro)
[![Build status](https://ci.appveyor.com/api/projects/status/67fxu2by3ibvqtat/branch/master?svg=true)](https://ci.appveyor.com/project/afc163/ant-design-pro/branch/master)
[![Dependencies](https://img.shields.io/david/ant-design/ant-design-pro.svg)](https://david-dm.org/ant-design/ant-design-pro)
[![DevDependencies](https://img.shields.io/david/dev/ant-design/ant-design-pro.svg)](https://david-dm.org/ant-design/ant-design-pro#info=devDependencies&view=list)
[![Gitter](https://badges.gitter.im/ant-design/ant-design-pro.svg)](https://gitter.im/ant-design/ant-design-pro?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
UI-решение "из коробки" для корпоративных приложений как React boilerplate
![](https://gw.alipayobjects.com/zos/rmsportal/xEdBqwSzvoSapmnSnYjU.png)
- Демо: http://preview.pro.ant.design
- Домашняя страница: http://pro.ant.design
- Документация: http://pro.ant.design/docs/getting-started
- История изменений: http://pro.ant.design/docs/changelog
- FAQ: http://pro.ant.design/docs/faq
- Китайское зеркало сайта: http://ant-design-pro.gitee.io
## Поиск переводчиков :loudspeaker:
Нам нужна ваша помощь: https://github.com/ant-design/ant-design-pro/issues/120
## Возможности
- :gem: **Аккуратный дизайн**: Посмотрите [спецификацию Ant Design](http://ant.design/)
- :triangular_ruler: **Общие шаблоны**: Стандартные шаблоны для корпоративных приложений
- :rocket: **Разработка, как искусство**: Новейший стек технологий React/dva/antd
- :iphone: **Отзывчивая верстка**: Создан для экранов разных размеров
- :art: **Темизация**: Возможность изменения темы с помощью конфигурации
- :globe_with_meridians: **Мультиязычность**: Встроенное i18n решение
- :gear: **Лучшие практики**: Надежные процессы для хорошего кода
- :1234: **Разработка по шиблону**: Простое в использовании решение для разработки
- :white_check_mark: **UI тесты**: Разрабатывайте безопасно с юнит и e2e тестами
## Шаблоны
```
- Dashboard
- Analytic
- Monitor
- Workspace
- Form
- Basic Form
- Step Form
- Advanced From
- List
- Standard Table
- Standard List
- Card List
- Search List (Project/Applications/Article)
- Profile
- Simple Profile
- Advanced Profile
- Result
- Success
- Failed
- Exception
- 403
- 404
- 500
- User
- Login
- Register
- Register Result
```
## Использование
```bash
$ git clone https://github.com/ant-design/ant-design-pro.git --depth=1
$ cd ant-design-pro
$ npm install
$ npm start # visit http://localhost:8000
```
Также можно использовать инструмент командной строки: [ant-design-pro-cli](https://github.com/ant-design/ant-design-pro-cli)
```bash
$ npm install ant-design-pro-cli -g
$ mkdir pro-demo && cd pro-demo
$ pro new
```
Больше информации в [документации](http://pro.ant.design/docs/getting-started).
## Совместимость
Современные браузеры и IE11.
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera |
| --------- | --------- | --------- | --------- | --------- |
| IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions
## Распространение
Любые варианты распространения приветствуются! Вот несколько примероы того, как вы можете помочь распространению проекта:
- Использовать Ant Design Pro в ежедневной работе.
- Создавать [задачи](http://github.com/ant-design/ant-design-pro/issues) заводить баги или отвечать на вопросы.
- Делать [pull-реквесты](http://github.com/ant-design/ant-design-pro/pulls) для совершенствования нашего кода.
[English](./README.md) | 简体中文
[Русский](./README.ru-RU.md) | [English](./README.md) | 简体中文
# Ant Design Pro
......@@ -82,10 +82,14 @@ $ pro new
更多信息请参考 [使用文档](http://pro.ant.design/docs/getting-started)
## 兼容性
## 支持环境
现代浏览器及 IE11。
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera |
| --------- | --------- | --------- | --------- | --------- |
| IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions
## 参与贡献
我们非常欢迎你的贡献,你可以通过以下方式和我们一起共建 :smiley::
......
module.exports = {
testURL: 'http://localhost:8000',
};
......@@ -23,8 +23,9 @@
"prettier": "prettier --write ./src/**/**/**/*"
},
"dependencies": {
"@antv/data-set": "^0.8.9",
"antd": "^3.7.3",
"@antv/data-set": "^0.9.0",
"@babel/polyfill": "^7.0.0-beta.36",
"antd": "^3.8.0",
"bizcharts": "^3.1.10",
"bizcharts-plugin-slider": "^2.0.3",
"classnames": "^2.2.6",
......@@ -35,9 +36,10 @@
"moment": "^2.22.2",
"numeral": "^2.0.6",
"omit.js": "^1.0.0",
"path-to-regexp": "^2.2.1",
"prop-types": "^15.6.2",
"qs": "^6.5.2",
"path-to-regexp": "^2.1.0",
"prop-types": "^15.5.10",
"qs": "^6.5.0",
"react": "^16.4.1",
"react-container-query": "^0.11.0",
"react-copy-to-clipboard": "^5.0.1",
"react-document-title": "^2.0.3",
......@@ -60,8 +62,8 @@
"babel-runtime": "^6.9.2",
"cross-env": "^5.1.1",
"cross-port-killer": "^1.0.1",
"enzyme": "^3.1.0",
"eslint": "^5.1.0",
"enzyme": "^3.4.1",
"eslint": "^5.0.0",
"eslint-config-airbnb": "^17.0.0",
"eslint-config-prettier": "^2.9.0",
"eslint-config-umi": "^0.1.4",
......
import * as React from 'react';
export interface ITimelineChartProps {
data: Array<{
x: string;
y1: string;
y2: string;
x: number;
y1: number;
y2?: number;
}>;
titleMap: { y1: string; y2: string };
titleMap: { y1: string; y2?: string };
padding?: [number, number, number, number];
height?: number;
style?: React.CSSProperties;
......
......@@ -137,11 +137,15 @@ export default class Ellipsis extends Component {
if (sh <= th) {
shadowNode.innerHTML = text.substring(0, mid + 1) + suffix;
sh = shadowNode.offsetHeight;
if (sh > th) {
if (sh > th || mid === begin) {
return mid;
} else {
begin = mid;
mid = Math.floor((end - begin) / 2) + begin;
if (end - begin === 1) {
mid = 1 + begin;
} else {
mid = Math.floor((end - begin) / 2) + begin;
}
return this.bisection(th, mid, begin, end, text, shadowNode);
}
} else {
......
......@@ -81,7 +81,7 @@ export default class HeaderSearch extends PureComponent {
})
debouncePressEnter() {
const { onPressEnter } = this.props;
const value = this.state;
const { value } = this.state;
onPressEnter(value);
}
......
......@@ -79,6 +79,7 @@ class WarpFormItem extends Component {
defaultValue,
rules,
name,
buttonText,
updateActive,
type,
...restProps
......@@ -103,7 +104,7 @@ class WarpFormItem extends Component {
size="large"
onClick={this.onGetCaptcha}
>
{count ? `${count} s` : '获取验证码'}
{count ? `${count} s` : buttonText}
</Button>
</Col>
</Row>
......
......@@ -19,6 +19,7 @@ export interface LoginItemProps {
style?: React.CSSProperties;
onGetCaptcha?: () => void;
placeholder?: string;
buttonText?: React.ReactNode;
}
export class LoginItem extends React.Component<LoginItemProps, any> {}
......
......@@ -40,6 +40,7 @@ Property | Description | Type | Default
----|------|-----|------
onGetCaptcha | callback on getting a new Captcha | () => (void \| false \| Promise) | -
countDown | count down | number |-
buttonText | text on getting a new Captcha | ReactNode | '获取验证码'
Apart from the above properties, _Login.Captcha_ support the same properties with _Login.UserName_.
......
......@@ -32,8 +32,7 @@ name | 控件标记,提交数据中同样以此为 key | String | -
rules | 校验规则,同 Form getFieldDecorator(id, options) 中 [option.rules 的规则](getFieldDecorator(id, options)) | object[] | -
除上述属性以外,Login.UserName 还支持 antd.Input 的所有属性,并且自带默认的基础配置,包括 `placeholder` `size` `prefix` 等,这些基础配置均可被覆盖。
### Login.Password、Login.Mobile 同 Login.UserName
## Login.Password、Login.Mobile 同 Login.UserName
### Login.Captcha
......@@ -41,6 +40,7 @@ rules | 校验规则,同 Form getFieldDecorator(id, options) 中 [option.rules
----|------|-----|------
onGetCaptcha | 点击获取校验码的回调 | () => (void \| false \| Promise) | -
countDown | 倒计时 | number |-
buttonText | 点击获取校验码的说明文字 | ReactNode | '获取验证码'
除上述属性以外,Login.Captcha 支持的属性与 Login.UserName 相同。
......
import React from 'react';
import * as React from 'react';
import NoticeIconTab, { INoticeIconData } from './NoticeIconTab';
export interface INoticeIconProps {
......
......@@ -218,17 +218,18 @@ export default class PageHeader extends PureComponent {
</div>
</div>
</div>
{tabList &&
tabList.length && (
<Tabs
className={styles.tabs}
{...activeKeyProps}
onChange={this.onChange}
tabBarExtraContent={tabBarExtraContent}
>
{tabList.map(item => <TabPane tab={item.tab} key={item.key} />)}
</Tabs>
)}
{tabList && tabList.length ? (
<Tabs
className={styles.tabs}
{...activeKeyProps}
onChange={this.onChange}
tabBarExtraContent={tabBarExtraContent}
>
{tabList.map(item => (
<TabPane tab={item.tab} key={item.key} />
))}
</Tabs>
) : null}
</Card>
);
}
......
......@@ -19,4 +19,4 @@ order: 14
|----------|------------------------------------------|-------------|-------|
| colorful | 是否彩色标记 | Boolean | true |
| flag | 上升下降标识:`up|down` | string | - |
| reverseColor | 颜色反转 | Boolean | true |
| reverseColor | 颜色反转 | Boolean | false |
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { Layout, Icon, message } from 'antd';
import DocumentTitle from 'react-document-title';
import { connect } from 'dva';
import { Route, Redirect, Switch, routerRedux } from 'dva/router';
import { ContainerQuery } from 'react-container-query';
import classNames from 'classnames';
import pathToRegexp from 'path-to-regexp';
import { enquireScreen, unenquireScreen } from 'enquire-js';
import GlobalHeader from '../components/GlobalHeader';
import GlobalFooter from '../components/GlobalFooter';
import SiderMenu from '../components/SiderMenu';
import NotFound from '../routes/Exception/404';
import { getRoutes } from '../utils/utils';
import Authorized from '../utils/Authorized';
import { getMenuData } from '../common/menu';
import logo from '../assets/logo.svg';
const { Content, Header, Footer } = Layout;
const { AuthorizedRoute, check } = Authorized;
/**
* 根据菜单取得重定向地址.
*/
const redirectData = [];
const getRedirect = item => {
if (item && item.children) {
if (item.children[0] && item.children[0].path) {
redirectData.push({
from: `${item.path}`,
to: `${item.children[0].path}`,
});
item.children.forEach(children => {
getRedirect(children);
});
}
}
};
getMenuData().forEach(getRedirect);
/**
* 获取面包屑映射
* @param {Object} menuData 菜单配置
* @param {Object} routerData 路由配置
*/
const getBreadcrumbNameMap = (menuData, routerData) => {
const result = {};
const childResult = {};
for (const i of menuData) {
if (!routerData[i.path]) {
result[i.path] = i;
}
if (i.children) {
Object.assign(childResult, getBreadcrumbNameMap(i.children, routerData));
}
}
return Object.assign({}, routerData, result, childResult);
};
const query = {
'screen-xs': {
maxWidth: 575,
},
'screen-sm': {
minWidth: 576,
maxWidth: 767,
},
'screen-md': {
minWidth: 768,
maxWidth: 991,
},
'screen-lg': {
minWidth: 992,
maxWidth: 1199,
},
'screen-xl': {
minWidth: 1200,
maxWidth: 1599,
},
'screen-xxl': {
minWidth: 1600,
},
};
let isMobile;
enquireScreen(b => {
isMobile = b;
});
@connect(({ user, global = {}, loading }) => ({
currentUser: user.currentUser,
collapsed: global.collapsed,
fetchingNotices: loading.effects['global/fetchNotices'],
notices: global.notices,
}))
export default class BasicLayout extends React.PureComponent {
static childContextTypes = {
location: PropTypes.object,
breadcrumbNameMap: PropTypes.object,
};
state = {
isMobile,
};
getChildContext() {
const { location, routerData } = this.props;
return {
location,
breadcrumbNameMap: getBreadcrumbNameMap(getMenuData(), routerData),
};
}
componentDidMount() {
this.enquireHandler = enquireScreen(mobile => {
this.setState({
isMobile: mobile,
});
});
const { dispatch } = this.props;
dispatch({
type: 'user/fetchCurrent',
});
}
componentWillUnmount() {
unenquireScreen(this.enquireHandler);
}
getPageTitle() {
const { routerData, location } = this.props;
const { pathname } = location;
let title = 'Ant Design Pro';
let currRouterData = null;
// match params path
Object.keys(routerData).forEach(key => {
if (pathToRegexp(key).test(pathname)) {
currRouterData = routerData[key];
}
});
if (currRouterData && currRouterData.name) {
title = `${currRouterData.name} - Ant Design Pro`;
}
return title;
}
getBaseRedirect = () => {
// According to the url parameter to redirect
// 这里是重定向的,重定向到 url 的 redirect 参数所示地址
const urlParams = new URL(window.location.href);
const redirect = urlParams.searchParams.get('redirect');
// Remove the parameters in the url
if (redirect) {
urlParams.searchParams.delete('redirect');
window.history.replaceState(null, 'redirect', urlParams.href);
} else {
const { routerData } = this.props;
// get the first authorized route path in routerData
const authorizedPath = Object.keys(routerData).find(
item => check(routerData[item].authority, item) && item !== '/'
);
return authorizedPath;
}
return redirect;
};
handleMenuCollapse = collapsed => {
const { dispatch } = this.props;
dispatch({
type: 'global/changeLayoutCollapsed',
payload: collapsed,
});
};
handleNoticeClear = type => {
message.success(`清空了${type}`);
const { dispatch } = this.props;
dispatch({
type: 'global/clearNotices',
payload: type,
});
};
handleMenuClick = ({ key }) => {
const { dispatch } = this.props;
if (key === 'triggerError') {
dispatch(routerRedux.push('/exception/trigger'));
return;
}
if (key === 'logout') {
dispatch({
type: 'login/logout',
});
}
};
handleNoticeVisibleChange = visible => {
const { dispatch } = this.props;
if (visible) {
dispatch({
type: 'global/fetchNotices',
});
}
};
render() {
const {
currentUser,
collapsed,
fetchingNotices,
notices,
routerData,
match,
location,
} = this.props;
const { isMobile: mb } = this.state;
const baseRedirect = this.getBaseRedirect();
const layout = (
<Layout>
<SiderMenu
logo={logo}
// 不带Authorized参数的情况下如果没有权限,会强制跳到403界面
// If you do not have the Authorized parameter
// you will be forced to jump to the 403 interface without permission
Authorized={Authorized}
menuData={getMenuData()}
collapsed={collapsed}
location={location}
isMobile={mb}
onCollapse={this.handleMenuCollapse}
/>
<Layout>
<Header style={{ padding: 0 }}>
<GlobalHeader
logo={logo}
currentUser={currentUser}
fetchingNotices={fetchingNotices}
notices={notices}
collapsed={collapsed}
isMobile={mb}
onNoticeClear={this.handleNoticeClear}
onCollapse={this.handleMenuCollapse}
onMenuClick={this.handleMenuClick}
onNoticeVisibleChange={this.handleNoticeVisibleChange}
/>
</Header>
<Content style={{ margin: '24px 24px 0', height: '100%' }}>
<Switch>
{redirectData.map(item => (
<Redirect key={item.from} exact from={item.from} to={item.to} />
))}
{getRoutes(match.path, routerData).map(item => (
<AuthorizedRoute
key={item.key}
path={item.path}
component={item.component}
exact={item.exact}
authority={item.authority}
redirectPath="/exception/403"
/>
))}
<Redirect exact from="/" to={baseRedirect} />
<Route render={NotFound} />
</Switch>
</Content>
<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={
<Fragment>
Copyright <Icon type="copyright" /> 2018 蚂蚁金服体验技术部出品
</Fragment>
}
/>
</Footer>
</Layout>
</Layout>
);
return (
<DocumentTitle title={this.getPageTitle()}>
<ContainerQuery query={query}>
{params => <div className={classNames(params)}>{layout}</div>}
</ContainerQuery>
</DocumentTitle>
);
}
}
......@@ -57,7 +57,12 @@ const tableData = [
},
];
class AdvancedForm extends PureComponent {
@connect(({ global, loading }) => ({
collapsed: global.collapsed,
submitting: loading.effects['form/submitAdvancedForm'],
}))
@Form.create()
export default class AdvancedForm extends PureComponent {
state = {
width: '100%',
};
......@@ -303,8 +308,3 @@ class AdvancedForm extends PureComponent {
);
}
}
export default connect(({ global, loading }) => ({
collapsed: global.collapsed,
submitting: loading.effects['form/submitAdvancedForm'],
}))(Form.create()(AdvancedForm));
......@@ -15,8 +15,11 @@ const formItemLayout = {
},
};
@connect(({ form }) => ({
data: form.step,
}))
@Form.create()
class Step1 extends React.PureComponent {
export default class Step1 extends React.PureComponent {
render() {
const { form, dispatch, data } = this.props;
const { getFieldDecorator, validateFields } = form;
......@@ -108,7 +111,3 @@ class Step1 extends React.PureComponent {
);
}
}
export default connect(({ form }) => ({
data: form.step,
}))(Step1);
......@@ -5,7 +5,10 @@ import { routerRedux } from 'dva/router';
import Result from 'components/Result';
import styles from './style.less';
class Step3 extends React.PureComponent {
@connect(({ form }) => ({
data: form.step,
}))
export default class Step3 extends React.PureComponent {
render() {
const { dispatch, data } = this.props;
const onFinish = () => {
......@@ -67,7 +70,3 @@ class Step3 extends React.PureComponent {
);
}
}
export default connect(({ form }) => ({
data: form.step,
}))(Step3);
......@@ -30,12 +30,12 @@ export default class SearchList extends Component {
tab: '文章',
},
{
key: 'Applications',
tab: '应用',
key: 'projects',
tab: '项目',
},
{
key: 'Projects',
tab: '项目',
key: 'applications',
tab: '应用',
},
];
......
......@@ -587,7 +587,7 @@ export default class TableList extends PureComponent {
</Col>
</Row>
<div style={{ overflow: 'hidden' }}>
<span style={{ float: 'right', marginBottom: 24 }}>
<div style={{ float: 'right', marginBottom: 24 }}>
<Button type="primary" htmlType="submit">
查询
</Button>
......@@ -597,7 +597,7 @@ export default class TableList extends PureComponent {
<a style={{ marginLeft: 8 }} onClick={this.toggleForm}>
收起 <Icon type="up" />
</a>
</span>
</div>
</div>
</Form>
);
......
......@@ -30,6 +30,7 @@
}
}
.submitButtons {
display: block;
white-space: nowrap;
margin-bottom: 24px;
}
......
import React, { PureComponent } from 'react';
import moment from 'moment';
import { connect } from 'dva';
import {
List,
Card,
Row,
Col,
Radio,
Input,
Progress,
Button,
Icon,
Dropdown,
Menu,
Avatar,
} from 'antd';
import PageHeaderLayout from '../../layouts/PageHeaderLayout';
import styles from './BasicList.less';
const RadioButton = Radio.Button;
const RadioGroup = Radio.Group;
const { Search } = Input;
const ListContent = ({ data: { owner, createdAt, percent, status } }) => (
<div className={styles.listContent}>
<div className={styles.listContentItem}>
<span>Owner</span>
<p>{owner}</p>
</div>
<div className={styles.listContentItem}>
<span>开始时间</span>
<p>{moment(createdAt).format('YYYY-MM-DD HH:mm')}</p>
</div>
<div className={styles.listContentItem}>
<Progress percent={percent} status={status} strokeWidth={6} style={{ width: 180 }} />
</div>
</div>
);
@connect(({ list, loading }) => ({
list,
loading: loading.models.list,
}))
export default class BasicList extends PureComponent {
componentDidMount() {
const { dispatch } = this.props;
dispatch({
type: 'list/fetch',
payload: {
count: 5,
},
});
}
render() {
const {
list: { list },
loading,
} = this.props;
const Info = ({ title, value, bordered }) => (
<div className={styles.headerInfo}>
<span>{title}</span>
<p>{value}</p>
{bordered && <em />}
</div>
);
const extraContent = (
<div className={styles.extraContent}>
<RadioGroup defaultValue="all">
<RadioButton value="all">全部</RadioButton>
<RadioButton value="progress">进行中</RadioButton>
<RadioButton value="waiting">等待中</RadioButton>
</RadioGroup>
<Search className={styles.extraContentSearch} placeholder="请输入" onSearch={() => ({})} />
</div>
);
const paginationProps = {
showSizeChanger: true,
showQuickJumper: true,
pageSize: 5,
total: 50,
};
const menu = (
<Menu>
<Menu.Item>
<a>编辑</a>
</Menu.Item>
<Menu.Item>
<a>删除</a>
</Menu.Item>
</Menu>
);
const MoreBtn = () => (
<Dropdown overlay={menu}>
<a>
更多 <Icon type="down" />
</a>
</Dropdown>
);
return (
<PageHeaderLayout>
<div className={styles.standardList}>
<Card bordered={false}>
<Row>
<Col sm={8} xs={24}>
<Info title="我的待办" value="8个任务" bordered />
</Col>
<Col sm={8} xs={24}>
<Info title="本周任务平均处理时间" value="32分钟" bordered />
</Col>
<Col sm={8} xs={24}>
<Info title="本周完成任务数" value="24个任务" />
</Col>
</Row>
</Card>
<Card
className={styles.listCard}
bordered={false}
title="标准列表"
style={{ marginTop: 24 }}
bodyStyle={{ padding: '0 32px 40px 32px' }}
extra={extraContent}
>
<Button type="dashed" style={{ width: '100%', marginBottom: 8 }} icon="plus">
添加
</Button>
<List
size="large"
rowKey="id"
loading={loading}
pagination={paginationProps}
dataSource={list}
renderItem={item => (
<List.Item actions={[<a>编辑</a>, <MoreBtn />]}>
<List.Item.Meta
avatar={<Avatar src={item.logo} shape="square" size="large" />}
title={<a href={item.href}>{item.title}</a>}
description={item.subDescription}
/>
<ListContent data={item} />
</List.Item>
)}
/>
</Card>
</div>
</PageHeaderLayout>
);
}
}
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