Commit c9ff3d38 authored by jim's avatar jim

Merge branch 'v2' into top_nav

parents 8b904c66 3621feb6
...@@ -24,7 +24,7 @@ We need your help: https://github.com/ant-design/ant-design-pro/issues/120 ...@@ -24,7 +24,7 @@ We need your help: https://github.com/ant-design/ant-design-pro/issues/120
- :triangular_ruler: **Common Templates**: Typical templates for enterprise applications - :triangular_ruler: **Common Templates**: Typical templates for enterprise applications
- :rocket: **State of The Art Development**: Newest development stack of React/dva/antd - :rocket: **State of The Art Development**: Newest development stack of React/dva/antd
- :iphone: **Responsive**: Designed for varies of screen size - :iphone: **Responsive**: Designed for varies of screen size
- :art: **Themeing**: Customizable theme with simple config - :art: **Theming**: Customizable theme with simple config
- :globe_with_meridians: **International**: Built-in i18n solution - :globe_with_meridians: **International**: Built-in i18n solution
- :gear: **Best Practice**: Solid workflow make your code health - :gear: **Best Practice**: Solid workflow make your code health
- :1234: **Mock development**: Easy to use mock development solution - :1234: **Mock development**: Easy to use mock development solution
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
"dva": "^2.1.0", "dva": "^2.1.0",
"dva-loading": "^1.0.4", "dva-loading": "^1.0.4",
"enquire-js": "^0.1.1", "enquire-js": "^0.1.1",
"fastclick": "^1.0.6",
"lodash": "^4.17.4", "lodash": "^4.17.4",
"lodash-decorators": "^4.4.1", "lodash-decorators": "^4.4.1",
"moment": "^2.19.1", "moment": "^2.19.1",
...@@ -77,7 +76,7 @@ ...@@ -77,7 +76,7 @@
"stylelint-config-standard": "^18.0.0" "stylelint-config-standard": "^18.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"nightmare": "^2.10.0" "puppeteer": "^1.1.1"
}, },
"lint-staged": { "lint-staged": {
"**/*.{js,jsx}": "lint-staged:js", "**/*.{js,jsx}": "lint-staged:js",
......
--- ---
order: 0 order: 0
title: Standard Login title:
zh-CN: 标准登录
en-US: Standard Login
--- ---
支持账号密码及手机号登录两种模式。 Support login with account and mobile number.
````jsx ````jsx
import Login from 'ant-design-pro/lib/Login'; import Login from 'ant-design-pro/lib/Login';
...@@ -26,7 +28,7 @@ class LoginDemo extends React.Component { ...@@ -26,7 +28,7 @@ class LoginDemo extends React.Component {
if (!err && (values.username !== 'admin' || values.password !== '888888')) { if (!err && (values.username !== 'admin' || values.password !== '888888')) {
setTimeout(() => { setTimeout(() => {
this.setState({ this.setState({
notice: '账号或密码错误!', notice: 'The combination of username and password is incorrect!',
}); });
}, 500); }, 500);
} }
...@@ -50,7 +52,7 @@ class LoginDemo extends React.Component { ...@@ -50,7 +52,7 @@ class LoginDemo extends React.Component {
onTabChange={this.onTabChange} onTabChange={this.onTabChange}
onSubmit={this.onSubmit} onSubmit={this.onSubmit}
> >
<Tab key="tab1" tab="账号密码登录"> <Tab key="tab1" tab="Account">
{ {
this.state.notice && this.state.notice &&
<Alert style={{ marginBottom: 24 }} message={this.state.notice} type="error" showIcon closable /> <Alert style={{ marginBottom: 24 }} message={this.state.notice} type="error" showIcon closable />
...@@ -58,21 +60,21 @@ class LoginDemo extends React.Component { ...@@ -58,21 +60,21 @@ class LoginDemo extends React.Component {
<UserName name="username" /> <UserName name="username" />
<Password name="password" /> <Password name="password" />
</Tab> </Tab>
<Tab key="tab2" tab="手机号登录"> <Tab key="tab2" tab="Mobile">
<Mobile name="mobile" /> <Mobile name="mobile" />
<Captcha onGetCaptcha={() => console.log('Get captcha!')} name="captcha" /> <Captcha onGetCaptcha={() => console.log('Get captcha!')} name="captcha" />
</Tab> </Tab>
<div> <div>
<Checkbox checked={this.state.autoLogin} onChange={this.changeAutoLogin}>自动登录</Checkbox> <Checkbox checked={this.state.autoLogin} onChange={this.changeAutoLogin}>Keep me logged in</Checkbox>
<a style={{ float: 'right' }} href="">忘记密码</a> <a style={{ float: 'right' }} href="">Forgot password</a>
</div> </div>
<Submit>登录</Submit> <Submit>Login</Submit>
<div> <div>
其他登录方式 Other login methods
<span className="icon icon-alipay" /> <span className="icon icon-alipay" />
<span className="icon icon-taobao" /> <span className="icon icon-taobao" />
<span className="icon icon-weibo" /> <span className="icon icon-weibo" />
<a style={{ float: 'right' }} href="">注册账户</a> <a style={{ float: 'right' }} href="">Register</a>
</div> </div>
</Login> </Login>
); );
......
---
title: Login
cols: 1
order: 15
---
Support multiple common ways of login with built-in controls. You can choose your own combinations and use with your custom controls.
## API
### Login
Property | Description | Type | Default
----|------|-----|------
defaultActiveKey | default key to activate the tab panel | String | -
onTabChange | callback on changing tabs | (key) => void | -
onSubmit | callback on submit | (err, values) => void | -
### Login.Tab
Property | Description | Type | Default
----|------|-----|------
key | key of the tab | String | -
tab | displayed text of the tab | ReactNode | -
### Login.UserName
Property | Description | Type | Default
----|------|-----|------
name | name of the control, also the key of the submitted data | String | -
rules | validation rules, same with [option.rules](getFieldDecorator(id, options)) in Form getFieldDecorator(id, options) | object[] | -
Apart from the above properties, Login.Username also support all properties of antd.Input, together with the default values of basic settings, such as _placeholder_, _size_ and _prefix_. All of these default values can be over-written.
### Login.Password, Login.Mobile are the same as Login.UserName
### Login.Captcha
Property | Description | Type | Default
----|------|-----|------
onGetCaptcha | callback on getting a new Captcha | () => void | -
Apart from the above properties, _Login.Captcha_ support the same properties with _Login.UserName_.
### Login.Submit
Support all properties of _antd.Button_.
\ No newline at end of file
--- ---
title: title: Login
en-US: Login
zh-CN: Login
subtitle: 登录 subtitle: 登录
cols: 1 cols: 1
order: 15 order: 15
...@@ -48,4 +46,3 @@ onGetCaptcha | 点击获取校验码的回调 | () => void | - ...@@ -48,4 +46,3 @@ onGetCaptcha | 点击获取校验码的回调 | () => void | -
### Login.Submit ### Login.Submit
支持 antd.Button 的所有属性。 支持 antd.Button 的所有属性。
...@@ -11,7 +11,7 @@ const map = { ...@@ -11,7 +11,7 @@ const map = {
placeholder: 'admin', placeholder: 'admin',
}, },
rules: [{ rules: [{
required: true, message: '请输入账户名!', required: true, message: 'Please enter username!',
}], }],
}, },
Password: { Password: {
...@@ -23,7 +23,7 @@ const map = { ...@@ -23,7 +23,7 @@ const map = {
placeholder: '888888', placeholder: '888888',
}, },
rules: [{ rules: [{
required: true, message: '请输入密码!', required: true, message: 'Please enter password!',
}], }],
}, },
Mobile: { Mobile: {
...@@ -31,12 +31,12 @@ const map = { ...@@ -31,12 +31,12 @@ const map = {
props: { props: {
size: 'large', size: 'large',
prefix: <Icon type="mobile" className={styles.prefixIcon} />, prefix: <Icon type="mobile" className={styles.prefixIcon} />,
placeholder: '手机号', placeholder: 'mobile number',
}, },
rules: [{ rules: [{
required: true, message: '请输入手机号!', required: true, message: 'Please enter mobile number!',
}, { }, {
pattern: /^1\d{10}$/, message: '手机号格式错误!', pattern: /^1\d{10}$/, message: 'Wrong mobile number format!',
}], }],
}, },
Captcha: { Captcha: {
...@@ -44,10 +44,10 @@ const map = { ...@@ -44,10 +44,10 @@ const map = {
props: { props: {
size: 'large', size: 'large',
prefix: <Icon type="mail" className={styles.prefixIcon} />, prefix: <Icon type="mail" className={styles.prefixIcon} />,
placeholder: '验证码', placeholder: 'captcha',
}, },
rules: [{ rules: [{
required: true, message: '请输入验证码!', required: true, message: 'Please enter Captcha!',
}], }],
}, },
}; };
......
import Nightmare from 'nightmare'; import puppeteer from 'puppeteer';
describe('Homepage', () => { describe('Homepage', () => {
it('it should have logo text', async () => { it('it should have logo text', async () => {
const page = Nightmare().goto('http://localhost:8000'); const browser = await puppeteer.launch();
const text = await page.wait('h1').evaluate(() => document.body.innerHTML).end(); const page = await browser.newPage();
await page.goto('http://localhost:8000');
await page.waitForSelector('h1');
const text = await page.evaluate(() => document.body.innerHTML);
expect(text).toContain('<h1>Ant Design Pro</h1>'); expect(text).toContain('<h1>Ant Design Pro</h1>');
await page.close();
browser.close();
}); });
}); });
import Nightmare from 'nightmare'; import puppeteer from 'puppeteer';
describe('Login', () => { describe('Login', () => {
let browser;
let page; let page;
beforeEach(() => {
page = Nightmare(); beforeAll(async () => {
page browser = await puppeteer.launch();
.goto('http://localhost:8000/') });
.evaluate(() => {
window.localStorage.setItem('antd-pro-authority', 'guest'); beforeEach(async () => {
}) page = await browser.newPage();
.goto('http://localhost:8000/#/user/login'); await page.goto('http://localhost:8000/#/user/login');
await page.evaluate(() => window.localStorage.setItem('antd-pro-authority', 'guest'));
}); });
afterEach(() => page.close());
it('should login with failure', async () => { it('should login with failure', async () => {
await page.type('#userName', 'mockuser') await page.type('#userName', 'mockuser');
.type('#password', 'wrong_password') await page.type('#password', 'wrong_password');
.click('button[type="submit"]') await page.click('button[type="submit"]');
.wait('.ant-alert-error') // should display error await page.waitForSelector('.ant-alert-error'); // should display error
.end();
}); });
it('should login successfully', async () => { it('should login successfully', async () => {
const text = await page.type('#userName', 'admin') await page.type('#userName', 'admin');
.type('#password', '888888') await page.type('#password', '888888');
.click('button[type="submit"]') await page.click('button[type="submit"]');
.wait('.ant-layout-sider h1') // should display error await page.waitForSelector('.ant-layout-sider h1'); // should display error
.evaluate(() => document.body.innerHTML) const text = await page.evaluate(() => document.body.innerHTML);
.end();
expect(text).toContain('<h1>Ant Design Pro</h1>'); expect(text).toContain('<h1>Ant Design Pro</h1>');
}); });
afterAll(() => browser.close());
}); });
...@@ -7,7 +7,6 @@ import createHistory from 'history/createHashHistory'; ...@@ -7,7 +7,6 @@ import createHistory from 'history/createHashHistory';
// import createHistory from 'history/createBrowserHistory'; // import createHistory from 'history/createBrowserHistory';
import createLoading from 'dva-loading'; import createLoading from 'dva-loading';
import 'moment/locale/zh-cn'; import 'moment/locale/zh-cn';
import FastClick from 'fastclick';
import './rollbar'; import './rollbar';
import './index.less'; import './index.less';
...@@ -28,7 +27,4 @@ app.router(require('./router').default); ...@@ -28,7 +27,4 @@ app.router(require('./router').default);
// 5. Start // 5. Start
app.start('#root'); app.start('#root');
FastClick.attach(document.body);
export default app._store; // eslint-disable-line export default app._store; // eslint-disable-line
...@@ -22,6 +22,7 @@ const CreateForm = Form.create()((props) => { ...@@ -22,6 +22,7 @@ const CreateForm = Form.create()((props) => {
const okHandle = () => { const okHandle = () => {
form.validateFields((err, fieldsValue) => { form.validateFields((err, fieldsValue) => {
if (err) return; if (err) return;
form.resetFields();
handleAdd(fieldsValue); handleAdd(fieldsValue);
}); });
}; };
......
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