Commit 645f7daf authored by jim's avatar jim Committed by 陈帅

support perttier

parent 08456b98
{ {
"parser": "babel-eslint", "parser": "babel-eslint",
"extends": "airbnb", "extends": ["airbnb", "prettier"],
"plugins": ["compat"],
"env": { "env": {
"browser": true, "browser": true,
"node": true, "node": true,
...@@ -20,7 +19,9 @@ ...@@ -20,7 +19,9 @@
"react/jsx-no-bind": [0], "react/jsx-no-bind": [0],
"react/prop-types": [0], "react/prop-types": [0],
"react/prefer-stateless-function": [0], "react/prefer-stateless-function": [0],
"react/jsx-wrap-multilines": ["error", { "react/jsx-wrap-multilines": [
"error",
{
"declaration": "parens-new-line", "declaration": "parens-new-line",
"assignment": "parens-new-line", "assignment": "parens-new-line",
"return": "parens-new-line", "return": "parens-new-line",
...@@ -28,7 +29,8 @@ ...@@ -28,7 +29,8 @@
"condition": "parens-new-line", "condition": "parens-new-line",
"logical": "parens-new-line", "logical": "parens-new-line",
"prop": "ignore" "prop": "ignore"
}], }
],
"no-else-return": [0], "no-else-return": [0],
"no-restricted-syntax": [0], "no-restricted-syntax": [0],
"import/no-extraneous-dependencies": [0], "import/no-extraneous-dependencies": [0],
...@@ -43,18 +45,20 @@ ...@@ -43,18 +45,20 @@
"no-bitwise": [0], "no-bitwise": [0],
"no-cond-assign": [0], "no-cond-assign": [0],
"import/no-unresolved": [0], "import/no-unresolved": [0],
"comma-dangle": ["error", { "comma-dangle": [
"error",
{
"arrays": "always-multiline", "arrays": "always-multiline",
"objects": "always-multiline", "objects": "always-multiline",
"imports": "always-multiline", "imports": "always-multiline",
"exports": "always-multiline", "exports": "always-multiline",
"functions": "ignore" "functions": "ignore"
}], }
],
"object-curly-newline": [0], "object-curly-newline": [0],
"function-paren-newline": [0], "function-paren-newline": [0],
"no-restricted-globals": [0], "no-restricted-globals": [0],
"require-yield": [1], "require-yield": [1]
"compat/compat": "error"
}, },
"parserOptions": { "parserOptions": {
"ecmaFeatures": { "ecmaFeatures": {
......
...@@ -20,4 +20,3 @@ yarn.lock ...@@ -20,4 +20,3 @@ yarn.lock
package-lock.json package-lock.json
*bak *bak
jsconfig.json jsconfig.json
.prettierrc
**/*.md
**/*.svg
\ No newline at end of file
{
"singleQuote": true,
"trailingComma": "es5",
"printWidth": 100,
"overrides": [
{
"files": ".prettierrc",
"options": { "parser": "json" }
}
]
}
...@@ -14,7 +14,7 @@ const noProxy = process.env.NO_PROXY === 'true'; ...@@ -14,7 +14,7 @@ const noProxy = process.env.NO_PROXY === 'true';
const proxy = { const proxy = {
// 支持值为 Object 和 Array // 支持值为 Object 和 Array
'GET /api/currentUser': { 'GET /api/currentUser': {
$desc: "获取当前用户接口", $desc: '获取当前用户接口',
$params: { $params: {
pageSize: { pageSize: {
desc: '分页', desc: '分页',
...@@ -29,22 +29,26 @@ const proxy = { ...@@ -29,22 +29,26 @@ const proxy = {
}, },
}, },
// GET POST 可省略 // GET POST 可省略
'GET /api/users': [{ 'GET /api/users': [
{
key: '1', key: '1',
name: 'John Brown', name: 'John Brown',
age: 32, age: 32,
address: 'New York No. 1 Lake Park', address: 'New York No. 1 Lake Park',
}, { },
{
key: '2', key: '2',
name: 'Jim Green', name: 'Jim Green',
age: 42, age: 42,
address: 'London No. 1 Lake Park', address: 'London No. 1 Lake Park',
}, { },
{
key: '3', key: '3',
name: 'Joe Black', name: 'Joe Black',
age: 32, age: 32,
address: 'Sidney No. 1 Lake Park', address: 'Sidney No. 1 Lake Park',
}], },
],
'GET /api/project/notice': getNotice, 'GET /api/project/notice': getNotice,
'GET /api/activities': getActivities, 'GET /api/activities': getActivities,
'GET /api/rule': getRule, 'GET /api/rule': getRule,
...@@ -61,7 +65,7 @@ const proxy = { ...@@ -61,7 +65,7 @@ const proxy = {
res.send({ message: 'Ok' }); res.send({ message: 'Ok' });
}, },
'GET /api/tags': mockjs.mock({ 'GET /api/tags': mockjs.mock({
'list|100': [{ name: '@city', 'value|1-100': 150, 'type|0-2': 1 }] 'list|100': [{ name: '@city', 'value|1-100': 150, 'type|0-2': 1 }],
}), }),
'GET /api/fake_list': getFakeList, 'GET /api/fake_list': getFakeList,
'GET /api/fake_chart_data': getFakeChartData, 'GET /api/fake_chart_data': getFakeChartData,
...@@ -69,26 +73,26 @@ const proxy = { ...@@ -69,26 +73,26 @@ const proxy = {
'GET /api/profile/advanced': getProfileAdvancedData, 'GET /api/profile/advanced': getProfileAdvancedData,
'POST /api/login/account': (req, res) => { 'POST /api/login/account': (req, res) => {
const { password, userName, type } = req.body; const { password, userName, type } = req.body;
if(password === '888888' && userName === 'admin'){ if (password === '888888' && userName === 'admin') {
res.send({ res.send({
status: 'ok', status: 'ok',
type, type,
currentAuthority: 'admin' currentAuthority: 'admin',
}); });
return ; return;
} }
if(password === '123456' && userName === 'user'){ if (password === '123456' && userName === 'user') {
res.send({ res.send({
status: 'ok', status: 'ok',
type, type,
currentAuthority: 'user' currentAuthority: 'user',
}); });
return ; return;
} }
res.send({ res.send({
status: 'error', status: 'error',
type, type,
currentAuthority: 'guest' currentAuthority: 'guest',
}); });
}, },
'POST /api/register': (req, res) => { 'POST /api/register': (req, res) => {
...@@ -97,40 +101,40 @@ const proxy = { ...@@ -97,40 +101,40 @@ const proxy = {
'GET /api/notices': getNotices, 'GET /api/notices': getNotices,
'GET /api/500': (req, res) => { 'GET /api/500': (req, res) => {
res.status(500).send({ res.status(500).send({
"timestamp": 1513932555104, timestamp: 1513932555104,
"status": 500, status: 500,
"error": "error", error: 'error',
"message": "error", message: 'error',
"path": "/base/category/list" path: '/base/category/list',
}); });
}, },
'GET /api/404': (req, res) => { 'GET /api/404': (req, res) => {
res.status(404).send({ res.status(404).send({
"timestamp": 1513932643431, timestamp: 1513932643431,
"status": 404, status: 404,
"error": "Not Found", error: 'Not Found',
"message": "No message available", message: 'No message available',
"path": "/base/category/list/2121212" path: '/base/category/list/2121212',
}); });
}, },
'GET /api/403': (req, res) => { 'GET /api/403': (req, res) => {
res.status(403).send({ res.status(403).send({
"timestamp": 1513932555104, timestamp: 1513932555104,
"status": 403, status: 403,
"error": "Unauthorized", error: 'Unauthorized',
"message": "Unauthorized", message: 'Unauthorized',
"path": "/base/category/list" path: '/base/category/list',
}); });
}, },
'GET /api/401': (req, res) => { 'GET /api/401': (req, res) => {
res.status(401).send({ res.status(401).send({
"timestamp": 1513932555104, timestamp: 1513932555104,
"status": 401, status: 401,
"error": "Unauthorized", error: 'Unauthorized',
"message": "Unauthorized", message: 'Unauthorized',
"path": "/base/category/list" path: '/base/category/list',
}); });
}, },
}; };
export default noProxy ? {} : delay(proxy, 1000); export default (noProxy ? {} : delay(proxy, 1000));
{ {
"extends": "stylelint-config-standard", "extends": ["stylelint-config-standard", "stylelint-config-prettier"],
"rules": { "rules": {
"selector-pseudo-class-no-unknown": null, "selector-pseudo-class-no-unknown": null,
"shorthand-property-no-redundant-values": null, "shorthand-property-no-redundant-values": null,
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
"number-no-trailing-zeros": null, "number-no-trailing-zeros": null,
"rule-empty-line-before": null, "rule-empty-line-before": null,
"selector-combinator-space-after": null, "selector-combinator-space-after": null,
"selector-descendant-combinator-no-non-space": null,
"selector-list-comma-newline-after": null, "selector-list-comma-newline-after": null,
"selector-pseudo-element-colon-notation": null, "selector-pseudo-element-colon-notation": null,
"unit-no-unknown": null, "unit-no-unknown": null,
......
{
"editor.formatOnSave": true
}
...@@ -12,7 +12,7 @@ export default { ...@@ -12,7 +12,7 @@ export default {
}, },
}, },
alias: { alias: {
'components': path.resolve(__dirname, 'src/components/'), components: path.resolve(__dirname, 'src/components/'),
}, },
ignoreMomentLocale: true, ignoreMomentLocale: true,
theme: './src/theme.js', theme: './src/theme.js',
......
...@@ -69,21 +69,23 @@ export function fakeList(count) { ...@@ -69,21 +69,23 @@ export function fakeList(count) {
owner: user[i % 10], owner: user[i % 10],
title: titles[i % 8], title: titles[i % 8],
avatar: avatars[i % 8], avatar: avatars[i % 8],
cover: parseInt(i / 4, 10) % 2 === 0 ? covers[i % 4] : covers[3 - (i % 4)], cover: parseInt(i / 4, 10) % 2 === 0 ? covers[i % 4] : covers[3 - i % 4],
status: ['active', 'exception', 'normal'][i % 3], status: ['active', 'exception', 'normal'][i % 3],
percent: Math.ceil(Math.random() * 50) + 50, percent: Math.ceil(Math.random() * 50) + 50,
logo: avatars[i % 8], logo: avatars[i % 8],
href: 'https://ant.design', href: 'https://ant.design',
updatedAt: new Date(new Date().getTime() - (1000 * 60 * 60 * 2 * i)), updatedAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i),
createdAt: new Date(new Date().getTime() - (1000 * 60 * 60 * 2 * i)), createdAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i),
subDescription: desc[i % 5], subDescription: desc[i % 5],
description: '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。', description:
'在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。',
activeUser: Math.ceil(Math.random() * 100000) + 100000, activeUser: Math.ceil(Math.random() * 100000) + 100000,
newUser: Math.ceil(Math.random() * 1000) + 1000, newUser: Math.ceil(Math.random() * 1000) + 1000,
star: Math.ceil(Math.random() * 100) + 100, star: Math.ceil(Math.random() * 100) + 100,
like: Math.ceil(Math.random() * 100) + 100, like: Math.ceil(Math.random() * 100) + 100,
message: Math.ceil(Math.random() * 10) + 10, message: Math.ceil(Math.random() * 10) + 10,
content: '段落示意:蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。', content:
'段落示意:蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。',
members: [ members: [
{ {
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png', avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png',
...@@ -112,7 +114,7 @@ export function getFakeList(req, res, u) { ...@@ -112,7 +114,7 @@ export function getFakeList(req, res, u) {
const params = parse(url, true).query; const params = parse(url, true).query;
const count = (params.count * 1) || 20; const count = params.count * 1 || 20;
const result = fakeList(count); const result = fakeList(count);
...@@ -287,7 +289,6 @@ export const getActivities = [ ...@@ -287,7 +289,6 @@ export const getActivities = [
}, },
]; ];
export default { export default {
getNotice, getNotice,
getActivities, getActivities,
......
...@@ -7,7 +7,7 @@ const beginDay = new Date().getTime(); ...@@ -7,7 +7,7 @@ const beginDay = new Date().getTime();
const fakeY = [7, 5, 4, 2, 4, 7, 5, 6, 5, 9, 6, 3, 1, 5, 3, 6, 5]; const fakeY = [7, 5, 4, 2, 4, 7, 5, 6, 5, 9, 6, 3, 1, 5, 3, 6, 5];
for (let i = 0; i < fakeY.length; i += 1) { for (let i = 0; i < fakeY.length; i += 1) {
visitData.push({ visitData.push({
x: moment(new Date(beginDay + (1000 * 60 * 60 * 24 * i))).format('YYYY-MM-DD'), x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'),
y: fakeY[i], y: fakeY[i],
}); });
} }
...@@ -16,7 +16,7 @@ const visitData2 = []; ...@@ -16,7 +16,7 @@ const visitData2 = [];
const fakeY2 = [1, 6, 4, 8, 3, 7, 2]; const fakeY2 = [1, 6, 4, 8, 3, 7, 2];
for (let i = 0; i < fakeY2.length; i += 1) { for (let i = 0; i < fakeY2.length; i += 1) {
visitData2.push({ visitData2.push({
x: moment(new Date(beginDay + (1000 * 60 * 60 * 24 * i))).format('YYYY-MM-DD'), x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'),
y: fakeY2[i], y: fakeY2[i],
}); });
} }
...@@ -125,7 +125,7 @@ for (let i = 0; i < 10; i += 1) { ...@@ -125,7 +125,7 @@ for (let i = 0; i < 10; i += 1) {
const offlineChartData = []; const offlineChartData = [];
for (let i = 0; i < 20; i += 1) { for (let i = 0; i < 20; i += 1) {
offlineChartData.push({ offlineChartData.push({
x: (new Date().getTime()) + (1000 * 60 * 30 * i), x: new Date().getTime() + 1000 * 60 * 30 * i,
y1: Math.floor(Math.random() * 100) + 10, y1: Math.floor(Math.random() * 100) + 10,
y2: Math.floor(Math.random() * 100) + 10, y2: Math.floor(Math.random() * 100) + 10,
}); });
...@@ -167,8 +167,8 @@ const radarTitleMap = { ...@@ -167,8 +167,8 @@ const radarTitleMap = {
contribute: '贡献', contribute: '贡献',
hot: '热度', hot: '热度',
}; };
radarOriginData.forEach((item) => { radarOriginData.forEach(item => {
Object.keys(item).forEach((key) => { Object.keys(item).forEach(key => {
if (key !== 'name') { if (key !== 'name') {
radarData.push({ radarData.push({
name: item.name, name: item.name,
......
...@@ -5,9 +5,12 @@ let tableListDataSource = []; ...@@ -5,9 +5,12 @@ let tableListDataSource = [];
for (let i = 0; i < 46; i += 1) { for (let i = 0; i < 46; i += 1) {
tableListDataSource.push({ tableListDataSource.push({
key: i, key: i,
disabled: ((i % 6) === 0), disabled: i % 6 === 0,
href: 'https://ant.design', href: 'https://ant.design',
avatar: ['https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png'][i % 2], avatar: [
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
][i % 2],
no: `TradeCode ${i}`, no: `TradeCode ${i}`,
title: `一个任务名称 ${i}`, title: `一个任务名称 ${i}`,
owner: '曲丽丽', owner: '曲丽丽',
...@@ -43,7 +46,7 @@ export function getRule(req, res, u) { ...@@ -43,7 +46,7 @@ export function getRule(req, res, u) {
if (params.status) { if (params.status) {
const status = params.status.split(','); const status = params.status.split(',');
let filterDataSource = []; let filterDataSource = [];
status.forEach((s) => { status.forEach(s => {
filterDataSource = filterDataSource.concat( filterDataSource = filterDataSource.concat(
[...dataSource].filter(data => parseInt(data.status, 10) === parseInt(s[0], 10)) [...dataSource].filter(data => parseInt(data.status, 10) === parseInt(s[0], 10))
); );
...@@ -95,7 +98,10 @@ export function postRule(req, res, u, b) { ...@@ -95,7 +98,10 @@ export function postRule(req, res, u, b) {
tableListDataSource.unshift({ tableListDataSource.unshift({
key: i, key: i,
href: 'https://ant.design', href: 'https://ant.design',
avatar: ['https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png', 'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png'][i % 2], avatar: [
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
][i % 2],
no: `TradeCode ${i}`, no: `TradeCode ${i}`,
title: `一个任务名称 ${i}`, title: `一个任务名称 ${i}`,
owner: '曲丽丽', owner: '曲丽丽',
......
...@@ -17,7 +17,8 @@ ...@@ -17,7 +17,8 @@
"lint-staged:js": "eslint --ext .js", "lint-staged:js": "eslint --ext .js",
"test": "roadhog test", "test": "roadhog test",
"test:component": "roadhog test ./src/components", "test:component": "roadhog test ./src/components",
"test:all": "node ./tests/run-tests.js" "test:all": "node ./tests/run-tests.js",
"prettier": "prettier --write ./src/**/**/**/*"
}, },
"dependencies": { "dependencies": {
"@antv/data-set": "^0.8.0", "@antv/data-set": "^0.8.0",
...@@ -64,31 +65,31 @@ ...@@ -64,31 +65,31 @@
"eslint-plugin-jsx-a11y": "^6.0.3", "eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-markdown": "^1.0.0-beta.6", "eslint-plugin-markdown": "^1.0.0-beta.6",
"eslint-plugin-react": "^7.0.1", "eslint-plugin-react": "^7.0.1",
"eslint-config-prettier": "^2.9.0",
"gh-pages": "^1.0.0", "gh-pages": "^1.0.0",
"husky": "^0.14.3", "husky": "^0.14.3",
"lint-staged": "^6.0.0", "lint-staged": "^6.0.0",
"mockjs": "^1.0.1-beta3", "mockjs": "^1.0.1-beta3",
"prettier": "1.11.1",
"pro-download": "^1.0.1", "pro-download": "^1.0.1",
"redbox-react": "^1.5.0", "redbox-react": "^1.5.0",
"regenerator-runtime": "^0.11.1", "regenerator-runtime": "^0.11.1",
"roadhog": "^2.3.0", "roadhog": "^2.3.0",
"roadhog-api-doc": "^0.3.4", "roadhog-api-doc": "^0.3.4",
"stylelint": "^8.4.0", "stylelint": "^8.4.0",
"stylelint-config-prettier": "^3.0.4",
"stylelint-config-standard": "^18.0.0" "stylelint-config-standard": "^18.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"puppeteer": "^1.1.1" "puppeteer": "^1.1.1"
}, },
"lint-staged": { "lint-staged": {
"**/*.{js,jsx,less}": ["prettier --wirter", "git add"],
"**/*.{js,jsx}": "lint-staged:js", "**/*.{js,jsx}": "lint-staged:js",
"**/*.less": "stylelint --syntax less" "**/*.less": "stylelint --syntax less"
}, },
"engines": { "engines": {
"node": ">=8.0.0" "node": ">=8.0.0"
}, },
"browserslist": [ "browserslist": ["> 1%", "last 2 versions", "not ie <= 10"]
"> 1%",
"last 2 versions",
"not ie <= 10"
]
} }
import { isUrl } from '../utils/utils'; import { isUrl } from '../utils/utils';
const menuData = [{ const menuData = [
{
name: 'dashboard', name: 'dashboard',
icon: 'dashboard', icon: 'dashboard',
path: 'dashboard', path: 'dashboard',
children: [{ children: [
{
name: '分析页', name: '分析页',
path: 'analysis', path: 'analysis',
}, { },
{
name: '监控页', name: '监控页',
path: 'monitor', path: 'monitor',
}, { },
{
name: '工作台', name: '工作台',
path: 'workplace', path: 'workplace',
// hideInBreadcrumb: true, // hideInBreadcrumb: true,
// hideInMenu: true, // hideInMenu: true,
}], },
}, { ],
},
{
name: '表单页', name: '表单页',
icon: 'form', icon: 'form',
path: 'form', path: 'form',
children: [{ children: [
{
name: '基础表单', name: '基础表单',
path: 'basic-form', path: 'basic-form',
}, { },
{
name: '分步表单', name: '分步表单',
path: 'step-form', path: 'step-form',
}, { },
{
name: '高级表单', name: '高级表单',
authority: 'admin', authority: 'admin',
path: 'advanced-form', path: 'advanced-form',
}], },
}, { ],
},
{
name: '列表页', name: '列表页',
icon: 'table', icon: 'table',
path: 'list', path: 'list',
children: [{ children: [
{
name: '查询表格', name: '查询表格',
path: 'table-list', path: 'table-list',
}, { },
{
name: '标准列表', name: '标准列表',
path: 'basic-list', path: 'basic-list',
}, { },
{
name: '卡片列表', name: '卡片列表',
path: 'card-list', path: 'card-list',
}, { },
{
name: '搜索列表', name: '搜索列表',
path: 'search', path: 'search',
children: [{ children: [
{
name: '搜索列表(文章)', name: '搜索列表(文章)',
path: 'articles', path: 'articles',
}, { },
{
name: '搜索列表(项目)', name: '搜索列表(项目)',
path: 'projects', path: 'projects',
}, { },
{
name: '搜索列表(应用)', name: '搜索列表(应用)',
path: 'applications', path: 'applications',
}], },
}], ],
}, { },
],
},
{
name: '详情页', name: '详情页',
icon: 'profile', icon: 'profile',
path: 'profile', path: 'profile',
children: [{ children: [
{
name: '基础详情页', name: '基础详情页',
path: 'basic', path: 'basic',
}, { },
{
name: '高级详情页', name: '高级详情页',
path: 'advanced', path: 'advanced',
authority: 'admin', authority: 'admin',
}], },
}, { ],
},
{
name: '结果页', name: '结果页',
icon: 'check-circle-o', icon: 'check-circle-o',
path: 'result', path: 'result',
children: [{ children: [
{
name: '成功', name: '成功',
path: 'success', path: 'success',
}, { },
{
name: '失败', name: '失败',
path: 'fail', path: 'fail',
}], },
}, { ],
},
{
name: '异常页', name: '异常页',
icon: 'warning', icon: 'warning',
path: 'exception', path: 'exception',
children: [{ children: [
{
name: '403', name: '403',
path: '403', path: '403',
}, { },
{
name: '404', name: '404',
path: '404', path: '404',
}, { },
{
name: '500', name: '500',
path: '500', path: '500',
}, { },
{
name: '触发异常', name: '触发异常',
path: 'trigger', path: 'trigger',
hideInMenu: true, hideInMenu: true,
}], },
}, { ],
},
{
name: '账户', name: '账户',
icon: 'user', icon: 'user',
path: 'user', path: 'user',
authority: 'guest', authority: 'guest',
children: [{ children: [
{
name: '登录', name: '登录',
path: 'login', path: 'login',
}, { },
{
name: '注册', name: '注册',
path: 'register', path: 'register',
}, { },
{
name: '注册结果', name: '注册结果',
path: 'register-result', path: 'register-result',
}], },
}]; ],
},
];
function formatter(data, parentPath = '/', parentAuthority) { function formatter(data, parentPath = '/', parentAuthority) {
return data.map((item) => { return data.map(item => {
let { path } = item; let { path } = item;
if (!isUrl(path)) { if (!isUrl(path)) {
path = parentPath + item.path; path = parentPath + item.path;
......
...@@ -5,25 +5,24 @@ import { getMenuData } from './menu'; ...@@ -5,25 +5,24 @@ import { getMenuData } from './menu';
let routerDataCache; let routerDataCache;
const modelNotExisted = (app, model) => ( const modelNotExisted = (app, model) =>
// eslint-disable-next-line // eslint-disable-next-line
!app._models.some(({ namespace }) => { !app._models.some(({ namespace }) => {
return namespace === model.substring(model.lastIndexOf('/') + 1); return namespace === model.substring(model.lastIndexOf('/') + 1);
}) });
);
// wrapper of dynamic // wrapper of dynamic
const dynamicWrapper = (app, models, component) => { const dynamicWrapper = (app, models, component) => {
// () => require('module') // () => require('module')
// transformed by babel-plugin-dynamic-import-node-sync // transformed by babel-plugin-dynamic-import-node-sync
if (component.toString().indexOf('.then(') < 0) { if (component.toString().indexOf('.then(') < 0) {
models.forEach((model) => { models.forEach(model => {
if (modelNotExisted(app, model)) { if (modelNotExisted(app, model)) {
// eslint-disable-next-line // eslint-disable-next-line
app.model(require(`../models/${model}`).default); app.model(require(`../models/${model}`).default);
} }
}); });
return (props) => { return props => {
if (!routerDataCache) { if (!routerDataCache) {
routerDataCache = getRouterData(app); routerDataCache = getRouterData(app);
} }
...@@ -36,17 +35,17 @@ const dynamicWrapper = (app, models, component) => { ...@@ -36,17 +35,17 @@ const dynamicWrapper = (app, models, component) => {
// () => import('module') // () => import('module')
return dynamic({ return dynamic({
app, app,
models: () => models.filter( models: () =>
model => modelNotExisted(app, model)).map(m => import(`../models/${m}.js`) models.filter(model => modelNotExisted(app, model)).map(m => import(`../models/${m}.js`)),
),
// add routerData prop // add routerData prop
component: () => { component: () => {
if (!routerDataCache) { if (!routerDataCache) {
routerDataCache = getRouterData(app); routerDataCache = getRouterData(app);
} }
return component().then((raw) => { return component().then(raw => {
const Component = raw.default || raw; const Component = raw.default || raw;
return props => createElement(Component, { return props =>
createElement(Component, {
...props, ...props,
routerData: routerDataCache, routerData: routerDataCache,
}); });
...@@ -57,7 +56,7 @@ const dynamicWrapper = (app, models, component) => { ...@@ -57,7 +56,7 @@ const dynamicWrapper = (app, models, component) => {
function getFlatMenuData(menus) { function getFlatMenuData(menus) {
let keys = {}; let keys = {};
menus.forEach((item) => { menus.forEach(item => {
if (item.children) { if (item.children) {
keys[item.path] = { ...item }; keys[item.path] = { ...item };
keys = { ...keys, ...getFlatMenuData(item.children) }; keys = { ...keys, ...getFlatMenuData(item.children) };
...@@ -68,7 +67,7 @@ function getFlatMenuData(menus) { ...@@ -68,7 +67,7 @@ function getFlatMenuData(menus) {
return keys; return keys;
} }
export const getRouterData = (app) => { export const getRouterData = app => {
const routerConfig = { const routerConfig = {
'/': { '/': {
component: dynamicWrapper(app, ['user', 'login'], () => import('../layouts/BasicLayout')), component: dynamicWrapper(app, ['user', 'login'], () => import('../layouts/BasicLayout')),
...@@ -80,7 +79,9 @@ export const getRouterData = (app) => { ...@@ -80,7 +79,9 @@ export const getRouterData = (app) => {
component: dynamicWrapper(app, ['monitor'], () => import('../routes/Dashboard/Monitor')), component: dynamicWrapper(app, ['monitor'], () => import('../routes/Dashboard/Monitor')),
}, },
'/dashboard/workplace': { '/dashboard/workplace': {
component: dynamicWrapper(app, ['project', 'activities', 'chart'], () => import('../routes/Dashboard/Workplace')), component: dynamicWrapper(app, ['project', 'activities', 'chart'], () =>
import('../routes/Dashboard/Workplace')
),
// hideInBreadcrumb: true, // hideInBreadcrumb: true,
// name: '工作台', // name: '工作台',
// authority: 'admin', // authority: 'admin',
...@@ -131,7 +132,9 @@ export const getRouterData = (app) => { ...@@ -131,7 +132,9 @@ export const getRouterData = (app) => {
component: dynamicWrapper(app, ['profile'], () => import('../routes/Profile/BasicProfile')), component: dynamicWrapper(app, ['profile'], () => import('../routes/Profile/BasicProfile')),
}, },
'/profile/advanced': { '/profile/advanced': {
component: dynamicWrapper(app, ['profile'], () => import('../routes/Profile/AdvancedProfile')), component: dynamicWrapper(app, ['profile'], () =>
import('../routes/Profile/AdvancedProfile')
),
}, },
'/result/success': { '/result/success': {
component: dynamicWrapper(app, [], () => import('../routes/Result/Success')), component: dynamicWrapper(app, [], () => import('../routes/Result/Success')),
...@@ -149,7 +152,9 @@ export const getRouterData = (app) => { ...@@ -149,7 +152,9 @@ export const getRouterData = (app) => {
component: dynamicWrapper(app, [], () => import('../routes/Exception/500')), component: dynamicWrapper(app, [], () => import('../routes/Exception/500')),
}, },
'/exception/trigger': { '/exception/trigger': {
component: dynamicWrapper(app, ['error'], () => import('../routes/Exception/triggerException')), component: dynamicWrapper(app, ['error'], () =>
import('../routes/Exception/triggerException')
),
}, },
'/user': { '/user': {
component: dynamicWrapper(app, [], () => import('../layouts/UserLayout')), component: dynamicWrapper(app, [], () => import('../layouts/UserLayout')),
...@@ -174,7 +179,7 @@ export const getRouterData = (app) => { ...@@ -174,7 +179,7 @@ export const getRouterData = (app) => {
// eg. {name,authority ...routerConfig } // eg. {name,authority ...routerConfig }
const routerData = {}; const routerData = {};
// The route matches the menu // The route matches the menu
Object.keys(routerConfig).forEach((path) => { Object.keys(routerConfig).forEach(path => {
// Regular match item name // Regular match item name
// eg. router /user/:id === /user/chen // eg. router /user/:id === /user/chen
const pathRegexp = pathToRegexp(path); const pathRegexp = pathToRegexp(path);
......
...@@ -14,7 +14,7 @@ function getActiveData() { ...@@ -14,7 +14,7 @@ function getActiveData() {
for (let i = 0; i < 24; i += 1) { for (let i = 0; i < 24; i += 1) {
activeData.push({ activeData.push({
x: `${fixedZero(i)}:00`, x: `${fixedZero(i)}:00`,
y: Math.floor(Math.random() * 200) + (i * 50), y: Math.floor(Math.random() * 200) + i * 50,
}); });
} }
return activeData; return activeData;
......
...@@ -4,29 +4,13 @@ import Authorized from './Authorized'; ...@@ -4,29 +4,13 @@ import Authorized from './Authorized';
class AuthorizedRoute extends React.Component { class AuthorizedRoute extends React.Component {
render() { render() {
const { const { component: Component, render, authority, redirectPath, ...rest } = this.props;
component: Component,
render,
authority,
redirectPath,
...rest
} = this.props;
return ( return (
<Authorized <Authorized
authority={authority} authority={authority}
noMatch={ noMatch={<Route {...rest} render={() => <Redirect to={{ pathname: redirectPath }} />} />}
<Route
{...rest}
render={() => <Redirect to={{ pathname: redirectPath }} />}
/>
}
> >
<Route <Route {...rest} render={props => (Component ? <Component {...props} /> : render(props))} />
{...rest}
render={props =>
(Component ? <Component {...props} /> : render(props))
}
/>
</Authorized> </Authorized>
); );
} }
......
...@@ -20,24 +20,16 @@ describe('test CheckPermissions', () => { ...@@ -20,24 +20,16 @@ describe('test CheckPermissions', () => {
expect(checkPermissions('admin', 'user', target, error)).toEqual('error'); expect(checkPermissions('admin', 'user', target, error)).toEqual('error');
}); });
it('Correct Array permission authentication', () => { it('Correct Array permission authentication', () => {
expect(checkPermissions(['user', 'admin'], 'user', target, error)).toEqual( expect(checkPermissions(['user', 'admin'], 'user', target, error)).toEqual('ok');
'ok'
);
}); });
it('Wrong Array permission authentication,currentAuthority error', () => { it('Wrong Array permission authentication,currentAuthority error', () => {
expect( expect(checkPermissions(['user', 'admin'], 'user,admin', target, error)).toEqual('error');
checkPermissions(['user', 'admin'], 'user,admin', target, error)
).toEqual('error');
}); });
it('Wrong Array permission authentication', () => { it('Wrong Array permission authentication', () => {
expect(checkPermissions(['user', 'admin'], 'guest', target, error)).toEqual( expect(checkPermissions(['user', 'admin'], 'guest', target, error)).toEqual('error');
'error'
);
}); });
it('Wrong Function permission authentication', () => { it('Wrong Function permission authentication', () => {
expect(checkPermissions(() => false, 'guest', target, error)).toEqual( expect(checkPermissions(() => false, 'guest', target, error)).toEqual('error');
'error'
);
}); });
it('Correct Function permission authentication', () => { it('Correct Function permission authentication', () => {
expect(checkPermissions(() => true, 'guest', target, error)).toEqual('ok'); expect(checkPermissions(() => true, 'guest', target, error)).toEqual('ok');
......
...@@ -32,7 +32,7 @@ export default class PromiseRender extends React.PureComponent { ...@@ -32,7 +32,7 @@ export default class PromiseRender extends React.PureComponent {
// AuthorizedRoute is already instantiated // AuthorizedRoute is already instantiated
// Authorized render is already instantiated, children is no instantiated // Authorized render is already instantiated, children is no instantiated
// Secured is not instantiated // Secured is not instantiated
checkIsInstantiation = (target) => { checkIsInstantiation = target => {
if (!React.isValidElement(target)) { if (!React.isValidElement(target)) {
return target; return target;
} }
......
...@@ -5,15 +5,13 @@ import CheckPermissions from './CheckPermissions'; ...@@ -5,15 +5,13 @@ import CheckPermissions from './CheckPermissions';
* 默认不能访问任何页面 * 默认不能访问任何页面
* default is "NULL" * default is "NULL"
*/ */
const Exception403 = () => ( const Exception403 = () => <Exception type="403" style={{ minHeight: 500, height: '80%' }} />;
<Exception type="403" style={{ minHeight: 500, height: '80%' }} />
);
// Determine whether the incoming component has been instantiated // Determine whether the incoming component has been instantiated
// AuthorizedRoute is already instantiated // AuthorizedRoute is already instantiated
// Authorized render is already instantiated, children is no instantiated // Authorized render is already instantiated, children is no instantiated
// Secured is not instantiated // Secured is not instantiated
const checkIsInstantiation = (target) => { const checkIsInstantiation = target => {
if (!React.isValidElement(target)) { if (!React.isValidElement(target)) {
return target; return target;
} }
......
...@@ -11,24 +11,19 @@ export type IReactComponent<P = any> = ...@@ -11,24 +11,19 @@ export type IReactComponent<P = any> =
| React.ClassicComponentClass<P>; | React.ClassicComponentClass<P>;
interface Secured { interface Secured {
(authority: authority, error?: React.ReactNode): <T extends IReactComponent>( (authority: authority, error?: React.ReactNode): <T extends IReactComponent>(target: T) => T;
target: T,
) => T;
} }
export interface AuthorizedRouteProps extends RouteProps { export interface AuthorizedRouteProps extends RouteProps {
authority: authority; authority: authority;
} }
export class AuthorizedRoute extends React.Component< export class AuthorizedRoute extends React.Component<AuthorizedRouteProps, any> {}
AuthorizedRouteProps,
any
> {}
interface check { interface check {
<T extends IReactComponent, S extends IReactComponent>( <T extends IReactComponent, S extends IReactComponent>(
authority: authority, authority: authority,
target: T, target: T,
Exception: S, Exception: S
): T | S; ): T | S;
} }
......
...@@ -14,7 +14,7 @@ Authorized.check = check; ...@@ -14,7 +14,7 @@ Authorized.check = check;
* use authority or getAuthority * use authority or getAuthority
* @param {string|()=>String} currentAuthority * @param {string|()=>String} currentAuthority
*/ */
const renderAuthorize = (currentAuthority) => { const renderAuthorize = currentAuthority => {
if (currentAuthority) { if (currentAuthority) {
if (currentAuthority.constructor.name === 'Function') { if (currentAuthority.constructor.name === 'Function') {
CURRENT = currentAuthority(); CURRENT = currentAuthority();
......
...@@ -4,9 +4,7 @@ import AvatarItem from './AvatarItem'; ...@@ -4,9 +4,7 @@ import AvatarItem from './AvatarItem';
export interface IAvatarListProps { export interface IAvatarListProps {
size?: 'large' | 'small' | 'mini' | 'default'; size?: 'large' | 'small' | 'mini' | 'default';
style?: React.CSSProperties; style?: React.CSSProperties;
children: children: React.ReactElement<AvatarItem> | Array<React.ReactElement<AvatarItem>>;
| React.ReactElement<AvatarItem>
| Array<React.ReactElement<AvatarItem>>;
} }
export default class AvatarList extends React.Component<IAvatarListProps, any> { export default class AvatarList extends React.Component<IAvatarListProps, any> {
......
...@@ -18,7 +18,7 @@ const AvatarList = ({ children, size, ...other }) => { ...@@ -18,7 +18,7 @@ const AvatarList = ({ children, size, ...other }) => {
); );
}; };
const Item = ({ src, size, tips, onClick = (() => {}) }) => { const Item = ({ src, size, tips, onClick = () => {} }) => {
const cls = classNames(styles.avatarItem, { const cls = classNames(styles.avatarItem, {
[styles.avatarItemLarge]: size === 'large', [styles.avatarItemLarge]: size === 'large',
[styles.avatarItemSmall]: size === 'small', [styles.avatarItemSmall]: size === 'small',
...@@ -26,14 +26,14 @@ const Item = ({ src, size, tips, onClick = (() => {}) }) => { ...@@ -26,14 +26,14 @@ const Item = ({ src, size, tips, onClick = (() => {}) }) => {
}); });
return ( return (
<li className={cls} onClick={onClick} > <li className={cls} onClick={onClick}>
{ {tips ? (
tips ? (
<Tooltip title={tips}> <Tooltip title={tips}>
<Avatar src={src} size={size} style={{ cursor: 'pointer' }} /> <Avatar src={src} size={size} style={{ cursor: 'pointer' }} />
</Tooltip> </Tooltip>
) : <Avatar src={src} size={size} /> ) : (
} <Avatar src={src} size={size} />
)}
</li> </li>
); );
}; };
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.avatarList { .avatarList {
display: inline-block; display: inline-block;
......
import * as React from "react"; import * as React from 'react';
export interface IBarProps { export interface IBarProps {
title: React.ReactNode; title: React.ReactNode;
color?: string; color?: string;
......
...@@ -46,11 +46,11 @@ class Bar extends Component { ...@@ -46,11 +46,11 @@ class Bar extends Component {
} }
} }
handleRoot = (n) => { handleRoot = n => {
this.root = n; this.root = n;
}; };
handleRef = (n) => { handleRef = n => {
this.node = n; this.node = n;
}; };
......
import * as React from "react"; import * as React from 'react';
export interface IChartCardProps { export interface IChartCardProps {
title: React.ReactNode; title: React.ReactNode;
action?: React.ReactNode; action?: React.ReactNode;
......
...@@ -4,7 +4,7 @@ import classNames from 'classnames'; ...@@ -4,7 +4,7 @@ import classNames from 'classnames';
import styles from './index.less'; import styles from './index.less';
const renderTotal = (total) => { const renderTotal = total => {
let totalDom; let totalDom;
switch (typeof total) { switch (typeof total) {
case undefined: case undefined:
...@@ -33,7 +33,9 @@ const ChartCard = ({ ...@@ -33,7 +33,9 @@ const ChartCard = ({
const content = ( const content = (
<div className={styles.chartCard}> <div className={styles.chartCard}>
<div <div
className={classNames(styles.chartTop, { [styles.chartTopMargin]: !children && !footer })} className={classNames(styles.chartTop, {
[styles.chartTopMargin]: !children && !footer,
})}
> >
<div className={styles.avatar}>{avatar}</div> <div className={styles.avatar}>{avatar}</div>
<div className={styles.metaWrap}> <div className={styles.metaWrap}>
...@@ -50,7 +52,11 @@ const ChartCard = ({ ...@@ -50,7 +52,11 @@ const ChartCard = ({
</div> </div>
)} )}
{footer && ( {footer && (
<div className={classNames(styles.footer, { [styles.footerMargin]: !children })}> <div
className={classNames(styles.footer, {
[styles.footerMargin]: !children,
})}
>
{footer} {footer}
</div> </div>
)} )}
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.chartCard { .chartCard {
position: relative; position: relative;
......
import * as React from "react"; import * as React from 'react';
export interface IFieldProps { export interface IFieldProps {
label: React.ReactNode; label: React.ReactNode;
value: React.ReactNode; value: React.ReactNode;
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.field { .field {
white-space: nowrap; white-space: nowrap;
......
import * as React from "react"; import * as React from 'react';
export interface IGaugeProps { export interface IGaugeProps {
title: React.ReactNode; title: React.ReactNode;
color?: string; color?: string;
......
...@@ -4,7 +4,7 @@ import autoHeight from '../autoHeight'; ...@@ -4,7 +4,7 @@ import autoHeight from '../autoHeight';
const { Arc, Html, Line } = Guide; const { Arc, Html, Line } = Guide;
const defaultFormatter = (val) => { const defaultFormatter = val => {
switch (val) { switch (val) {
case '2': case '2':
return '差'; return '差';
......
import * as React from "react"; import * as React from 'react';
export interface IMiniProgressProps { export interface IMiniProgressProps {
target: number; target: number;
color?: string; color?: string;
...@@ -7,7 +7,4 @@ export interface IMiniProgressProps { ...@@ -7,7 +7,4 @@ export interface IMiniProgressProps {
style?: React.CSSProperties; style?: React.CSSProperties;
} }
export default class MiniProgress extends React.Component< export default class MiniProgress extends React.Component<IMiniProgressProps, any> {}
IMiniProgressProps,
any
> {}
...@@ -6,21 +6,18 @@ import styles from './index.less'; ...@@ -6,21 +6,18 @@ import styles from './index.less';
const MiniProgress = ({ target, color = 'rgb(19, 194, 194)', strokeWidth, percent }) => ( const MiniProgress = ({ target, color = 'rgb(19, 194, 194)', strokeWidth, percent }) => (
<div className={styles.miniProgress}> <div className={styles.miniProgress}>
<Tooltip title={`目标值: ${target}%`}> <Tooltip title={`目标值: ${target}%`}>
<div <div className={styles.target} style={{ left: target ? `${target}%` : null }}>
className={styles.target} <span style={{ backgroundColor: color || null }} />
style={{ left: (target ? `${target}%` : null) }} <span style={{ backgroundColor: color || null }} />
>
<span style={{ backgroundColor: (color || null) }} />
<span style={{ backgroundColor: (color || null) }} />
</div> </div>
</Tooltip> </Tooltip>
<div className={styles.progressWrap}> <div className={styles.progressWrap}>
<div <div
className={styles.progress} className={styles.progress}
style={{ style={{
backgroundColor: (color || null), backgroundColor: color || null,
width: (percent ? `${percent}%` : null), width: percent ? `${percent}%` : null,
height: (strokeWidth || null), height: strokeWidth || null,
}} }}
/> />
</div> </div>
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.miniProgress { .miniProgress {
padding: 5px 0; padding: 5px 0;
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
position: relative; position: relative;
} }
.progress { .progress {
transition: all .4s cubic-bezier(.08, .82, .17, 1) 0s; transition: all 0.4s cubic-bezier(0.08, 0.82, 0.17, 1) 0s;
border-radius: 1px 0 0 1px; border-radius: 1px 0 0 1px;
background-color: @primary-color; background-color: @primary-color;
width: 0; width: 0;
......
...@@ -44,7 +44,7 @@ export default class Pie extends Component { ...@@ -44,7 +44,7 @@ export default class Pie extends Component {
this.resize.cancel(); this.resize.cancel();
} }
getG2Instance = (chart) => { getG2Instance = chart => {
this.chart = chart; this.chart = chart;
}; };
...@@ -54,7 +54,7 @@ export default class Pie extends Component { ...@@ -54,7 +54,7 @@ export default class Pie extends Component {
const geom = this.chart.getAllGeoms()[0]; // 获取所有的图形 const geom = this.chart.getAllGeoms()[0]; // 获取所有的图形
const items = geom.get('dataArray') || []; // 获取图形对应的 const items = geom.get('dataArray') || []; // 获取图形对应的
const legendData = items.map((item) => { const legendData = items.map(item => {
/* eslint no-underscore-dangle:0 */ /* eslint no-underscore-dangle:0 */
const origin = item[0]._origin; const origin = item[0]._origin;
origin.color = item[0].color; origin.color = item[0].color;
...@@ -89,7 +89,7 @@ export default class Pie extends Component { ...@@ -89,7 +89,7 @@ export default class Pie extends Component {
} }
} }
handleRoot = (n) => { handleRoot = n => {
this.root = n; this.root = n;
}; };
...@@ -154,7 +154,7 @@ export default class Pie extends Component { ...@@ -154,7 +154,7 @@ export default class Pie extends Component {
if (percent) { if (percent) {
selected = false; selected = false;
tooltip = false; tooltip = false;
formatColor = (value) => { formatColor = value => {
if (value === '占比') { if (value === '占比') {
return color || 'rgba(24, 144, 255, 0.85)'; return color || 'rgba(24, 144, 255, 0.85)';
} else { } else {
...@@ -235,7 +235,9 @@ export default class Pie extends Component { ...@@ -235,7 +235,9 @@ export default class Pie extends Component {
<li key={item.x} onClick={() => this.handleLegendClick(item, i)}> <li key={item.x} onClick={() => this.handleLegendClick(item, i)}>
<span <span
className={styles.dot} className={styles.dot}
style={{ backgroundColor: !item.checked ? '#aaa' : item.color }} style={{
backgroundColor: !item.checked ? '#aaa' : item.color,
}}
/> />
<span className={styles.legendTitle}>{item.x}</span> <span className={styles.legendTitle}>{item.x}</span>
<Divider type="vertical" /> <Divider type="vertical" />
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.pie { .pie {
position: relative; position: relative;
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
position: relative; position: relative;
} }
&.hasLegend .chart { &.hasLegend .chart {
width: ~"calc(100% - 240px)"; width: ~'calc(100% - 240px)';
} }
.legend { .legend {
position: absolute; position: absolute;
......
import * as React from "react"; import * as React from 'react';
export interface IRadarProps { export interface IRadarProps {
title?: React.ReactNode; title?: React.ReactNode;
height: number; height: number;
......
...@@ -21,7 +21,7 @@ export default class Radar extends Component { ...@@ -21,7 +21,7 @@ export default class Radar extends Component {
} }
} }
getG2Instance = (chart) => { getG2Instance = chart => {
this.chart = chart; this.chart = chart;
}; };
...@@ -31,7 +31,7 @@ export default class Radar extends Component { ...@@ -31,7 +31,7 @@ export default class Radar extends Component {
const geom = this.chart.getAllGeoms()[0]; // 获取所有的图形 const geom = this.chart.getAllGeoms()[0]; // 获取所有的图形
const items = geom.get('dataArray') || []; // 获取图形对应的 const items = geom.get('dataArray') || []; // 获取图形对应的
const legendData = items.map((item) => { const legendData = items.map(item => {
// eslint-disable-next-line // eslint-disable-next-line
const origins = item.map(t => t._origin); const origins = item.map(t => t._origin);
const result = { const result = {
...@@ -49,7 +49,7 @@ export default class Radar extends Component { ...@@ -49,7 +49,7 @@ export default class Radar extends Component {
}); });
}; };
handleRef = (n) => { handleRef = n => {
this.node = n; this.node = n;
}; };
...@@ -60,9 +60,7 @@ export default class Radar extends Component { ...@@ -60,9 +60,7 @@ export default class Radar extends Component {
const { legendData } = this.state; const { legendData } = this.state;
legendData[i] = newItem; legendData[i] = newItem;
const filteredLegendData = legendData const filteredLegendData = legendData.filter(l => l.checked).map(l => l.name);
.filter(l => l.checked)
.map(l => l.name);
if (this.chart) { if (this.chart) {
this.chart.filter('name', val => filteredLegendData.indexOf(val) > -1); this.chart.filter('name', val => filteredLegendData.indexOf(val) > -1);
...@@ -143,12 +141,7 @@ export default class Radar extends Component { ...@@ -143,12 +141,7 @@ export default class Radar extends Component {
}, },
}} }}
/> />
<Geom <Geom type="line" position="label*value" color={['name', colors]} size={1} />
type="line"
position="label*value"
color={['name', colors]}
size={1}
/>
<Geom <Geom
type="point" type="point"
position="label*value" position="label*value"
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.radar { .radar {
.legend { .legend {
......
import * as React from "react"; import * as React from 'react';
export interface ITagCloudProps { export interface ITagCloudProps {
data: Array<{ data: Array<{
name: string; name: string;
......
...@@ -39,7 +39,7 @@ class TagCloud extends Component { ...@@ -39,7 +39,7 @@ class TagCloud extends Component {
this.renderChart(); this.renderChart();
}; };
saveRootRef = (node) => { saveRootRef = node => {
this.root = node; this.root = node;
}; };
...@@ -77,7 +77,7 @@ class TagCloud extends Component { ...@@ -77,7 +77,7 @@ class TagCloud extends Component {
@Bind() @Bind()
@Debounce(500) @Debounce(500)
renderChart = (nextProps) => { renderChart = nextProps => {
// const colors = ['#1890FF', '#41D9C7', '#2FC25B', '#FACC14', '#9AE65C']; // const colors = ['#1890FF', '#41D9C7', '#2FC25B', '#FACC14', '#9AE65C'];
const { data, height } = nextProps || this.props; const { data, height } = nextProps || this.props;
......
import * as React from "react"; import * as React from 'react';
export interface ITimelineChartProps { export interface ITimelineChartProps {
data: Array<{ data: Array<{
x: string; x: string;
...@@ -11,7 +11,4 @@ export interface ITimelineChartProps { ...@@ -11,7 +11,4 @@ export interface ITimelineChartProps {
style?: React.CSSProperties; style?: React.CSSProperties;
} }
export default class TimelineChart extends React.Component< export default class TimelineChart extends React.Component<ITimelineChartProps, any> {}
ITimelineChartProps,
any
> {}
...@@ -48,7 +48,7 @@ export default class TimelineChart extends React.Component { ...@@ -48,7 +48,7 @@ export default class TimelineChart extends React.Component {
.source(data) .source(data)
.transform({ .transform({
type: 'filter', type: 'filter',
callback: (obj) => { callback: obj => {
const date = obj.x; const date = obj.x;
return date <= ds.state.end && date >= ds.state.start; return date <= ds.state.end && date >= ds.state.start;
}, },
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.waterWave { .waterWave {
display: inline-block; display: inline-block;
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
} }
} }
.waterWaveCanvasWrapper { .waterWaveCanvasWrapper {
transform: scale(.5); transform: scale(0.5);
transform-origin: 0 0; transform-origin: 0 0;
} }
} }
...@@ -30,7 +30,7 @@ function getAutoHeight(n) { ...@@ -30,7 +30,7 @@ function getAutoHeight(n) {
return height; return height;
} }
const autoHeight = () => (WrappedComponent) => { const autoHeight = () => WrappedComponent => {
return class extends React.Component { return class extends React.Component {
state = { state = {
computedHeight: 0, computedHeight: 0,
...@@ -45,7 +45,7 @@ const autoHeight = () => (WrappedComponent) => { ...@@ -45,7 +45,7 @@ const autoHeight = () => (WrappedComponent) => {
} }
} }
handleRoot = (node) => { handleRoot = node => {
this.root = node; this.root = node;
}; };
......
import * as React from "react"; import * as React from 'react';
export interface ICountDownProps { export interface ICountDownProps {
format?: (time: number) => void; format?: (time: number) => void;
target: Date | number; target: Date | number;
......
...@@ -23,11 +23,14 @@ class CountDown extends Component { ...@@ -23,11 +23,14 @@ class CountDown extends Component {
if (this.props.target !== nextProps.target) { if (this.props.target !== nextProps.target) {
clearTimeout(this.timer); clearTimeout(this.timer);
const { lastTime } = this.initTime(nextProps); const { lastTime } = this.initTime(nextProps);
this.setState({ this.setState(
{
lastTime, lastTime,
}, () => { },
() => {
this.tick(); this.tick();
}); }
);
} }
} }
...@@ -37,7 +40,7 @@ class CountDown extends Component { ...@@ -37,7 +40,7 @@ class CountDown extends Component {
timer = 0; timer = 0;
interval = 1000; interval = 1000;
initTime = (props) => { initTime = props => {
let lastTime = 0; let lastTime = 0;
let targetTime = 0; let targetTime = 0;
try { try {
...@@ -54,21 +57,23 @@ class CountDown extends Component { ...@@ -54,21 +57,23 @@ class CountDown extends Component {
return { return {
lastTime: lastTime < 0 ? 0 : lastTime, lastTime: lastTime < 0 ? 0 : lastTime,
}; };
} };
// defaultFormat = time => ( // defaultFormat = time => (
// <span>{moment(time).format('hh:mm:ss')}</span> // <span>{moment(time).format('hh:mm:ss')}</span>
// ); // );
defaultFormat = (time) => { defaultFormat = time => {
const hours = 60 * 60 * 1000; const hours = 60 * 60 * 1000;
const minutes = 60 * 1000; const minutes = 60 * 1000;
const h = Math.floor(time / hours); const h = Math.floor(time / hours);
const m = Math.floor((time - (h * hours)) / minutes); const m = Math.floor((time - h * hours) / minutes);
const s = Math.floor((time - (h * hours) - (m * minutes)) / 1000); const s = Math.floor((time - h * hours - m * minutes) / 1000);
return ( return (
<span>{fixedZero(h)}:{fixedZero(m)}:{fixedZero(s)}</span> <span>
{fixedZero(h)}:{fixedZero(m)}:{fixedZero(s)}
</span>
); );
} };
tick = () => { tick = () => {
const { onEnd } = this.props; const { onEnd } = this.props;
let { lastTime } = this.state; let { lastTime } = this.state;
...@@ -76,30 +81,36 @@ class CountDown extends Component { ...@@ -76,30 +81,36 @@ class CountDown extends Component {
this.timer = setTimeout(() => { this.timer = setTimeout(() => {
if (lastTime < this.interval) { if (lastTime < this.interval) {
clearTimeout(this.timer); clearTimeout(this.timer);
this.setState({ this.setState(
{
lastTime: 0, lastTime: 0,
}, () => { },
() => {
if (onEnd) { if (onEnd) {
onEnd(); onEnd();
} }
}); }
);
} else { } else {
lastTime -= this.interval; lastTime -= this.interval;
this.setState({ this.setState(
{
lastTime, lastTime,
}, () => { },
() => {
this.tick(); this.tick();
});
} }
}, this.interval); );
} }
}, this.interval);
};
render() { render() {
const { format = this.defaultFormat, onEnd, ...rest } = this.props; const { format = this.defaultFormat, onEnd, ...rest } = this.props;
const { lastTime } = this.state; const { lastTime } = this.state;
const result = format(lastTime); const result = format(lastTime);
return (<span {...rest}>{result}</span>); return <span {...rest}>{result}</span>;
} }
} }
......
...@@ -3,8 +3,16 @@ import classNames from 'classnames'; ...@@ -3,8 +3,16 @@ import classNames from 'classnames';
import { Row } from 'antd'; import { Row } from 'antd';
import styles from './index.less'; import styles from './index.less';
export default ({ className, title, col = 3, layout = 'horizontal', gutter = 32, export default ({
children, size, ...restProps }) => { className,
title,
col = 3,
layout = 'horizontal',
gutter = 32,
children,
size,
...restProps
}) => {
const clsString = classNames(styles.descriptionList, styles[layout], className, { const clsString = classNames(styles.descriptionList, styles[layout], className, {
[styles.small]: size === 'small', [styles.small]: size === 'small',
[styles.large]: size === 'large', [styles.large]: size === 'large',
......
...@@ -10,9 +10,6 @@ export interface IDescriptionListProps { ...@@ -10,9 +10,6 @@ export interface IDescriptionListProps {
style?: React.CSSProperties; style?: React.CSSProperties;
} }
export default class DescriptionList extends React.Component< export default class DescriptionList extends React.Component<IDescriptionListProps, any> {
IDescriptionListProps,
any
> {
public static Description: typeof Description; public static Description: typeof Description;
} }
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.descriptionList { .descriptionList {
// offset the padding-bottom of last row // offset the padding-bottom of last row
...@@ -25,10 +25,10 @@ ...@@ -25,10 +25,10 @@
display: table-cell; display: table-cell;
&:after { &:after {
content: ":"; content: ':';
margin: 0 8px 0 2px; margin: 0 8px 0 2px;
position: relative; position: relative;
top: -.5px; top: -0.5px;
} }
} }
...@@ -51,7 +51,8 @@ ...@@ -51,7 +51,8 @@
margin-bottom: 12px; margin-bottom: 12px;
color: @text-color; color: @text-color;
} }
.term, .detail { .term,
.detail {
padding-bottom: 8px; padding-bottom: 8px;
} }
} }
......
...@@ -7,48 +7,34 @@ export default class EditableItem extends PureComponent { ...@@ -7,48 +7,34 @@ export default class EditableItem extends PureComponent {
value: this.props.value, value: this.props.value,
editable: false, editable: false,
}; };
handleChange = (e) => { handleChange = e => {
const { value } = e.target; const { value } = e.target;
this.setState({ value }); this.setState({ value });
} };
check = () => { check = () => {
this.setState({ editable: false }); this.setState({ editable: false });
if (this.props.onChange) { if (this.props.onChange) {
this.props.onChange(this.state.value); this.props.onChange(this.state.value);
} }
} };
edit = () => { edit = () => {
this.setState({ editable: true }); this.setState({ editable: true });
} };
render() { render() {
const { value, editable } = this.state; const { value, editable } = this.state;
return ( return (
<div className={styles.editableItem}> <div className={styles.editableItem}>
{ {editable ? (
editable ? (
<div className={styles.wrapper}> <div className={styles.wrapper}>
<Input <Input value={value} onChange={this.handleChange} onPressEnter={this.check} />
value={value} <Icon type="check" className={styles.icon} onClick={this.check} />
onChange={this.handleChange}
onPressEnter={this.check}
/>
<Icon
type="check"
className={styles.icon}
onClick={this.check}
/>
</div> </div>
) : ( ) : (
<div className={styles.wrapper}> <div className={styles.wrapper}>
<span>{value || ' '}</span> <span>{value || ' '}</span>
<Icon <Icon type="edit" className={styles.icon} onClick={this.edit} />
type="edit"
className={styles.icon}
onClick={this.edit}
/>
</div> </div>
) )}
}
</div> </div>
); );
} }
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.editableItem { .editableItem {
line-height: @input-height-base; line-height: @input-height-base;
......
...@@ -22,15 +22,17 @@ class EditableLinkGroup extends PureComponent { ...@@ -22,15 +22,17 @@ class EditableLinkGroup extends PureComponent {
const { links, linkElement, onAdd } = this.props; const { links, linkElement, onAdd } = this.props;
return ( return (
<div className={styles.linkGroup}> <div className={styles.linkGroup}>
{links.map(link =>
createElement(
linkElement,
{ {
links.map(link => (
createElement(linkElement, {
key: `linkGroup-item-${link.id || link.title}`, key: `linkGroup-item-${link.id || link.title}`,
to: link.href, to: link.href,
href: link.href, href: link.href,
}, link.title) },
)) link.title
} )
)}
{ {
<Button size="small" type="primary" ghost onClick={onAdd} icon="plus"> <Button size="small" type="primary" ghost onClick={onAdd} icon="plus">
添加 添加
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.linkGroup { .linkGroup {
padding: 20px 0 8px 24px; padding: 20px 0 8px 24px;
......
...@@ -125,23 +125,23 @@ export default class Ellipsis extends Component { ...@@ -125,23 +125,23 @@ export default class Ellipsis extends Component {
} }
}; };
handleRoot = (n) => { handleRoot = n => {
this.root = n; this.root = n;
}; };
handleContent = (n) => { handleContent = n => {
this.content = n; this.content = n;
}; };
handleNode = (n) => { handleNode = n => {
this.node = n; this.node = n;
}; };
handleShadow = (n) => { handleShadow = n => {
this.shadow = n; this.shadow = n;
}; };
handleShadowChildren = (n) => { handleShadowChildren = n => {
this.shadowChildren = n; this.shadowChildren = n;
}; };
......
import * as React from "react"; import * as React from 'react';
export interface IExceptionProps { export interface IExceptionProps {
type?: "403" | "404" | "500"; type?: '403' | '404' | '500';
title?: React.ReactNode; title?: React.ReactNode;
desc?: React.ReactNode; desc?: React.ReactNode;
img?: string; img?: string;
......
...@@ -19,13 +19,15 @@ export default ({ className, linkElement = 'a', type, title, desc, img, actions, ...@@ -19,13 +19,15 @@ export default ({ className, linkElement = 'a', type, title, desc, img, actions,
<h1>{title || config[pageType].title}</h1> <h1>{title || config[pageType].title}</h1>
<div className={styles.desc}>{desc || config[pageType].desc}</div> <div className={styles.desc}>{desc || config[pageType].desc}</div>
<div className={styles.actions}> <div className={styles.actions}>
{actions ||
createElement(
linkElement,
{ {
actions ||
createElement(linkElement, {
to: '/', to: '/',
href: '/', href: '/',
}, <Button type="primary">返回首页</Button>) },
} <Button type="primary">返回首页</Button>
)}
</div> </div>
</div> </div>
</div> </div>
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.exception { .exception {
display: flex; display: flex;
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
zoom: 1; zoom: 1;
&:before, &:before,
&:after { &:after {
content: " "; content: ' ';
display: table; display: table;
} }
&:after { &:after {
......
...@@ -4,7 +4,4 @@ export interface IFooterToolbarProps { ...@@ -4,7 +4,4 @@ export interface IFooterToolbarProps {
style?: React.CSSProperties; style?: React.CSSProperties;
} }
export default class FooterToolbar extends React.Component< export default class FooterToolbar extends React.Component<IFooterToolbarProps, any> {}
IFooterToolbarProps,
any
> {}
...@@ -6,10 +6,7 @@ export default class FooterToolbar extends Component { ...@@ -6,10 +6,7 @@ export default class FooterToolbar extends Component {
render() { render() {
const { children, className, extra, ...restProps } = this.props; const { children, className, extra, ...restProps } = this.props;
return ( return (
<div <div className={classNames(className, styles.toolbar)} {...restProps}>
className={classNames(className, styles.toolbar)}
{...restProps}
>
<div className={styles.left}>{extra}</div> <div className={styles.left}>{extra}</div>
<div className={styles.right}>{children}</div> <div className={styles.right}>{children}</div>
</div> </div>
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.toolbar { .toolbar {
position: fixed; position: fixed;
...@@ -7,14 +7,14 @@ ...@@ -7,14 +7,14 @@
right: 0; right: 0;
height: 56px; height: 56px;
line-height: 56px; line-height: 56px;
box-shadow: 0 -1px 2px rgba(0, 0, 0, .03); box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.03);
background: #fff; background: #fff;
border-top: 1px solid @border-color-split; border-top: 1px solid @border-color-split;
padding: 0 24px; padding: 0 24px;
z-index: 9; z-index: 9;
&:after { &:after {
content: ""; content: '';
display: block; display: block;
clear: both; clear: both;
} }
......
import * as React from "react"; import * as React from 'react';
export interface IGlobalFooterProps { export interface IGlobalFooterProps {
links?: Array<{ links?: Array<{
title: React.ReactNode; title: React.ReactNode;
...@@ -9,7 +9,4 @@ export interface IGlobalFooterProps { ...@@ -9,7 +9,4 @@ export interface IGlobalFooterProps {
style?: React.CSSProperties; style?: React.CSSProperties;
} }
export default class GlobalFooter extends React.Component< export default class GlobalFooter extends React.Component<IGlobalFooterProps, any> {}
IGlobalFooterProps,
any
> {}
...@@ -6,21 +6,15 @@ export default ({ className, links, copyright }) => { ...@@ -6,21 +6,15 @@ export default ({ className, links, copyright }) => {
const clsString = classNames(styles.globalFooter, className); const clsString = classNames(styles.globalFooter, className);
return ( return (
<div className={clsString}> <div className={clsString}>
{ {links && (
links && (
<div className={styles.links}> <div className={styles.links}>
{links.map(link => ( {links.map(link => (
<a <a key={link.key} target={link.blankTarget ? '_blank' : '_self'} href={link.href}>
key={link.key}
target={link.blankTarget ? '_blank' : '_self'}
href={link.href}
>
{link.title} {link.title}
</a> </a>
))} ))}
</div> </div>
) )}
}
{copyright && <div className={styles.copyright}>{copyright}</div>} {copyright && <div className={styles.copyright}>{copyright}</div>}
</div> </div>
); );
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.globalFooter { .globalFooter {
padding: 0 16px; padding: 0 16px;
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
a { a {
color: @text-color-secondary; color: @text-color-secondary;
transition: all .3s; transition: all 0.3s;
&:not(:last-child) { &:not(:last-child) {
margin-right: 40px; margin-right: 40px;
......
...@@ -17,7 +17,7 @@ export default class GlobalHeader extends PureComponent { ...@@ -17,7 +17,7 @@ export default class GlobalHeader extends PureComponent {
if (notices.length === 0) { if (notices.length === 0) {
return {}; return {};
} }
const newNotices = notices.map((notice) => { const newNotices = notices.map(notice => {
const newNotice = { ...notice }; const newNotice = { ...notice };
if (newNotice.datetime) { if (newNotice.datetime) {
newNotice.datetime = moment(notice.datetime).fromNow(); newNotice.datetime = moment(notice.datetime).fromNow();
...@@ -27,13 +27,17 @@ export default class GlobalHeader extends PureComponent { ...@@ -27,13 +27,17 @@ export default class GlobalHeader extends PureComponent {
newNotice.key = newNotice.id; newNotice.key = newNotice.id;
} }
if (newNotice.extra && newNotice.status) { if (newNotice.extra && newNotice.status) {
const color = ({ const color = {
todo: '', todo: '',
processing: 'blue', processing: 'blue',
urgent: 'red', urgent: 'red',
doing: 'gold', doing: 'gold',
})[newNotice.status]; }[newNotice.status];
newNotice.extra = <Tag color={color} style={{ marginRight: 0 }}>{newNotice.extra}</Tag>; newNotice.extra = (
<Tag color={color} style={{ marginRight: 0 }}>
{newNotice.extra}
</Tag>
);
} }
return newNotice; return newNotice;
}); });
...@@ -43,40 +47,50 @@ export default class GlobalHeader extends PureComponent { ...@@ -43,40 +47,50 @@ export default class GlobalHeader extends PureComponent {
const { collapsed, onCollapse } = this.props; const { collapsed, onCollapse } = this.props;
onCollapse(!collapsed); onCollapse(!collapsed);
this.triggerResizeEvent(); this.triggerResizeEvent();
} };
@Debounce(600) @Debounce(600)
triggerResizeEvent() { // eslint-disable-line triggerResizeEvent = () => {
const event = document.createEvent('HTMLEvents'); const event = document.createEvent('HTMLEvents');
event.initEvent('resize', true, false); event.initEvent('resize', true, false);
window.dispatchEvent(event); window.dispatchEvent(event);
} };
render() { render() {
const { const {
currentUser, collapsed, fetchingNotices, isMobile, logo, currentUser,
onNoticeVisibleChange, onMenuClick, onNoticeClear, collapsed,
fetchingNotices,
isMobile,
logo,
onNoticeVisibleChange,
onMenuClick,
onNoticeClear,
} = this.props; } = this.props;
const menu = ( const menu = (
<Menu className={styles.menu} selectedKeys={[]} onClick={onMenuClick}> <Menu className={styles.menu} selectedKeys={[]} onClick={onMenuClick}>
<Menu.Item disabled><Icon type="user" />个人中心</Menu.Item> <Menu.Item disabled>
<Menu.Item disabled><Icon type="setting" />设置</Menu.Item> <Icon type="user" />个人中心
<Menu.Item key="triggerError"><Icon type="close-circle" />触发报错</Menu.Item> </Menu.Item>
<Menu.Item disabled>
<Icon type="setting" />设置
</Menu.Item>
<Menu.Item key="triggerError">
<Icon type="close-circle" />触发报错
</Menu.Item>
<Menu.Divider /> <Menu.Divider />
<Menu.Item key="logout"><Icon type="logout" />退出登录</Menu.Item> <Menu.Item key="logout">
<Icon type="logout" />退出登录
</Menu.Item>
</Menu> </Menu>
); );
const noticeData = this.getNoticeData(); const noticeData = this.getNoticeData();
return ( return (
<div className={styles.header}> <div className={styles.header}>
{isMobile && ( {isMobile && [
[
(
<Link to="/" className={styles.logo} key="logo"> <Link to="/" className={styles.logo} key="logo">
<img src={logo} alt="logo" width="32" /> <img src={logo} alt="logo" width="32" />
</Link> </Link>,
),
<Divider type="vertical" key="line" />, <Divider type="vertical" key="line" />,
] ]}
)}
<Icon <Icon
className={styles.trigger} className={styles.trigger}
type={collapsed ? 'menu-unfold' : 'menu-fold'} type={collapsed ? 'menu-unfold' : 'menu-fold'}
...@@ -87,10 +101,10 @@ export default class GlobalHeader extends PureComponent { ...@@ -87,10 +101,10 @@ export default class GlobalHeader extends PureComponent {
className={`${styles.action} ${styles.search}`} className={`${styles.action} ${styles.search}`}
placeholder="站内搜索" placeholder="站内搜索"
dataSource={['搜索提示一', '搜索提示二', '搜索提示三']} dataSource={['搜索提示一', '搜索提示二', '搜索提示三']}
onSearch={(value) => { onSearch={value => {
console.log('input', value); // eslint-disable-line console.log('input', value); // eslint-disable-line
}} }}
onPressEnter={(value) => { onPressEnter={value => {
console.log('enter', value); // eslint-disable-line console.log('enter', value); // eslint-disable-line
}} }}
/> />
...@@ -102,7 +116,7 @@ export default class GlobalHeader extends PureComponent { ...@@ -102,7 +116,7 @@ export default class GlobalHeader extends PureComponent {
className={styles.action} className={styles.action}
> >
<Icon type="question-circle-o" /> <Icon type="question-circle-o" />
</a > </a>
</Tooltip> </Tooltip>
<NoticeIcon <NoticeIcon
className={styles.action} className={styles.action}
...@@ -141,7 +155,9 @@ export default class GlobalHeader extends PureComponent { ...@@ -141,7 +155,9 @@ export default class GlobalHeader extends PureComponent {
<span className={styles.name}>{currentUser.name}</span> <span className={styles.name}>{currentUser.name}</span>
</span> </span>
</Dropdown> </Dropdown>
) : <Spin size="small" style={{ marginLeft: 8 }} />} ) : (
<Spin size="small" style={{ marginLeft: 8 }} />
)}
</div> </div>
</div> </div>
); );
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.header { .header {
height: 64px; height: 64px;
padding: 0 12px 0 0; padding: 0 12px 0 0;
background: #fff; background: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 41, .08); box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
position: relative; position: relative;
} }
...@@ -42,7 +42,7 @@ i.trigger { ...@@ -42,7 +42,7 @@ i.trigger {
font-size: 20px; font-size: 20px;
line-height: 64px; line-height: 64px;
cursor: pointer; cursor: pointer;
transition: all .3s, padding 0s; transition: all 0.3s, padding 0s;
padding: 0 24px; padding: 0 24px;
&:hover { &:hover {
background: @primary-1; background: @primary-1;
...@@ -56,7 +56,7 @@ i.trigger { ...@@ -56,7 +56,7 @@ i.trigger {
cursor: pointer; cursor: pointer;
padding: 0 12px; padding: 0 12px;
display: inline-block; display: inline-block;
transition: all .3s; transition: all 0.3s;
height: 100%; height: 100%;
> i { > i {
font-size: 16px; font-size: 16px;
...@@ -79,7 +79,7 @@ i.trigger { ...@@ -79,7 +79,7 @@ i.trigger {
.avatar { .avatar {
margin: 20px 8px 20px 0; margin: 20px 8px 20px 0;
color: @primary-color; color: @primary-color;
background: rgba(255, 255, 255, .85); background: rgba(255, 255, 255, 0.85);
vertical-align: middle; vertical-align: middle;
} }
} }
......
...@@ -8,7 +8,4 @@ export interface IHeaderSearchProps { ...@@ -8,7 +8,4 @@ export interface IHeaderSearchProps {
style?: React.CSSProperties; style?: React.CSSProperties;
} }
export default class HeaderSearch extends React.Component< export default class HeaderSearch extends React.Component<IHeaderSearchProps, any> {}
IHeaderSearchProps,
any
> {}
...@@ -28,42 +28,39 @@ export default class HeaderSearch extends PureComponent { ...@@ -28,42 +28,39 @@ export default class HeaderSearch extends PureComponent {
componentWillUnmount() { componentWillUnmount() {
clearTimeout(this.timeout); clearTimeout(this.timeout);
} }
onKeyDown = (e) => { onKeyDown = e => {
if (e.key === 'Enter') { if (e.key === 'Enter') {
this.timeout = setTimeout(() => { this.timeout = setTimeout(() => {
this.props.onPressEnter(this.state.value); // Fix duplicate onPressEnter this.props.onPressEnter(this.state.value); // Fix duplicate onPressEnter
}, 0); }, 0);
} }
} };
onChange = (value) => { onChange = value => {
this.setState({ value }); this.setState({ value });
if (this.props.onChange) { if (this.props.onChange) {
this.props.onChange(); this.props.onChange();
} }
} };
enterSearchMode = () => { enterSearchMode = () => {
this.setState({ searchMode: true }, () => { this.setState({ searchMode: true }, () => {
if (this.state.searchMode) { if (this.state.searchMode) {
this.input.focus(); this.input.focus();
} }
}); });
} };
leaveSearchMode = () => { leaveSearchMode = () => {
this.setState({ this.setState({
searchMode: false, searchMode: false,
value: '', value: '',
}); });
} };
render() { render() {
const { className, placeholder, ...restProps } = this.props; const { className, placeholder, ...restProps } = this.props;
const inputClass = classNames(styles.input, { const inputClass = classNames(styles.input, {
[styles.show]: this.state.searchMode, [styles.show]: this.state.searchMode,
}); });
return ( return (
<span <span className={classNames(className, styles.headerSearch)} onClick={this.enterSearchMode}>
className={classNames(className, styles.headerSearch)}
onClick={this.enterSearchMode}
>
<Icon type="search" key="Icon" /> <Icon type="search" key="Icon" />
<AutoComplete <AutoComplete
key="AutoComplete" key="AutoComplete"
...@@ -74,7 +71,9 @@ export default class HeaderSearch extends PureComponent { ...@@ -74,7 +71,9 @@ export default class HeaderSearch extends PureComponent {
> >
<Input <Input
placeholder={placeholder} placeholder={placeholder}
ref={(node) => { this.input = node; }} ref={node => {
this.input = node;
}}
onKeyDown={this.onKeyDown} onKeyDown={this.onKeyDown}
onBlur={this.leaveSearchMode} onBlur={this.leaveSearchMode}
/> />
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.headerSearch { .headerSearch {
:global(.anticon-search) { :global(.anticon-search) {
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
font-size: 16px; font-size: 16px;
} }
.input { .input {
transition: width .3s, margin-left .3s; transition: width 0.3s, margin-left 0.3s;
width: 0; width: 0;
background: transparent; background: transparent;
border-radius: 0; border-radius: 0;
......
...@@ -8,7 +8,7 @@ import map from './map'; ...@@ -8,7 +8,7 @@ import map from './map';
const FormItem = Form.Item; const FormItem = Form.Item;
function generator({ defaultProps, defaultRules, type }) { function generator({ defaultProps, defaultRules, type }) {
return (WrappedComponent) => { return WrappedComponent => {
return class BasicComponent extends Component { return class BasicComponent extends Component {
static contextTypes = { static contextTypes = {
form: PropTypes.object, form: PropTypes.object,
...@@ -41,7 +41,7 @@ function generator({ defaultProps, defaultRules, type }) { ...@@ -41,7 +41,7 @@ function generator({ defaultProps, defaultRules, type }) {
clearInterval(this.interval); clearInterval(this.interval);
} }
}, 1000); }, 1000);
} };
render() { render() {
const { getFieldDecorator } = this.context.form; const { getFieldDecorator } = this.context.form;
const options = {}; const options = {};
...@@ -93,7 +93,7 @@ function generator({ defaultProps, defaultRules, type }) { ...@@ -93,7 +93,7 @@ function generator({ defaultProps, defaultRules, type }) {
} }
const LoginItem = {}; const LoginItem = {};
Object.keys(map).forEach((item) => { Object.keys(map).forEach(item => {
LoginItem[item] = generator({ LoginItem[item] = generator({
defaultProps: map[item].props, defaultProps: map[item].props,
defaultRules: map[item].rules, defaultRules: map[item].rules,
......
import * as React from "react"; import * as React from 'react';
import Button from "antd/lib/button"; import Button from 'antd/lib/button';
export interface LoginProps { export interface LoginProps {
defaultActiveKey?: string; defaultActiveKey?: string;
onTabChange?: (key: string) => void; onTabChange?: (key: string) => void;
......
...@@ -34,19 +34,19 @@ class Login extends Component { ...@@ -34,19 +34,19 @@ class Login extends Component {
getChildContext() { getChildContext() {
return { return {
tabUtil: { tabUtil: {
addTab: (id) => { addTab: id => {
this.setState({ this.setState({
tabs: [...this.state.tabs, id], tabs: [...this.state.tabs, id],
}); });
}, },
removeTab: (id) => { removeTab: id => {
this.setState({ this.setState({
tabs: this.state.tabs.filter(currentId => currentId !== id), tabs: this.state.tabs.filter(currentId => currentId !== id),
}); });
}, },
}, },
form: this.props.form, form: this.props.form,
updateActive: (activeItem) => { updateActive: activeItem => {
const { type, active } = this.state; const { type, active } = this.state;
if (active[type]) { if (active[type]) {
active[type].push(activeItem); active[type].push(activeItem);
...@@ -59,28 +59,26 @@ class Login extends Component { ...@@ -59,28 +59,26 @@ class Login extends Component {
}, },
}; };
} }
onSwitch = (type) => { onSwitch = type => {
this.setState({ this.setState({
type, type,
}); });
this.props.onTabChange(type); this.props.onTabChange(type);
} };
handleSubmit = (e) => { handleSubmit = e => {
e.preventDefault(); e.preventDefault();
const { active, type } = this.state; const { active, type } = this.state;
const activeFileds = active[type]; const activeFileds = active[type];
this.props.form.validateFields(activeFileds, { force: true }, this.props.form.validateFields(activeFileds, { force: true }, (err, values) => {
(err, values) => {
this.props.onSubmit(err, values); this.props.onSubmit(err, values);
} });
); };
}
render() { render() {
const { className, children } = this.props; const { className, children } = this.props;
const { type, tabs } = this.state; const { type, tabs } = this.state;
const TabChildren = []; const TabChildren = [];
const otherChildren = []; const otherChildren = [];
React.Children.forEach(children, (item) => { React.Children.forEach(children, item => {
if (!item) { if (!item) {
return; return;
} }
...@@ -94,8 +92,7 @@ class Login extends Component { ...@@ -94,8 +92,7 @@ class Login extends Component {
return ( return (
<div className={classNames(className, styles.login)}> <div className={classNames(className, styles.login)}>
<Form onSubmit={this.handleSubmit}> <Form onSubmit={this.handleSubmit}>
{ {tabs.length ? (
tabs.length ? (
<div> <div>
<Tabs <Tabs
animated={false} animated={false}
...@@ -107,8 +104,9 @@ class Login extends Component { ...@@ -107,8 +104,9 @@ class Login extends Component {
</Tabs> </Tabs>
{otherChildren} {otherChildren}
</div> </div>
) : [...children] ) : (
} [...children]
)}
</Form> </Form>
</div> </div>
); );
...@@ -117,7 +115,7 @@ class Login extends Component { ...@@ -117,7 +115,7 @@ class Login extends Component {
Login.Tab = LoginTab; Login.Tab = LoginTab;
Login.Submit = LoginSubmit; Login.Submit = LoginSubmit;
Object.keys(LoginItem).forEach((item) => { Object.keys(LoginItem).forEach(item => {
Login[item] = LoginItem[item]; Login[item] = LoginItem[item];
}); });
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.login { .login {
.tabs { .tabs {
padding: 0 2px; padding: 0 2px;
margin: 0 -2px; margin: 0 -2px;
......
...@@ -10,9 +10,12 @@ const map = { ...@@ -10,9 +10,12 @@ const map = {
prefix: <Icon type="user" className={styles.prefixIcon} />, prefix: <Icon type="user" className={styles.prefixIcon} />,
placeholder: 'admin', placeholder: 'admin',
}, },
rules: [{ rules: [
required: true, message: 'Please enter username!', {
}], required: true,
message: 'Please enter username!',
},
],
}, },
Password: { Password: {
component: Input, component: Input,
...@@ -22,9 +25,12 @@ const map = { ...@@ -22,9 +25,12 @@ const map = {
type: 'password', type: 'password',
placeholder: '888888', placeholder: '888888',
}, },
rules: [{ rules: [
required: true, message: 'Please enter password!', {
}], required: true,
message: 'Please enter password!',
},
],
}, },
Mobile: { Mobile: {
component: Input, component: Input,
...@@ -33,11 +39,16 @@ const map = { ...@@ -33,11 +39,16 @@ const map = {
prefix: <Icon type="mobile" className={styles.prefixIcon} />, prefix: <Icon type="mobile" className={styles.prefixIcon} />,
placeholder: 'mobile number', placeholder: 'mobile number',
}, },
rules: [{ rules: [
required: true, message: 'Please enter mobile number!', {
}, { required: true,
pattern: /^1\d{10}$/, message: 'Wrong mobile number format!', message: 'Please enter mobile number!',
}], },
{
pattern: /^1\d{10}$/,
message: 'Wrong mobile number format!',
},
],
}, },
Captcha: { Captcha: {
component: Input, component: Input,
...@@ -46,9 +57,12 @@ const map = { ...@@ -46,9 +57,12 @@ const map = {
prefix: <Icon type="mail" className={styles.prefixIcon} />, prefix: <Icon type="mail" className={styles.prefixIcon} />,
placeholder: 'captcha', placeholder: 'captcha',
}, },
rules: [{ rules: [
required: true, message: 'Please enter Captcha!', {
}], required: true,
message: 'Please enter Captcha!',
},
],
}, },
}; };
......
...@@ -16,7 +16,4 @@ export interface INoticeIconTabProps { ...@@ -16,7 +16,4 @@ export interface INoticeIconTabProps {
style?: React.CSSProperties; style?: React.CSSProperties;
} }
export default class NoticeIconTab extends React.Component< export default class NoticeIconTab extends React.Component<INoticeIconTabProps, any> {}
INoticeIconTabProps,
any
> {}
...@@ -4,14 +4,18 @@ import classNames from 'classnames'; ...@@ -4,14 +4,18 @@ import classNames from 'classnames';
import styles from './NoticeList.less'; import styles from './NoticeList.less';
export default function NoticeList({ export default function NoticeList({
data = [], onClick, onClear, title, locale, emptyText, emptyImage, data = [],
onClick,
onClear,
title,
locale,
emptyText,
emptyImage,
}) { }) {
if (data.length === 0) { if (data.length === 0) {
return ( return (
<div className={styles.notFound}> <div className={styles.notFound}>
{emptyImage ? ( {emptyImage ? <img src={emptyImage} alt="not found" /> : null}
<img src={emptyImage} alt="not found" />
) : null}
<div>{emptyText || locale.emptyText}</div> <div>{emptyText || locale.emptyText}</div>
</div> </div>
); );
...@@ -48,7 +52,8 @@ export default function NoticeList({ ...@@ -48,7 +52,8 @@ export default function NoticeList({
})} })}
</List> </List>
<div className={styles.clear} onClick={onClear}> <div className={styles.clear} onClick={onClear}>
{locale.clear}{title} {locale.clear}
{title}
</div> </div>
</div> </div>
); );
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.list { .list {
max-height: 400px; max-height: 400px;
overflow: auto; overflow: auto;
.item { .item {
transition: all .3s; transition: all 0.3s;
overflow: hidden; overflow: hidden;
cursor: pointer; cursor: pointer;
padding-left: 24px; padding-left: 24px;
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
} }
&.read { &.read {
opacity: .4; opacity: 0.4;
} }
&:last-child { &:last-child {
border-bottom: 0; border-bottom: 0;
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
color: @text-color; color: @text-color;
border-radius: 0 0 @border-radius-base @border-radius-base; border-radius: 0 0 @border-radius-base @border-radius-base;
border-top: 1px solid @border-color-split; border-top: 1px solid @border-color-split;
transition: all .3s; transition: all 0.3s;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
......
...@@ -30,19 +30,21 @@ export default class NoticeIcon extends PureComponent { ...@@ -30,19 +30,21 @@ export default class NoticeIcon extends PureComponent {
onItemClick = (item, tabProps) => { onItemClick = (item, tabProps) => {
const { onItemClick } = this.props; const { onItemClick } = this.props;
onItemClick(item, tabProps); onItemClick(item, tabProps);
} };
onTabChange = (tabType) => { onTabChange = tabType => {
this.setState({ tabType }); this.setState({ tabType });
this.props.onTabChange(tabType); this.props.onTabChange(tabType);
} };
getNotificationBox() { getNotificationBox() {
const { children, loading, locale } = this.props; const { children, loading, locale } = this.props;
if (!children) { if (!children) {
return null; return null;
} }
const panes = React.Children.map(children, (child) => { const panes = React.Children.map(children, child => {
const title = child.props.list && child.props.list.length > 0 const title =
? `${child.props.title} (${child.props.list.length})` : child.props.title; child.props.list && child.props.list.length > 0
? `${child.props.title} (${child.props.list.length})`
: child.props.title;
return ( return (
<TabPane tab={title} key={child.props.title}> <TabPane tab={title} key={child.props.title}>
<List <List
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.popover { .popover {
width: 336px; width: 336px;
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
.noticeButton { .noticeButton {
cursor: pointer; cursor: pointer;
display: inline-block; display: inline-block;
transition: all .3s; transition: all 0.3s;
} }
.icon { .icon {
......
...@@ -10,7 +10,4 @@ export interface INumberInfoProps { ...@@ -10,7 +10,4 @@ export interface INumberInfoProps {
style?: React.CSSProperties; style?: React.CSSProperties;
} }
export default class NumberInfo extends React.Component< export default class NumberInfo extends React.Component<INumberInfoProps, any> {}
INumberInfoProps,
any
> {}
...@@ -3,15 +3,11 @@ import { Icon } from 'antd'; ...@@ -3,15 +3,11 @@ import { Icon } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import styles from './index.less'; import styles from './index.less';
export default ({ export default ({ theme, title, subTitle, total, subTotal, status, suffix, gap, ...rest }) => (
theme, title, subTitle, total, subTotal, status, suffix, gap, ...rest
}) => (
<div <div
className={ className={classNames(styles.numberInfo, {
classNames(styles.numberInfo, {
[styles[`numberInfo${theme}`]]: theme, [styles[`numberInfo${theme}`]]: theme,
}) })}
}
{...rest} {...rest}
> >
{title && <div className={styles.numberInfoTitle}>{title}</div>} {title && <div className={styles.numberInfoTitle}>{title}</div>}
...@@ -21,14 +17,12 @@ export default ({ ...@@ -21,14 +17,12 @@ export default ({
{total} {total}
{suffix && <em className={styles.suffix}>{suffix}</em>} {suffix && <em className={styles.suffix}>{suffix}</em>}
</span> </span>
{ {(status || subTotal) && (
(status || subTotal) && (
<span className={styles.subTotal}> <span className={styles.subTotal}>
{subTotal} {subTotal}
{status && <Icon type={`caret-${status}`} />} {status && <Icon type={`caret-${status}`} />}
</span> </span>
) )}
}
</div> </div>
</div> </div>
); );
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.numberInfo { .numberInfo {
.suffix { .suffix {
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
color: @text-color; color: @text-color;
font-size: @font-size-lg; font-size: @font-size-lg;
margin-bottom: 16px; margin-bottom: 16px;
transition: all .3s; transition: all 0.3s;
} }
.numberInfoSubTitle { .numberInfoSubTitle {
color: @text-color-secondary; color: @text-color-secondary;
......
...@@ -10,7 +10,7 @@ const { TabPane } = Tabs; ...@@ -10,7 +10,7 @@ const { TabPane } = Tabs;
export function getBreadcrumb(breadcrumbNameMap, url) { export function getBreadcrumb(breadcrumbNameMap, url) {
let breadcrumb = breadcrumbNameMap[url]; let breadcrumb = breadcrumbNameMap[url];
if (!breadcrumb) { if (!breadcrumb) {
Object.keys(breadcrumbNameMap).forEach((item) => { Object.keys(breadcrumbNameMap).forEach(item => {
if (pathToRegexp(item).test(url)) { if (pathToRegexp(item).test(url)) {
breadcrumb = breadcrumbNameMap[item]; breadcrumb = breadcrumbNameMap[item];
} }
...@@ -26,7 +26,7 @@ export default class PageHeader extends PureComponent { ...@@ -26,7 +26,7 @@ export default class PageHeader extends PureComponent {
location: PropTypes.object, location: PropTypes.object,
breadcrumbNameMap: PropTypes.object, breadcrumbNameMap: PropTypes.object,
}; };
onChange = (key) => { onChange = key => {
if (this.props.onTabChange) { if (this.props.onTabChange) {
this.props.onTabChange(key); this.props.onTabChange(key);
} }
...@@ -36,17 +36,12 @@ export default class PageHeader extends PureComponent { ...@@ -36,17 +36,12 @@ export default class PageHeader extends PureComponent {
routes: this.props.routes || this.context.routes, routes: this.props.routes || this.context.routes,
params: this.props.params || this.context.params, params: this.props.params || this.context.params,
routerLocation: this.props.location || this.context.location, routerLocation: this.props.location || this.context.location,
breadcrumbNameMap: breadcrumbNameMap: this.props.breadcrumbNameMap || this.context.breadcrumbNameMap,
this.props.breadcrumbNameMap || this.context.breadcrumbNameMap,
}; };
}; };
// Generated according to props // Generated according to props
conversionFromProps = () => { conversionFromProps = () => {
const { const { breadcrumbList, breadcrumbSeparator, linkElement = 'a' } = this.props;
breadcrumbList,
breadcrumbSeparator,
linkElement = 'a',
} = this.props;
return ( return (
<Breadcrumb className={styles.breadcrumb} separator={breadcrumbSeparator}> <Breadcrumb className={styles.breadcrumb} separator={breadcrumbSeparator}>
{breadcrumbList.map(item => ( {breadcrumbList.map(item => (
...@@ -57,7 +52,7 @@ export default class PageHeader extends PureComponent { ...@@ -57,7 +52,7 @@ export default class PageHeader extends PureComponent {
{ {
[linkElement === 'a' ? 'href' : 'to']: item.href, [linkElement === 'a' ? 'href' : 'to']: item.href,
}, },
item.title, item.title
) )
: item.title} : item.title}
</Breadcrumb.Item> </Breadcrumb.Item>
...@@ -72,14 +67,13 @@ export default class PageHeader extends PureComponent { ...@@ -72,14 +67,13 @@ export default class PageHeader extends PureComponent {
// Loop data mosaic routing // Loop data mosaic routing
const extraBreadcrumbItems = pathSnippets.map((url, index) => { const extraBreadcrumbItems = pathSnippets.map((url, index) => {
const currentBreadcrumb = getBreadcrumb(breadcrumbNameMap, url); const currentBreadcrumb = getBreadcrumb(breadcrumbNameMap, url);
const isLinkable = const isLinkable = index !== pathSnippets.length - 1 && currentBreadcrumb.component;
index !== pathSnippets.length - 1 && currentBreadcrumb.component;
return currentBreadcrumb.name && !currentBreadcrumb.hideInBreadcrumb ? ( return currentBreadcrumb.name && !currentBreadcrumb.hideInBreadcrumb ? (
<Breadcrumb.Item key={url}> <Breadcrumb.Item key={url}>
{createElement( {createElement(
isLinkable ? linkElement : 'span', isLinkable ? linkElement : 'span',
{ [linkElement === 'a' ? 'href' : 'to']: url }, { [linkElement === 'a' ? 'href' : 'to']: url },
currentBreadcrumb.name, currentBreadcrumb.name
)} )}
</Breadcrumb.Item> </Breadcrumb.Item>
) : null; ) : null;
...@@ -92,9 +86,9 @@ export default class PageHeader extends PureComponent { ...@@ -92,9 +86,9 @@ export default class PageHeader extends PureComponent {
{ {
[linkElement === 'a' ? 'href' : 'to']: '/', [linkElement === 'a' ? 'href' : 'to']: '/',
}, },
'首页', '首页'
)} )}
</Breadcrumb.Item>, </Breadcrumb.Item>
); );
return ( return (
<Breadcrumb className={styles.breadcrumb} separator={breadcrumbSeparator}> <Breadcrumb className={styles.breadcrumb} separator={breadcrumbSeparator}>
...@@ -108,12 +102,7 @@ export default class PageHeader extends PureComponent { ...@@ -108,12 +102,7 @@ export default class PageHeader extends PureComponent {
*/ */
conversionBreadcrumbList = () => { conversionBreadcrumbList = () => {
const { breadcrumbList, breadcrumbSeparator } = this.props; const { breadcrumbList, breadcrumbSeparator } = this.props;
const { const { routes, params, routerLocation, breadcrumbNameMap } = this.getBreadcrumbProps();
routes,
params,
routerLocation,
breadcrumbNameMap,
} = this.getBreadcrumbProps();
if (breadcrumbList && breadcrumbList.length) { if (breadcrumbList && breadcrumbList.length) {
return this.conversionFromProps(); return this.conversionFromProps();
} }
...@@ -151,7 +140,7 @@ export default class PageHeader extends PureComponent { ...@@ -151,7 +140,7 @@ export default class PageHeader extends PureComponent {
href: paths.join('/') || '/', href: paths.join('/') || '/',
to: paths.join('/') || '/', to: paths.join('/') || '/',
}, },
route.breadcrumbName, route.breadcrumbName
) )
); );
}; };
...@@ -191,9 +180,7 @@ export default class PageHeader extends PureComponent { ...@@ -191,9 +180,7 @@ export default class PageHeader extends PureComponent {
</div> </div>
<div className={styles.row}> <div className={styles.row}>
{content && <div className={styles.content}>{content}</div>} {content && <div className={styles.content}>{content}</div>}
{extraContent && ( {extraContent && <div className={styles.extraContent}>{extraContent}</div>}
<div className={styles.extraContent}>{extraContent}</div>
)}
</div> </div>
</div> </div>
</div> </div>
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.pageHeader { .pageHeader {
background: @component-background; background: @component-background;
...@@ -61,19 +61,27 @@ ...@@ -61,19 +61,27 @@
} }
} }
.title, .action, .content, .extraContent, .main { .title,
.action,
.content,
.extraContent,
.main {
flex: auto; flex: auto;
} }
.title, .action { .title,
.action {
margin-bottom: 16px; margin-bottom: 16px;
} }
.logo, .content, .extraContent { .logo,
.content,
.extraContent {
margin-bottom: 16px; margin-bottom: 16px;
} }
.action, .extraContent { .action,
.extraContent {
text-align: right; text-align: right;
} }
...@@ -105,7 +113,8 @@ ...@@ -105,7 +113,8 @@
display: block; display: block;
} }
.action, .extraContent { .action,
.extraContent {
margin-left: 0; margin-left: 0;
text-align: left; text-align: left;
} }
...@@ -124,7 +133,8 @@ ...@@ -124,7 +133,8 @@
.pageHeader { .pageHeader {
.action { .action {
:global { :global {
.ant-btn-group, .ant-btn { .ant-btn-group,
.ant-btn {
display: block; display: block;
margin-bottom: 8px; margin-bottom: 8px;
} }
......
...@@ -17,35 +17,29 @@ const routerData = { ...@@ -17,35 +17,29 @@ const routerData = {
}; };
describe('test getBreadcrumb', () => { describe('test getBreadcrumb', () => {
it('Simple url', () => { it('Simple url', () => {
expect(getBreadcrumb(routerData, '/dashboard/analysis').name).toEqual( expect(getBreadcrumb(routerData, '/dashboard/analysis').name).toEqual('分析页');
'分析页',
);
}); });
it('Parameters url', () => { it('Parameters url', () => {
expect(getBreadcrumb(routerData, '/userinfo/2144').name).toEqual( expect(getBreadcrumb(routerData, '/userinfo/2144').name).toEqual('用户信息');
'用户信息',
);
}); });
it('The middle parameter url', () => { it('The middle parameter url', () => {
expect(getBreadcrumb(routerData, '/userinfo/2144/addr').name).toEqual( expect(getBreadcrumb(routerData, '/userinfo/2144/addr').name).toEqual('收货订单');
'收货订单',
);
}); });
it('Loop through the parameters', () => { it('Loop through the parameters', () => {
const urlNameList = urlToList('/userinfo/2144/addr').map((url) => { const urlNameList = urlToList('/userinfo/2144/addr').map(url => {
return getBreadcrumb(routerData, url).name; return getBreadcrumb(routerData, url).name;
}); });
expect(urlNameList).toEqual(['用户列表', '用户信息', '收货订单']); expect(urlNameList).toEqual(['用户列表', '用户信息', '收货订单']);
}); });
it('a path', () => { it('a path', () => {
const urlNameList = urlToList('/userinfo').map((url) => { const urlNameList = urlToList('/userinfo').map(url => {
return getBreadcrumb(routerData, url).name; return getBreadcrumb(routerData, url).name;
}); });
expect(urlNameList).toEqual(['用户列表']); expect(urlNameList).toEqual(['用户列表']);
}); });
it('Secondary path', () => { it('Secondary path', () => {
const urlNameList = urlToList('/userinfo/2144').map((url) => { const urlNameList = urlToList('/userinfo/2144').map(url => {
return getBreadcrumb(routerData, url).name; return getBreadcrumb(routerData, url).name;
}); });
expect(urlNameList).toEqual(['用户列表', '用户信息']); expect(urlNameList).toEqual(['用户列表', '用户信息']);
......
...@@ -4,7 +4,13 @@ import { Icon } from 'antd'; ...@@ -4,7 +4,13 @@ import { Icon } from 'antd';
import styles from './index.less'; import styles from './index.less';
export default function Result({ export default function Result({
className, type, title, description, extra, actions, ...restProps className,
type,
title,
description,
extra,
actions,
...restProps
}) { }) {
const iconMap = { const iconMap = {
error: <Icon className={styles.error} type="close-circle" />, error: <Icon className={styles.error} type="close-circle" />,
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.result { .result {
text-align: center; text-align: center;
......
...@@ -12,7 +12,7 @@ const { SubMenu } = Menu; ...@@ -12,7 +12,7 @@ const { SubMenu } = Menu;
// icon: 'setting', // icon: 'setting',
// icon: 'http://demo.com/icon.png', // icon: 'http://demo.com/icon.png',
// icon: <Icon type="setting" />, // icon: <Icon type="setting" />,
const getIcon = (icon) => { const getIcon = icon => {
if (typeof icon === 'string' && icon.indexOf('http') === 0) { if (typeof icon === 'string' && icon.indexOf('http') === 0) {
return <img src={icon} alt="icon" className={`${styles.icon} sider-menu-item-img`} />; return <img src={icon} alt="icon" className={`${styles.icon} sider-menu-item-img`} />;
} }
...@@ -23,7 +23,7 @@ const getIcon = (icon) => { ...@@ -23,7 +23,7 @@ const getIcon = (icon) => {
}; };
export const getMeunMatcheys = (flatMenuKeys, path) => { export const getMeunMatcheys = (flatMenuKeys, path) => {
return flatMenuKeys.filter((item) => { return flatMenuKeys.filter(item => {
return pathToRegexp(item).test(path); return pathToRegexp(item).test(path);
}); });
}; };
...@@ -52,7 +52,7 @@ export default class SiderMenu extends PureComponent { ...@@ -52,7 +52,7 @@ export default class SiderMenu extends PureComponent {
getDefaultCollapsedSubMenus(props) { getDefaultCollapsedSubMenus(props) {
const { location: { pathname } } = props || this.props; const { location: { pathname } } = props || this.props;
return urlToList(pathname) return urlToList(pathname)
.map((item) => { .map(item => {
return getMeunMatcheys(this.flatMenuKeys, item)[0]; return getMeunMatcheys(this.flatMenuKeys, item)[0];
}) })
.filter(item => item); .filter(item => item);
...@@ -64,7 +64,7 @@ export default class SiderMenu extends PureComponent { ...@@ -64,7 +64,7 @@ export default class SiderMenu extends PureComponent {
*/ */
getFlatMenuKeys(menus) { getFlatMenuKeys(menus) {
let keys = []; let keys = [];
menus.forEach((item) => { menus.forEach(item => {
if (item.children) { if (item.children) {
keys = keys.concat(this.getFlatMenuKeys(item.children)); keys = keys.concat(this.getFlatMenuKeys(item.children));
} }
...@@ -77,7 +77,7 @@ export default class SiderMenu extends PureComponent { ...@@ -77,7 +77,7 @@ export default class SiderMenu extends PureComponent {
* Judge whether it is http link.return a or Link * Judge whether it is http link.return a or Link
* @memberof SiderMenu * @memberof SiderMenu
*/ */
getMenuItemPath = (item) => { getMenuItemPath = item => {
const itemPath = this.conversionPath(item.path); const itemPath = this.conversionPath(item.path);
const icon = getIcon(item.icon); const icon = getIcon(item.icon);
const { target, name } = item; const { target, name } = item;
...@@ -111,7 +111,7 @@ export default class SiderMenu extends PureComponent { ...@@ -111,7 +111,7 @@ export default class SiderMenu extends PureComponent {
/** /**
* get SubMenu or Item * get SubMenu or Item
*/ */
getSubMenuOrItem = (item) => { getSubMenuOrItem = item => {
if (item.children && item.children.some(child => child.name)) { if (item.children && item.children.some(child => child.name)) {
const childrenItems = this.getNavMenuItems(item.children); const childrenItems = this.getNavMenuItems(item.children);
// 当无子菜单时就不展示菜单 // 当无子菜单时就不展示菜单
...@@ -136,22 +136,20 @@ export default class SiderMenu extends PureComponent { ...@@ -136,22 +136,20 @@ export default class SiderMenu extends PureComponent {
} }
return null; return null;
} else { } else {
return ( return <Menu.Item key={item.path}>{this.getMenuItemPath(item)}</Menu.Item>;
<Menu.Item key={item.path}>{this.getMenuItemPath(item)}</Menu.Item>
);
} }
}; };
/** /**
* 获得菜单子节点 * 获得菜单子节点
* @memberof SiderMenu * @memberof SiderMenu
*/ */
getNavMenuItems = (menusData) => { getNavMenuItems = menusData => {
if (!menusData) { if (!menusData) {
return []; return [];
} }
return menusData return menusData
.filter(item => item.name && !item.hideInMenu) .filter(item => item.name && !item.hideInMenu)
.map((item) => { .map(item => {
// make dom // make dom
const ItemDom = this.getSubMenuOrItem(item); const ItemDom = this.getSubMenuOrItem(item);
return this.checkPermissionItem(item.authority, ItemDom); return this.checkPermissionItem(item.authority, ItemDom);
...@@ -161,13 +159,11 @@ export default class SiderMenu extends PureComponent { ...@@ -161,13 +159,11 @@ export default class SiderMenu extends PureComponent {
// Get the currently selected menu // Get the currently selected menu
getSelectedMenuKeys = () => { getSelectedMenuKeys = () => {
const { location: { pathname } } = this.props; const { location: { pathname } } = this.props;
return urlToList(pathname).map(itemPath => return urlToList(pathname).map(itemPath => getMeunMatcheys(this.flatMenuKeys, itemPath).pop());
getMeunMatcheys(this.flatMenuKeys, itemPath).pop(),
);
}; };
// conversion Path // conversion Path
// 转化路径 // 转化路径
conversionPath = (path) => { conversionPath = path => {
if (path && path.indexOf('http') === 0) { if (path && path.indexOf('http') === 0) {
return path; return path;
} else { } else {
...@@ -182,13 +178,10 @@ export default class SiderMenu extends PureComponent { ...@@ -182,13 +178,10 @@ export default class SiderMenu extends PureComponent {
} }
return ItemDom; return ItemDom;
}; };
isMainMenu = (key) => { isMainMenu = key => {
return this.menus.some( return this.menus.some(item => key && (item.key === key || item.path === key));
item => };
key && (item.key === key || item.path === key), handleOpenChange = openKeys => {
);
}
handleOpenChange = (openKeys) => {
const lastOpenKey = openKeys[openKeys.length - 1]; const lastOpenKey = openKeys[openKeys.length - 1];
const moreThanOne = openKeys.filter(openKey => this.isMainMenu(openKey)).length > 1; const moreThanOne = openKeys.filter(openKey => this.isMainMenu(openKey)).length > 1;
this.setState({ this.setState({
......
import { getMeunMatcheys } from './SiderMenu'; import { getMeunMatcheys } from './SiderMenu';
const meun = [ const meun = ['/dashboard', '/userinfo', '/dashboard/name', '/userinfo/:id', '/userinfo/:id/info'];
'/dashboard',
'/userinfo',
'/dashboard/name',
'/userinfo/:id',
'/userinfo/:id/info',
];
describe('test meun match', () => { describe('test meun match', () => {
it('simple path', () => { it('simple path', () => {
...@@ -17,20 +11,14 @@ describe('test meun match', () => { ...@@ -17,20 +11,14 @@ describe('test meun match', () => {
}); });
it('Secondary path', () => { it('Secondary path', () => {
expect(getMeunMatcheys(meun, '/dashboard/name')).toEqual([ expect(getMeunMatcheys(meun, '/dashboard/name')).toEqual(['/dashboard/name']);
'/dashboard/name',
]);
}); });
it('Parameter path', () => { it('Parameter path', () => {
expect(getMeunMatcheys(meun, '/userinfo/2144')).toEqual([ expect(getMeunMatcheys(meun, '/userinfo/2144')).toEqual(['/userinfo/:id']);
'/userinfo/:id',
]);
}); });
it('three parameter path', () => { it('three parameter path', () => {
expect(getMeunMatcheys(meun, '/userinfo/2144/info')).toEqual([ expect(getMeunMatcheys(meun, '/userinfo/2144/info')).toEqual(['/userinfo/:id/info']);
'/userinfo/:id/info',
]);
}); });
}); });
...@@ -3,17 +3,20 @@ import React from 'react'; ...@@ -3,17 +3,20 @@ import React from 'react';
import DrawerMenu from 'rc-drawer-menu'; import DrawerMenu from 'rc-drawer-menu';
import SiderMenu from './SiderMenu'; import SiderMenu from './SiderMenu';
export default props => ( export default props =>
props.isMobile ? ( props.isMobile ? (
<DrawerMenu <DrawerMenu
parent={null} parent={null}
level={null} level={null}
iconChild={null} iconChild={null}
open={!props.collapsed} open={!props.collapsed}
onMaskClick={() => { props.onCollapse(true); }} onMaskClick={() => {
props.onCollapse(true);
}}
width="256px" width="256px"
> >
<SiderMenu {...props} collapsed={props.isMobile ? false : props.collapsed} /> <SiderMenu {...props} collapsed={props.isMobile ? false : props.collapsed} />
</DrawerMenu> </DrawerMenu>
) : <SiderMenu {...props} /> ) : (
); <SiderMenu {...props} />
);
...@@ -51,7 +51,12 @@ ...@@ -51,7 +51,12 @@
} }
.ant-menu-inline-collapsed { .ant-menu-inline-collapsed {
& > .ant-menu-item .sider-menu-item-img + span, & > .ant-menu-item .sider-menu-item-img + span,
& > .ant-menu-item-group > .ant-menu-item-group-list > .ant-menu-item .sider-menu-item-img + span, &
> .ant-menu-item-group
> .ant-menu-item-group-list
> .ant-menu-item
.sider-menu-item-img
+ span,
& > .ant-menu-submenu > .ant-menu-submenu-title .sider-menu-item-img + span { & > .ant-menu-submenu > .ant-menu-submenu-title .sider-menu-item-img + span {
max-width: 0; max-width: 0;
display: inline-block; display: inline-block;
...@@ -60,7 +65,7 @@ ...@@ -60,7 +65,7 @@
} }
.ant-menu-item .sider-menu-item-img + span, .ant-menu-item .sider-menu-item-img + span,
.ant-menu-submenu-title .sider-menu-item-img + span { .ant-menu-submenu-title .sider-menu-item-img + span {
transition: opacity .3s @ease-in-out, width .3s @ease-in-out; transition: opacity 0.3s @ease-in-out, width 0.3s @ease-in-out;
opacity: 1; opacity: 1;
} }
} }
...@@ -11,16 +11,12 @@ export default ({ title, children, last, block, grid, ...rest }) => { ...@@ -11,16 +11,12 @@ export default ({ title, children, last, block, grid, ...rest }) => {
return ( return (
<div className={cls} {...rest}> <div className={cls} {...rest}>
{ {title && (
title && (
<div className={styles.label}> <div className={styles.label}>
<span>{title}</span> <span>{title}</span>
</div> </div>
) )}
} <div className={styles.content}>{children}</div>
<div className={styles.content}>
{children}
</div>
</div> </div>
); );
}; };
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.standardFormRow { .standardFormRow {
border-bottom: 1px dashed @border-color-split; border-bottom: 1px dashed @border-color-split;
......
...@@ -4,7 +4,7 @@ import styles from './index.less'; ...@@ -4,7 +4,7 @@ import styles from './index.less';
function initTotalList(columns) { function initTotalList(columns) {
const totalList = []; const totalList = [];
columns.forEach((column) => { columns.forEach(column => {
if (column.needTotal) { if (column.needTotal) {
totalList.push({ ...column, total: 0 }); totalList.push({ ...column, total: 0 });
} }
...@@ -37,7 +37,7 @@ class StandardTable extends PureComponent { ...@@ -37,7 +37,7 @@ class StandardTable extends PureComponent {
handleRowSelectChange = (selectedRowKeys, selectedRows) => { handleRowSelectChange = (selectedRowKeys, selectedRows) => {
let needTotalList = [...this.state.needTotalList]; let needTotalList = [...this.state.needTotalList];
needTotalList = needTotalList.map((item) => { needTotalList = needTotalList.map(item => {
return { return {
...item, ...item,
total: selectedRows.reduce((sum, val) => { total: selectedRows.reduce((sum, val) => {
...@@ -51,15 +51,15 @@ class StandardTable extends PureComponent { ...@@ -51,15 +51,15 @@ class StandardTable extends PureComponent {
} }
this.setState({ selectedRowKeys, needTotalList }); this.setState({ selectedRowKeys, needTotalList });
} };
handleTableChange = (pagination, filters, sorter) => { handleTableChange = (pagination, filters, sorter) => {
this.props.onChange(pagination, filters, sorter); this.props.onChange(pagination, filters, sorter);
} };
cleanSelectedKeys = () => { cleanSelectedKeys = () => {
this.handleRowSelectChange([], []); this.handleRowSelectChange([], []);
} };
render() { render() {
const { selectedRowKeys, needTotalList } = this.state; const { selectedRowKeys, needTotalList } = this.state;
...@@ -83,22 +83,22 @@ class StandardTable extends PureComponent { ...@@ -83,22 +83,22 @@ class StandardTable extends PureComponent {
<div className={styles.standardTable}> <div className={styles.standardTable}>
<div className={styles.tableAlert}> <div className={styles.tableAlert}>
<Alert <Alert
message={( message={
<Fragment> <Fragment>
已选择 <a style={{ fontWeight: 600 }}>{selectedRowKeys.length}</a> 项&nbsp;&nbsp; 已选择 <a style={{ fontWeight: 600 }}>{selectedRowKeys.length}</a> 项&nbsp;&nbsp;
{ {needTotalList.map(item => (
needTotalList.map(item => ( <span style={{ marginLeft: 8 }} key={item.dataIndex}>
<span style={{ marginLeft: 8 }} key={item.dataIndex}>{item.title}总计&nbsp; {item.title}总计&nbsp;
<span style={{ fontWeight: 600 }}> <span style={{ fontWeight: 600 }}>
{item.render ? item.render(item.total) : item.total} {item.render ? item.render(item.total) : item.total}
</span> </span>
</span> </span>
) ))}
) <a onClick={this.cleanSelectedKeys} style={{ marginLeft: 24 }}>
} 清空
<a onClick={this.cleanSelectedKeys} style={{ marginLeft: 24 }}>清空</a> </a>
</Fragment> </Fragment>
)} }
type="info" type="info"
showIcon showIcon
/> />
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.standardTable { .standardTable {
:global { :global {
......
...@@ -5,7 +5,4 @@ export interface ITagSelectOptionProps { ...@@ -5,7 +5,4 @@ export interface ITagSelectOptionProps {
style?: React.CSSProperties; style?: React.CSSProperties;
} }
export default class TagSelectOption extends React.Component< export default class TagSelectOption extends React.Component<ITagSelectOptionProps, any> {}
ITagSelectOptionProps,
any
> {}
...@@ -7,11 +7,7 @@ import styles from './index.less'; ...@@ -7,11 +7,7 @@ import styles from './index.less';
const { CheckableTag } = Tag; const { CheckableTag } = Tag;
const TagSelectOption = ({ children, checked, onChange, value }) => ( const TagSelectOption = ({ children, checked, onChange, value }) => (
<CheckableTag <CheckableTag checked={checked} key={value} onChange={state => onChange(value, state)}>
checked={checked}
key={value}
onChange={state => onChange(value, state)}
>
{children} {children}
</CheckableTag> </CheckableTag>
); );
...@@ -29,7 +25,7 @@ class TagSelect extends Component { ...@@ -29,7 +25,7 @@ class TagSelect extends Component {
} }
} }
onChange = (value) => { onChange = value => {
const { onChange } = this.props; const { onChange } = this.props;
if (!('value' in this.props)) { if (!('value' in this.props)) {
this.setState({ value }); this.setState({ value });
...@@ -37,15 +33,15 @@ class TagSelect extends Component { ...@@ -37,15 +33,15 @@ class TagSelect extends Component {
if (onChange) { if (onChange) {
onChange(value); onChange(value);
} }
} };
onSelectAll = (checked) => { onSelectAll = checked => {
let checkedTags = []; let checkedTags = [];
if (checked) { if (checked) {
checkedTags = this.getAllTags(); checkedTags = this.getAllTags();
} }
this.onChange(checkedTags); this.onChange(checkedTags);
} };
getAllTags() { getAllTags() {
let { children } = this.props; let { children } = this.props;
...@@ -66,19 +62,21 @@ class TagSelect extends Component { ...@@ -66,19 +62,21 @@ class TagSelect extends Component {
checkedTags.splice(index, 1); checkedTags.splice(index, 1);
} }
this.onChange(checkedTags); this.onChange(checkedTags);
} };
handleExpand = () => { handleExpand = () => {
this.setState({ this.setState({
expand: !this.state.expand, expand: !this.state.expand,
}); });
} };
isTagSelectOption = (node) => { isTagSelectOption = node => {
return node && node.type && ( return (
node.type.isTagSelectOption || node.type.displayName === 'TagSelectOption' node &&
node.type &&
(node.type.isTagSelectOption || node.type.displayName === 'TagSelectOption')
); );
} };
render() { render() {
const { value, expand } = this.state; const { value, expand } = this.state;
...@@ -92,15 +90,11 @@ class TagSelect extends Component { ...@@ -92,15 +90,11 @@ class TagSelect extends Component {
}); });
return ( return (
<div className={cls} style={style}> <div className={cls} style={style}>
<CheckableTag <CheckableTag checked={checkedAll} key="tag-select-__all__" onChange={this.onSelectAll}>
checked={checkedAll}
key="tag-select-__all__"
onChange={this.onSelectAll}
>
全部 全部
</CheckableTag> </CheckableTag>
{ {value &&
value && React.Children.map(children, (child) => { React.Children.map(children, child => {
if (this.isTagSelectOption(child)) { if (this.isTagSelectOption(child)) {
return React.cloneElement(child, { return React.cloneElement(child, {
key: `tag-select-${child.props.value}`, key: `tag-select-${child.props.value}`,
...@@ -110,15 +104,12 @@ class TagSelect extends Component { ...@@ -110,15 +104,12 @@ class TagSelect extends Component {
}); });
} }
return child; return child;
}) })}
} {expandable && (
{
expandable && (
<a className={styles.trigger} onClick={this.handleExpand}> <a className={styles.trigger} onClick={this.handleExpand}>
{expand ? '收起' : '展开'} <Icon type={expand ? 'up' : 'down'} /> {expand ? '收起' : '展开'} <Icon type={expand ? 'up' : 'down'} />
</a> </a>
) )}
}
</div> </div>
); );
} }
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.tagSelect { .tagSelect {
user-select: none; user-select: none;
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
overflow: hidden; overflow: hidden;
max-height: 32px; max-height: 32px;
line-height: 32px; line-height: 32px;
transition: all .3s; transition: all 0.3s;
:global { :global {
.ant-tag { .ant-tag {
padding: 0 8px; padding: 0 8px;
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
} }
} }
&.expanded { &.expanded {
transition: all .3s; transition: all 0.3s;
max-height: 200px; max-height: 200px;
} }
.trigger { .trigger {
......
...@@ -4,17 +4,21 @@ import classNames from 'classnames'; ...@@ -4,17 +4,21 @@ import classNames from 'classnames';
import styles from './index.less'; import styles from './index.less';
const Trend = ({ colorful = true, flag, children, className, ...rest }) => { const Trend = ({ colorful = true, flag, children, className, ...rest }) => {
const classString = classNames(styles.trendItem, { const classString = classNames(
styles.trendItem,
{
[styles.trendItemGrey]: !colorful, [styles.trendItemGrey]: !colorful,
}, className); },
className
);
return ( return (
<div <div {...rest} className={classString} title={typeof children === 'string' ? children : ''}>
{...rest}
className={classString}
title={typeof children === 'string' ? children : ''}
>
<span className={styles.value}>{children}</span> <span className={styles.value}>{children}</span>
{flag && <span className={styles[flag]}><Icon type={`caret-${flag}`} /></span>} {flag && (
<span className={styles[flag]}>
<Icon type={`caret-${flag}`} />
</span>
)}
</div> </div>
); );
}; };
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.trendItem { .trendItem {
display: inline-block; display: inline-block;
......
...@@ -5,10 +5,7 @@ describe('test urlToList', () => { ...@@ -5,10 +5,7 @@ describe('test urlToList', () => {
expect(urlToList('/userinfo')).toEqual(['/userinfo']); expect(urlToList('/userinfo')).toEqual(['/userinfo']);
}); });
it('Secondary path', () => { it('Secondary path', () => {
expect(urlToList('/userinfo/2144')).toEqual([ expect(urlToList('/userinfo/2144')).toEqual(['/userinfo', '/userinfo/2144']);
'/userinfo',
'/userinfo/2144',
]);
}); });
it('Three paths', () => { it('Three paths', () => {
expect(urlToList('/userinfo/2144/addr')).toEqual([ expect(urlToList('/userinfo/2144/addr')).toEqual([
......
...@@ -23,14 +23,14 @@ const { AuthorizedRoute, check } = Authorized; ...@@ -23,14 +23,14 @@ const { AuthorizedRoute, check } = Authorized;
* 根据菜单取得重定向地址. * 根据菜单取得重定向地址.
*/ */
const redirectData = []; const redirectData = [];
const getRedirect = (item) => { const getRedirect = item => {
if (item && item.children) { if (item && item.children) {
if (item.children[0] && item.children[0].path) { if (item.children[0] && item.children[0].path) {
redirectData.push({ redirectData.push({
from: `${item.path}`, from: `${item.path}`,
to: `${item.children[0].path}`, to: `${item.children[0].path}`,
}); });
item.children.forEach((children) => { item.children.forEach(children => {
getRedirect(children); getRedirect(children);
}); });
} }
...@@ -79,7 +79,7 @@ const query = { ...@@ -79,7 +79,7 @@ const query = {
}; };
let isMobile; let isMobile;
enquireScreen((b) => { enquireScreen(b => {
isMobile = b; isMobile = b;
}); });
...@@ -87,7 +87,7 @@ class BasicLayout extends React.PureComponent { ...@@ -87,7 +87,7 @@ class BasicLayout extends React.PureComponent {
static childContextTypes = { static childContextTypes = {
location: PropTypes.object, location: PropTypes.object,
breadcrumbNameMap: PropTypes.object, breadcrumbNameMap: PropTypes.object,
} };
state = { state = {
isMobile, isMobile,
}; };
...@@ -99,7 +99,7 @@ class BasicLayout extends React.PureComponent { ...@@ -99,7 +99,7 @@ class BasicLayout extends React.PureComponent {
}; };
} }
componentDidMount() { componentDidMount() {
enquireScreen((mobile) => { enquireScreen(mobile => {
this.setState({ this.setState({
isMobile: mobile, isMobile: mobile,
}); });
...@@ -130,25 +130,26 @@ class BasicLayout extends React.PureComponent { ...@@ -130,25 +130,26 @@ class BasicLayout extends React.PureComponent {
} else { } else {
const { routerData } = this.props; const { routerData } = this.props;
// get the first authorized route path in routerData // get the first authorized route path in routerData
const authorizedPath = Object.keys(routerData).find(item => const authorizedPath = Object.keys(routerData).find(
check(routerData[item].authority, item) && item !== '/'); item => check(routerData[item].authority, item) && item !== '/'
);
return authorizedPath; return authorizedPath;
} }
return redirect; return redirect;
} };
handleMenuCollapse = (collapsed) => { handleMenuCollapse = collapsed => {
this.props.dispatch({ this.props.dispatch({
type: 'global/changeLayoutCollapsed', type: 'global/changeLayoutCollapsed',
payload: collapsed, payload: collapsed,
}); });
} };
handleNoticeClear = (type) => { handleNoticeClear = type => {
message.success(`清空了${type}`); message.success(`清空了${type}`);
this.props.dispatch({ this.props.dispatch({
type: 'global/clearNotices', type: 'global/clearNotices',
payload: type, payload: type,
}); });
} };
handleMenuClick = ({ key }) => { handleMenuClick = ({ key }) => {
if (key === 'triggerError') { if (key === 'triggerError') {
this.props.dispatch(routerRedux.push('/exception/trigger')); this.props.dispatch(routerRedux.push('/exception/trigger'));
...@@ -159,17 +160,23 @@ class BasicLayout extends React.PureComponent { ...@@ -159,17 +160,23 @@ class BasicLayout extends React.PureComponent {
type: 'login/logout', type: 'login/logout',
}); });
} }
} };
handleNoticeVisibleChange = (visible) => { handleNoticeVisibleChange = visible => {
if (visible) { if (visible) {
this.props.dispatch({ this.props.dispatch({
type: 'global/fetchNotices', type: 'global/fetchNotices',
}); });
} }
} };
render() { render() {
const { const {
currentUser, collapsed, fetchingNotices, notices, routerData, match, location, currentUser,
collapsed,
fetchingNotices,
notices,
routerData,
match,
location,
} = this.props; } = this.props;
const bashRedirect = this.getBashRedirect(); const bashRedirect = this.getBashRedirect();
const layout = ( const layout = (
...@@ -203,14 +210,10 @@ class BasicLayout extends React.PureComponent { ...@@ -203,14 +210,10 @@ class BasicLayout extends React.PureComponent {
</Header> </Header>
<Content style={{ margin: '24px 24px 0', height: '100%' }}> <Content style={{ margin: '24px 24px 0', height: '100%' }}>
<Switch> <Switch>
{ {redirectData.map(item => (
redirectData.map(item =>
<Redirect key={item.from} exact from={item.from} to={item.to} /> <Redirect key={item.from} exact from={item.from} to={item.to} />
) ))}
} {getRoutes(match.path, routerData).map(item => (
{
getRoutes(match.path, routerData).map(item =>
(
<AuthorizedRoute <AuthorizedRoute
key={item.key} key={item.key}
path={item.path} path={item.path}
...@@ -219,31 +222,33 @@ class BasicLayout extends React.PureComponent { ...@@ -219,31 +222,33 @@ class BasicLayout extends React.PureComponent {
authority={item.authority} authority={item.authority}
redirectPath="/exception/403" redirectPath="/exception/403"
/> />
) ))}
)
}
<Redirect exact from="/" to={bashRedirect} /> <Redirect exact from="/" to={bashRedirect} />
<Route render={NotFound} /> <Route render={NotFound} />
</Switch> </Switch>
</Content> </Content>
<Footer style={{ padding: 0 }}> <Footer style={{ padding: 0 }}>
<GlobalFooter <GlobalFooter
links={[{ links={[
{
key: 'Pro 首页', key: 'Pro 首页',
title: 'Pro 首页', title: 'Pro 首页',
href: 'http://pro.ant.design', href: 'http://pro.ant.design',
blankTarget: true, blankTarget: true,
}, { },
{
key: 'github', key: 'github',
title: <Icon type="github" />, title: <Icon type="github" />,
href: 'https://github.com/ant-design/ant-design-pro', href: 'https://github.com/ant-design/ant-design-pro',
blankTarget: true, blankTarget: true,
}, { },
{
key: 'Ant Design', key: 'Ant Design',
title: 'Ant Design', title: 'Ant Design',
href: 'http://ant.design', href: 'http://ant.design',
blankTarget: true, blankTarget: true,
}]} },
]}
copyright={ copyright={
<Fragment> <Fragment>
Copyright <Icon type="copyright" /> 2018 蚂蚁金服体验技术部出品 Copyright <Icon type="copyright" /> 2018 蚂蚁金服体验技术部出品
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.content { .content {
margin: 24px 24px 0; margin: 24px 24px 0;
......
...@@ -7,21 +7,29 @@ import styles from './UserLayout.less'; ...@@ -7,21 +7,29 @@ import styles from './UserLayout.less';
import logo from '../assets/logo.svg'; import logo from '../assets/logo.svg';
import { getRoutes } from '../utils/utils'; import { getRoutes } from '../utils/utils';
const links = [{ const links = [
{
key: 'help', key: 'help',
title: '帮助', title: '帮助',
href: '', href: '',
}, { },
{
key: 'privacy', key: 'privacy',
title: '隐私', title: '隐私',
href: '', href: '',
}, { },
{
key: 'terms', key: 'terms',
title: '条款', title: '条款',
href: '', href: '',
}]; },
];
const copyright = <Fragment>Copyright <Icon type="copyright" /> 2018 蚂蚁金服体验技术部出品</Fragment>; const copyright = (
<Fragment>
Copyright <Icon type="copyright" /> 2018 蚂蚁金服体验技术部出品
</Fragment>
);
class UserLayout extends React.PureComponent { class UserLayout extends React.PureComponent {
getPageTitle() { getPageTitle() {
...@@ -49,16 +57,14 @@ class UserLayout extends React.PureComponent { ...@@ -49,16 +57,14 @@ class UserLayout extends React.PureComponent {
<div className={styles.desc}>Ant Design 是西湖区最具影响力的 Web 设计规范</div> <div className={styles.desc}>Ant Design 是西湖区最具影响力的 Web 设计规范</div>
</div> </div>
<Switch> <Switch>
{getRoutes(match.path, routerData).map(item => {getRoutes(match.path, routerData).map(item => (
(
<Route <Route
key={item.key} key={item.key}
path={item.path} path={item.path}
component={item.component} component={item.component}
exact={item.exact} exact={item.exact}
/> />
) ))}
)}
<Redirect exact from="/user" to="/user/login" /> <Redirect exact from="/user" to="/user/login" />
</Switch> </Switch>
</div> </div>
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.container { .container {
display: flex; display: flex;
......
// Use require.context to require reducers automatically // Use require.context to require reducers automatically
// Ref: https://webpack.js.org/guides/dependency-management/#require-context // Ref: https://webpack.js.org/guides/dependency-management/#require-context
const context = require.context('./', false, /\.js$/); const context = require.context('./', false, /\.js$/);
export default context.keys().filter(item => item !== './index.js').map(key => context(key)); export default context
.keys()
.filter(item => item !== './index.js')
.map(key => context(key));
...@@ -21,10 +21,7 @@ function RouterConfig({ history, app }) { ...@@ -21,10 +21,7 @@ function RouterConfig({ history, app }) {
<LocaleProvider locale={zhCN}> <LocaleProvider locale={zhCN}>
<ConnectedRouter history={history}> <ConnectedRouter history={history}>
<Switch> <Switch>
<Route <Route path="/user" component={UserLayout} />
path="/user"
component={UserLayout}
/>
<AuthorizedRoute <AuthorizedRoute
path="/" path="/"
render={props => <BasicLayout {...props} />} render={props => <BasicLayout {...props} />}
......
...@@ -66,19 +66,19 @@ export default class Analysis extends Component { ...@@ -66,19 +66,19 @@ export default class Analysis extends Component {
}); });
} }
handleChangeSalesType = (e) => { handleChangeSalesType = e => {
this.setState({ this.setState({
salesType: e.target.value, salesType: e.target.value,
}); });
}; };
handleTabChange = (key) => { handleTabChange = key => {
this.setState({ this.setState({
currentTabKey: key, currentTabKey: key,
}); });
}; };
handleRangePickerChange = (rangePickerValue) => { handleRangePickerChange = rangePickerValue => {
this.setState({ this.setState({
rangePickerValue, rangePickerValue,
}); });
...@@ -88,7 +88,7 @@ export default class Analysis extends Component { ...@@ -88,7 +88,7 @@ export default class Analysis extends Component {
}); });
}; };
selectDate = (type) => { selectDate = type => {
this.setState({ this.setState({
rangePickerValue: getTimeDistance(type), rangePickerValue: getTimeDistance(type),
}); });
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
@import "../../utils/utils.less"; @import '../../utils/utils.less';
.iconGroup { .iconGroup {
i { i {
......
...@@ -14,7 +14,7 @@ const { Secured } = Authorized; ...@@ -14,7 +14,7 @@ const { Secured } = Authorized;
const targetTime = new Date().getTime() + 3900000; const targetTime = new Date().getTime() + 3900000;
// use permission as a parameter // use permission as a parameter
const havePermissionAsync = new Promise((resolve) => { const havePermissionAsync = new Promise(resolve => {
// Call resolve on behalf of passed // Call resolve on behalf of passed
setTimeout(() => resolve(), 1000); setTimeout(() => resolve(), 1000);
}); });
...@@ -81,11 +81,7 @@ export default class Monitor extends PureComponent { ...@@ -81,11 +81,7 @@ export default class Monitor extends PureComponent {
bodyStyle={{ textAlign: 'center' }} bodyStyle={{ textAlign: 'center' }}
bordered={false} bordered={false}
> >
<Gauge <Gauge title="跳出率" height={180} percent={87} />
title="跳出率"
height={180}
percent={87}
/>
</Card> </Card>
</Col> </Col>
</Row> </Row>
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
@import "../../utils/utils.less"; @import '../../utils/utils.less';
.mapChart { .mapChart {
padding-top: 24px; padding-top: 24px;
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
} }
.pieCard :global(.pie-stat) { .pieCard :global(.pie-stat) {
font-size: 24px!important; font-size: 24px !important;
} }
@media screen and (max-width: @screen-lg) { @media screen and (max-width: @screen-lg) {
......
...@@ -99,13 +99,15 @@ export default class Workplace extends PureComponent { ...@@ -99,13 +99,15 @@ export default class Workplace extends PureComponent {
} }
renderActivities() { renderActivities() {
const { const { activities: { list } } = this.props;
activities: { list }, return list.map(item => {
} = this.props; const events = item.template.split(/@\{([^{}]*)\}/gi).map(key => {
return list.map((item) => {
const events = item.template.split(/@\{([^{}]*)\}/gi).map((key) => {
if (item[key]) { if (item[key]) {
return <a href={item[key].link} key={item[key].name}>{item[key].name}</a>; return (
<a href={item[key].link} key={item[key].name}>
{item[key].name}
</a>
);
} }
return key; return key;
}); });
...@@ -142,7 +144,10 @@ export default class Workplace extends PureComponent { ...@@ -142,7 +144,10 @@ export default class Workplace extends PureComponent {
const pageHeaderContent = ( const pageHeaderContent = (
<div className={styles.pageHeaderContent}> <div className={styles.pageHeaderContent}>
<div className={styles.avatar}> <div className={styles.avatar}>
<Avatar size="large" src="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png" /> <Avatar
size="large"
src="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png"
/>
</div> </div>
<div className={styles.content}> <div className={styles.content}>
<div className={styles.contentTitle}>早安,曲丽丽,祝你开心每一天!</div> <div className={styles.contentTitle}>早安,曲丽丽,祝你开心每一天!</div>
...@@ -159,7 +164,9 @@ export default class Workplace extends PureComponent { ...@@ -159,7 +164,9 @@ export default class Workplace extends PureComponent {
</div> </div>
<div className={styles.statItem}> <div className={styles.statItem}>
<p>团队内排名</p> <p>团队内排名</p>
<p>8<span> / 24</span></p> <p>
8<span> / 24</span>
</p>
</div> </div>
<div className={styles.statItem}> <div className={styles.statItem}>
<p>项目访问</p> <p>项目访问</p>
...@@ -169,10 +176,7 @@ export default class Workplace extends PureComponent { ...@@ -169,10 +176,7 @@ export default class Workplace extends PureComponent {
); );
return ( return (
<PageHeaderLayout <PageHeaderLayout content={pageHeaderContent} extraContent={extraContent}>
content={pageHeaderContent}
extraContent={extraContent}
>
<Row gutter={24}> <Row gutter={24}>
<Col xl={16} lg={24} md={24} sm={24} xs={24}> <Col xl={16} lg={24} md={24} sm={24} xs={24}>
<Card <Card
...@@ -184,17 +188,16 @@ export default class Workplace extends PureComponent { ...@@ -184,17 +188,16 @@ export default class Workplace extends PureComponent {
loading={projectLoading} loading={projectLoading}
bodyStyle={{ padding: 0 }} bodyStyle={{ padding: 0 }}
> >
{ {notice.map(item => (
notice.map(item => (
<Card.Grid className={styles.projectGrid} key={item.id}> <Card.Grid className={styles.projectGrid} key={item.id}>
<Card bodyStyle={{ padding: 0 }} bordered={false}> <Card bodyStyle={{ padding: 0 }} bordered={false}>
<Card.Meta <Card.Meta
title={( title={
<div className={styles.cardTitle}> <div className={styles.cardTitle}>
<Avatar size="small" src={item.logo} /> <Avatar size="small" src={item.logo} />
<Link to={item.href}>{item.title}</Link> <Link to={item.href}>{item.title}</Link>
</div> </div>
)} }
description={item.description} description={item.description}
/> />
<div className={styles.projectItemContent}> <div className={styles.projectItemContent}>
...@@ -207,8 +210,7 @@ export default class Workplace extends PureComponent { ...@@ -207,8 +210,7 @@ export default class Workplace extends PureComponent {
</div> </div>
</Card> </Card>
</Card.Grid> </Card.Grid>
)) ))}
}
</Card> </Card>
<Card <Card
bodyStyle={{ padding: 0 }} bodyStyle={{ padding: 0 }}
...@@ -218,9 +220,7 @@ export default class Workplace extends PureComponent { ...@@ -218,9 +220,7 @@ export default class Workplace extends PureComponent {
loading={activitiesLoading} loading={activitiesLoading}
> >
<List loading={activitiesLoading} size="large"> <List loading={activitiesLoading} size="large">
<div className={styles.activitiesList}> <div className={styles.activitiesList}>{this.renderActivities()}</div>
{this.renderActivities()}
</div>
</List> </List>
</Card> </Card>
</Col> </Col>
...@@ -231,11 +231,7 @@ export default class Workplace extends PureComponent { ...@@ -231,11 +231,7 @@ export default class Workplace extends PureComponent {
bordered={false} bordered={false}
bodyStyle={{ padding: 0 }} bodyStyle={{ padding: 0 }}
> >
<EditableLinkGroup <EditableLinkGroup onAdd={() => {}} links={links} linkElement={Link} />
onAdd={() => {}}
links={links}
linkElement={Link}
/>
</Card> </Card>
<Card <Card
style={{ marginBottom: 24 }} style={{ marginBottom: 24 }}
...@@ -247,23 +243,17 @@ export default class Workplace extends PureComponent { ...@@ -247,23 +243,17 @@ export default class Workplace extends PureComponent {
<Radar hasLegend height={343} data={radarData} /> <Radar hasLegend height={343} data={radarData} />
</div> </div>
</Card> </Card>
<Card <Card bodyStyle={{ paddingTop: 12, paddingBottom: 12 }} bordered={false} title="团队">
bodyStyle={{ paddingTop: 12, paddingBottom: 12 }}
bordered={false}
title="团队"
>
<div className={styles.members}> <div className={styles.members}>
<Row gutter={48}> <Row gutter={48}>
{ {members.map(item => (
members.map(item => (
<Col span={12} key={`members-item-${item.id}`}> <Col span={12} key={`members-item-${item.id}`}>
<Link to={item.link}> <Link to={item.link}>
<Avatar src={item.logo} size="small" /> <Avatar src={item.logo} size="small" />
<span className={styles.member}>{item.title}</span> <span className={styles.member}>{item.title}</span>
</Link> </Link>
</Col> </Col>
)) ))}
}
</Row> </Row>
</div> </div>
</Card> </Card>
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
@import "../../utils/utils.less"; @import '../../utils/utils.less';
.activitiesList { .activitiesList {
padding: 0 24px 8px 24px; padding: 0 24px 8px 24px;
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
max-width: 100px; max-width: 100px;
vertical-align: top; vertical-align: top;
margin-left: 12px; margin-left: 12px;
transition: all .3s; transition: all 0.3s;
display: inline-block; display: inline-block;
.textOverflow(); .textOverflow();
} }
......
.trigger { .trigger {
background: "red"; background: 'red';
:global(.ant-btn) { :global(.ant-btn) {
margin-right: 8px; margin-right: 8px;
margin-bottom: 12px; margin-bottom: 12px;
......
...@@ -10,7 +10,7 @@ export default class TriggerException extends PureComponent { ...@@ -10,7 +10,7 @@ export default class TriggerException extends PureComponent {
state = { state = {
isloading: false, isloading: false,
}; };
triggerError = (code) => { triggerError = code => {
this.setState({ this.setState({
isloading: true, isloading: true,
}); });
......
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { Card, Button, Form, Icon, Col, Row, DatePicker, TimePicker, Input, Select, Popover } from 'antd'; import {
Card,
Button,
Form,
Icon,
Col,
Row,
DatePicker,
TimePicker,
Input,
Select,
Popover,
} from 'antd';
import { connect } from 'dva'; import { connect } from 'dva';
import FooterToolbar from 'components/FooterToolbar'; import FooterToolbar from 'components/FooterToolbar';
import PageHeaderLayout from '../../layouts/PageHeaderLayout'; import PageHeaderLayout from '../../layouts/PageHeaderLayout';
...@@ -24,22 +36,26 @@ const fieldLabels = { ...@@ -24,22 +36,26 @@ const fieldLabels = {
type2: '任务类型', type2: '任务类型',
}; };
const tableData = [{ const tableData = [
{
key: '1', key: '1',
workId: '00001', workId: '00001',
name: 'John Brown', name: 'John Brown',
department: 'New York No. 1 Lake Park', department: 'New York No. 1 Lake Park',
}, { },
{
key: '2', key: '2',
workId: '00002', workId: '00002',
name: 'Jim Green', name: 'Jim Green',
department: 'London No. 1 Lake Park', department: 'London No. 1 Lake Park',
}, { },
{
key: '3', key: '3',
workId: '00003', workId: '00003',
name: 'Joe Black', name: 'Joe Black',
department: 'Sidney No. 1 Lake Park', department: 'Sidney No. 1 Lake Park',
}]; },
];
class AdvancedForm extends PureComponent { class AdvancedForm extends PureComponent {
state = { state = {
...@@ -57,7 +73,7 @@ class AdvancedForm extends PureComponent { ...@@ -57,7 +73,7 @@ class AdvancedForm extends PureComponent {
if (this.state.width !== width) { if (this.state.width !== width) {
this.setState({ width }); this.setState({ width });
} }
} };
render() { render() {
const { form, dispatch, submitting } = this.props; const { form, dispatch, submitting } = this.props;
const { getFieldDecorator, validateFieldsAndScroll, getFieldsError } = form; const { getFieldDecorator, validateFieldsAndScroll, getFieldsError } = form;
...@@ -78,13 +94,13 @@ class AdvancedForm extends PureComponent { ...@@ -78,13 +94,13 @@ class AdvancedForm extends PureComponent {
if (!errors || errorCount === 0) { if (!errors || errorCount === 0) {
return null; return null;
} }
const scrollToField = (fieldKey) => { const scrollToField = fieldKey => {
const labelNode = document.querySelector(`label[for="${fieldKey}"]`); const labelNode = document.querySelector(`label[for="${fieldKey}"]`);
if (labelNode) { if (labelNode) {
labelNode.scrollIntoView(true); labelNode.scrollIntoView(true);
} }
}; };
const errorList = Object.keys(errors).map((key) => { const errorList = Object.keys(errors).map(key => {
if (!errors[key]) { if (!errors[key]) {
return null; return null;
} }
...@@ -124,9 +140,7 @@ class AdvancedForm extends PureComponent { ...@@ -124,9 +140,7 @@ class AdvancedForm extends PureComponent {
<Form.Item label={fieldLabels.name}> <Form.Item label={fieldLabels.name}>
{getFieldDecorator('name', { {getFieldDecorator('name', {
rules: [{ required: true, message: '请输入仓库名称' }], rules: [{ required: true, message: '请输入仓库名称' }],
})( })(<Input placeholder="请输入仓库名称" />)}
<Input placeholder="请输入仓库名称" />
)}
</Form.Item> </Form.Item>
</Col> </Col>
<Col xl={{ span: 6, offset: 2 }} lg={{ span: 8 }} md={{ span: 12 }} sm={24}> <Col xl={{ span: 6, offset: 2 }} lg={{ span: 8 }} md={{ span: 12 }} sm={24}>
...@@ -200,18 +214,14 @@ class AdvancedForm extends PureComponent { ...@@ -200,18 +214,14 @@ class AdvancedForm extends PureComponent {
<Form.Item label={fieldLabels.name2}> <Form.Item label={fieldLabels.name2}>
{getFieldDecorator('name2', { {getFieldDecorator('name2', {
rules: [{ required: true, message: '请输入' }], rules: [{ required: true, message: '请输入' }],
})( })(<Input placeholder="请输入" />)}
<Input placeholder="请输入" />
)}
</Form.Item> </Form.Item>
</Col> </Col>
<Col xl={{ span: 6, offset: 2 }} lg={{ span: 8 }} md={{ span: 12 }} sm={24}> <Col xl={{ span: 6, offset: 2 }} lg={{ span: 8 }} md={{ span: 12 }} sm={24}>
<Form.Item label={fieldLabels.url2}> <Form.Item label={fieldLabels.url2}>
{getFieldDecorator('url2', { {getFieldDecorator('url2', {
rules: [{ required: true, message: '请选择' }], rules: [{ required: true, message: '请选择' }],
})( })(<Input placeholder="请输入" />)}
<Input placeholder="请输入" />
)}
</Form.Item> </Form.Item>
</Col> </Col>
<Col xl={{ span: 8, offset: 2 }} lg={{ span: 10 }} md={{ span: 24 }} sm={24}> <Col xl={{ span: 8, offset: 2 }} lg={{ span: 10 }} md={{ span: 24 }} sm={24}>
......
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { connect } from 'dva'; import { connect } from 'dva';
import { import {
Form, Input, DatePicker, Select, Button, Card, InputNumber, Radio, Icon, Tooltip, Form,
Input,
DatePicker,
Select,
Button,
Card,
InputNumber,
Radio,
Icon,
Tooltip,
} from 'antd'; } from 'antd';
import PageHeaderLayout from '../../layouts/PageHeaderLayout'; import PageHeaderLayout from '../../layouts/PageHeaderLayout';
import styles from './style.less'; import styles from './style.less';
...@@ -16,7 +25,7 @@ const { TextArea } = Input; ...@@ -16,7 +25,7 @@ const { TextArea } = Input;
})) }))
@Form.create() @Form.create()
export default class BasicForms extends PureComponent { export default class BasicForms extends PureComponent {
handleSubmit = (e) => { handleSubmit = e => {
e.preventDefault(); e.preventDefault();
this.props.form.validateFieldsAndScroll((err, values) => { this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) { if (!err) {
...@@ -26,7 +35,7 @@ export default class BasicForms extends PureComponent { ...@@ -26,7 +35,7 @@ export default class BasicForms extends PureComponent {
}); });
} }
}); });
} };
render() { render() {
const { submitting } = this.props; const { submitting } = this.props;
const { getFieldDecorator, getFieldValue } = this.props.form; const { getFieldDecorator, getFieldValue } = this.props.form;
...@@ -51,60 +60,57 @@ export default class BasicForms extends PureComponent { ...@@ -51,60 +60,57 @@ export default class BasicForms extends PureComponent {
}; };
return ( return (
<PageHeaderLayout title="基础表单" content="表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。"> <PageHeaderLayout
<Card bordered={false}> title="基础表单"
<Form content="表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。"
onSubmit={this.handleSubmit}
hideRequiredMark
style={{ marginTop: 8 }}
>
<FormItem
{...formItemLayout}
label="标题"
> >
<Card bordered={false}>
<Form onSubmit={this.handleSubmit} hideRequiredMark style={{ marginTop: 8 }}>
<FormItem {...formItemLayout} label="标题">
{getFieldDecorator('title', { {getFieldDecorator('title', {
rules: [{ rules: [
required: true, message: '请输入标题', {
}], required: true,
})( message: '请输入标题',
<Input placeholder="给目标起个名字" /> },
)} ],
})(<Input placeholder="给目标起个名字" />)}
</FormItem> </FormItem>
<FormItem <FormItem {...formItemLayout} label="起止日期">
{...formItemLayout}
label="起止日期"
>
{getFieldDecorator('date', { {getFieldDecorator('date', {
rules: [{ rules: [
required: true, message: '请选择起止日期', {
}], required: true,
})( message: '请选择起止日期',
<RangePicker style={{ width: '100%' }} placeholder={['开始日期', '结束日期']} /> },
)} ],
})(<RangePicker style={{ width: '100%' }} placeholder={['开始日期', '结束日期']} />)}
</FormItem> </FormItem>
<FormItem <FormItem {...formItemLayout} label="目标描述">
{...formItemLayout}
label="目标描述"
>
{getFieldDecorator('goal', { {getFieldDecorator('goal', {
rules: [{ rules: [
required: true, message: '请输入目标描述', {
}], required: true,
message: '请输入目标描述',
},
],
})( })(
<TextArea style={{ minHeight: 32 }} placeholder="请输入你的阶段性工作目标" rows={4} /> <TextArea
style={{ minHeight: 32 }}
placeholder="请输入你的阶段性工作目标"
rows={4}
/>
)} )}
</FormItem> </FormItem>
<FormItem <FormItem {...formItemLayout} label="衡量标准">
{...formItemLayout}
label="衡量标准"
>
{getFieldDecorator('standard', { {getFieldDecorator('standard', {
rules: [{ rules: [
required: true, message: '请输入衡量标准', {
}], required: true,
})( message: '请输入衡量标准',
<TextArea style={{ minHeight: 32 }} placeholder="请输入衡量标准" rows={4} /> },
)} ],
})(<TextArea style={{ minHeight: 32 }} placeholder="请输入衡量标准" rows={4} />)}
</FormItem> </FormItem>
<FormItem <FormItem
{...formItemLayout} {...formItemLayout}
...@@ -126,7 +132,11 @@ export default class BasicForms extends PureComponent { ...@@ -126,7 +132,11 @@ export default class BasicForms extends PureComponent {
</FormItem> </FormItem>
<FormItem <FormItem
{...formItemLayout} {...formItemLayout}
label={<span>邀评人<em className={styles.optional}>(选填)</em></span>} label={
<span>
邀评人<em className={styles.optional}>(选填)</em>
</span>
}
> >
{getFieldDecorator('invites')( {getFieldDecorator('invites')(
<Input placeholder="请直接 @姓名/工号,最多可邀请 5 人" /> <Input placeholder="请直接 @姓名/工号,最多可邀请 5 人" />
...@@ -134,18 +144,16 @@ export default class BasicForms extends PureComponent { ...@@ -134,18 +144,16 @@ export default class BasicForms extends PureComponent {
</FormItem> </FormItem>
<FormItem <FormItem
{...formItemLayout} {...formItemLayout}
label={<span>权重<em className={styles.optional}>(选填)</em></span>} label={
<span>
权重<em className={styles.optional}>(选填)</em>
</span>
}
> >
{getFieldDecorator('weight')( {getFieldDecorator('weight')(<InputNumber placeholder="请输入" min={0} max={100} />)}
<InputNumber placeholder="请输入" min={0} max={100} />
)}
<span>%</span> <span>%</span>
</FormItem> </FormItem>
<FormItem <FormItem {...formItemLayout} label="目标公开" help="客户、邀评人默认被分享">
{...formItemLayout}
label="目标公开"
help="客户、邀评人默认被分享"
>
<div> <div>
{getFieldDecorator('public', { {getFieldDecorator('public', {
initialValue: '1', initialValue: '1',
......
...@@ -34,10 +34,7 @@ class Step1 extends React.PureComponent { ...@@ -34,10 +34,7 @@ class Step1 extends React.PureComponent {
return ( return (
<Fragment> <Fragment>
<Form layout="horizontal" className={styles.stepForm} hideRequiredMark> <Form layout="horizontal" className={styles.stepForm} hideRequiredMark>
<Form.Item <Form.Item {...formItemLayout} label="付款账户">
{...formItemLayout}
label="付款账户"
>
{getFieldDecorator('payAccount', { {getFieldDecorator('payAccount', {
initialValue: data.payAccount, initialValue: data.payAccount,
rules: [{ required: true, message: '请选择付款账户' }], rules: [{ required: true, message: '请选择付款账户' }],
...@@ -47,10 +44,7 @@ class Step1 extends React.PureComponent { ...@@ -47,10 +44,7 @@ class Step1 extends React.PureComponent {
</Select> </Select>
)} )}
</Form.Item> </Form.Item>
<Form.Item <Form.Item {...formItemLayout} label="收款账户">
{...formItemLayout}
label="收款账户"
>
<Input.Group compact> <Input.Group compact>
<Select defaultValue="alipay" style={{ width: 100 }}> <Select defaultValue="alipay" style={{ width: 100 }}>
<Option value="alipay">支付宝</Option> <Option value="alipay">支付宝</Option>
...@@ -62,40 +56,34 @@ class Step1 extends React.PureComponent { ...@@ -62,40 +56,34 @@ class Step1 extends React.PureComponent {
{ required: true, message: '请输入收款人账户' }, { required: true, message: '请输入收款人账户' },
{ type: 'email', message: '账户名应为邮箱格式' }, { type: 'email', message: '账户名应为邮箱格式' },
], ],
})( })(<Input style={{ width: 'calc(100% - 100px)' }} placeholder="test@example.com" />)}
<Input style={{ width: 'calc(100% - 100px)' }} placeholder="test@example.com" />
)}
</Input.Group> </Input.Group>
</Form.Item> </Form.Item>
<Form.Item <Form.Item {...formItemLayout} label="收款人姓名">
{...formItemLayout}
label="收款人姓名"
>
{getFieldDecorator('receiverName', { {getFieldDecorator('receiverName', {
initialValue: data.receiverName, initialValue: data.receiverName,
rules: [{ required: true, message: '请输入收款人姓名' }], rules: [{ required: true, message: '请输入收款人姓名' }],
})( })(<Input placeholder="请输入收款人姓名" />)}
<Input placeholder="请输入收款人姓名" />
)}
</Form.Item> </Form.Item>
<Form.Item <Form.Item {...formItemLayout} label="转账金额">
{...formItemLayout}
label="转账金额"
>
{getFieldDecorator('amount', { {getFieldDecorator('amount', {
initialValue: data.amount, initialValue: data.amount,
rules: [ rules: [
{ required: true, message: '请输入转账金额' }, { required: true, message: '请输入转账金额' },
{ pattern: /^(\d+)((?:\.\d+)?)$/, message: '请输入合法金额数字' }, {
pattern: /^(\d+)((?:\.\d+)?)$/,
message: '请输入合法金额数字',
},
], ],
})( })(<Input prefix="¥" placeholder="请输入金额" />)}
<Input prefix="¥" placeholder="请输入金额" />
)}
</Form.Item> </Form.Item>
<Form.Item <Form.Item
wrapperCol={{ wrapperCol={{
xs: { span: 24, offset: 0 }, xs: { span: 24, offset: 0 },
sm: { span: formItemLayout.wrapperCol.span, offset: formItemLayout.labelCol.span }, sm: {
span: formItemLayout.wrapperCol.span,
offset: formItemLayout.labelCol.span,
},
}} }}
label="" label=""
> >
...@@ -108,9 +96,13 @@ class Step1 extends React.PureComponent { ...@@ -108,9 +96,13 @@ class Step1 extends React.PureComponent {
<div className={styles.desc}> <div className={styles.desc}>
<h3>说明</h3> <h3>说明</h3>
<h4>转账到支付宝账户</h4> <h4>转账到支付宝账户</h4>
<p>如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。</p> <p>
如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。
</p>
<h4>转账到银行卡</h4> <h4>转账到银行卡</h4>
<p>如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。</p> <p>
如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。如果需要,这里可以放一些关于产品的常见问题说明。
</p>
</div> </div>
</Fragment> </Fragment>
); );
......
...@@ -22,7 +22,7 @@ class Step2 extends React.PureComponent { ...@@ -22,7 +22,7 @@ class Step2 extends React.PureComponent {
const onPrev = () => { const onPrev = () => {
dispatch(routerRedux.push('/form/step-form')); dispatch(routerRedux.push('/form/step-form'));
}; };
const onValidateForm = (e) => { const onValidateForm = e => {
e.preventDefault(); e.preventDefault();
validateFields((err, values) => { validateFields((err, values) => {
if (!err) { if (!err) {
...@@ -44,55 +44,39 @@ class Step2 extends React.PureComponent { ...@@ -44,55 +44,39 @@ class Step2 extends React.PureComponent {
message="确认转账后,资金将直接打入对方账户,无法退回。" message="确认转账后,资金将直接打入对方账户,无法退回。"
style={{ marginBottom: 24 }} style={{ marginBottom: 24 }}
/> />
<Form.Item <Form.Item {...formItemLayout} className={styles.stepFormText} label="付款账户">
{...formItemLayout}
className={styles.stepFormText}
label="付款账户"
>
{data.payAccount} {data.payAccount}
</Form.Item> </Form.Item>
<Form.Item <Form.Item {...formItemLayout} className={styles.stepFormText} label="收款账户">
{...formItemLayout}
className={styles.stepFormText}
label="收款账户"
>
{data.receiverAccount} {data.receiverAccount}
</Form.Item> </Form.Item>
<Form.Item <Form.Item {...formItemLayout} className={styles.stepFormText} label="收款人姓名">
{...formItemLayout}
className={styles.stepFormText}
label="收款人姓名"
>
{data.receiverName} {data.receiverName}
</Form.Item> </Form.Item>
<Form.Item <Form.Item {...formItemLayout} className={styles.stepFormText} label="转账金额">
{...formItemLayout}
className={styles.stepFormText}
label="转账金额"
>
<span className={styles.money}>{data.amount}</span> <span className={styles.money}>{data.amount}</span>
<span className={styles.uppercase}>({digitUppercase(data.amount)})</span> <span className={styles.uppercase}>({digitUppercase(data.amount)})</span>
</Form.Item> </Form.Item>
<Divider style={{ margin: '24px 0' }} /> <Divider style={{ margin: '24px 0' }} />
<Form.Item <Form.Item {...formItemLayout} label="支付密码" required={false}>
{...formItemLayout}
label="支付密码"
required={false}
>
{getFieldDecorator('password', { {getFieldDecorator('password', {
initialValue: '123456', initialValue: '123456',
rules: [{ rules: [
required: true, message: '需要支付密码才能进行支付', {
}], required: true,
})( message: '需要支付密码才能进行支付',
<Input type="password" autoComplete="off" style={{ width: '80%' }} /> },
)} ],
})(<Input type="password" autoComplete="off" style={{ width: '80%' }} />)}
</Form.Item> </Form.Item>
<Form.Item <Form.Item
style={{ marginBottom: 8 }} style={{ marginBottom: 8 }}
wrapperCol={{ wrapperCol={{
xs: { span: 24, offset: 0 }, xs: { span: 24, offset: 0 },
sm: { span: formItemLayout.wrapperCol.span, offset: formItemLayout.labelCol.span }, sm: {
span: formItemLayout.wrapperCol.span,
offset: formItemLayout.labelCol.span,
},
}} }}
label="" label=""
> >
......
...@@ -14,20 +14,30 @@ class Step3 extends React.PureComponent { ...@@ -14,20 +14,30 @@ class Step3 extends React.PureComponent {
const information = ( const information = (
<div className={styles.information}> <div className={styles.information}>
<Row> <Row>
<Col span={8} className={styles.label}>付款账户:</Col> <Col span={8} className={styles.label}>
付款账户:
</Col>
<Col span={16}>{data.payAccount}</Col> <Col span={16}>{data.payAccount}</Col>
</Row> </Row>
<Row> <Row>
<Col span={8} className={styles.label}>收款账户:</Col> <Col span={8} className={styles.label}>
收款账户:
</Col>
<Col span={16}>{data.receiverAccount}</Col> <Col span={16}>{data.receiverAccount}</Col>
</Row> </Row>
<Row> <Row>
<Col span={8} className={styles.label}>收款人姓名:</Col> <Col span={8} className={styles.label}>
收款人姓名:
</Col>
<Col span={16}>{data.receiverName}</Col> <Col span={16}>{data.receiverName}</Col>
</Row> </Row>
<Row> <Row>
<Col span={8} className={styles.label}>转账金额:</Col> <Col span={8} className={styles.label}>
<Col span={16}><span className={styles.money}>{data.amount}</span> 元</Col> 转账金额:
</Col>
<Col span={16}>
<span className={styles.money}>{data.amount}</span> 元
</Col>
</Row> </Row>
</div> </div>
); );
...@@ -36,9 +46,7 @@ class Step3 extends React.PureComponent { ...@@ -36,9 +46,7 @@ class Step3 extends React.PureComponent {
<Button type="primary" onClick={onFinish}> <Button type="primary" onClick={onFinish}>
再转一笔 再转一笔
</Button> </Button>
<Button> <Button>查看账单</Button>
查看账单
</Button>
</Fragment> </Fragment>
); );
return ( return (
......
...@@ -14,16 +14,23 @@ export default class StepForm extends PureComponent { ...@@ -14,16 +14,23 @@ export default class StepForm extends PureComponent {
const { pathname } = location; const { pathname } = location;
const pathList = pathname.split('/'); const pathList = pathname.split('/');
switch (pathList[pathList.length - 1]) { switch (pathList[pathList.length - 1]) {
case 'info': return 0; case 'info':
case 'confirm': return 1; return 0;
case 'result': return 2; case 'confirm':
default: return 0; return 1;
case 'result':
return 2;
default:
return 0;
} }
} }
render() { render() {
const { match, routerData } = this.props; const { match, routerData } = this.props;
return ( return (
<PageHeaderLayout title="分步表单" content="将一个冗长或用户不熟悉的表单任务分成多个步骤,指导用户完成。"> <PageHeaderLayout
title="分步表单"
content="将一个冗长或用户不熟悉的表单任务分成多个步骤,指导用户完成。"
>
<Card bordered={false}> <Card bordered={false}>
<Fragment> <Fragment>
<Steps current={this.getCurrentStep()} className={styles.steps}> <Steps current={this.getCurrentStep()} className={styles.steps}>
...@@ -32,16 +39,14 @@ export default class StepForm extends PureComponent { ...@@ -32,16 +39,14 @@ export default class StepForm extends PureComponent {
<Step title="完成" /> <Step title="完成" />
</Steps> </Steps>
<Switch> <Switch>
{ {getRoutes(match.path, routerData).map(item => (
getRoutes(match.path, routerData).map(item => (
<Route <Route
key={item.key} key={item.key}
path={item.path} path={item.path}
component={item.component} component={item.component}
exact={item.exact} exact={item.exact}
/> />
)) ))}
}
<Redirect exact from="/form/step-form" to="/form/step-form/info" /> <Redirect exact from="/form/step-form" to="/form/step-form/info" />
<Route render={NotFound} /> <Route render={NotFound} />
</Switch> </Switch>
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.stepForm { .stepForm {
margin: 40px auto 0; margin: 40px auto 0;
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
} }
.money { .money {
font-family: "Helvetica Neue", sans-serif; font-family: 'Helvetica Neue', sans-serif;
font-weight: 500; font-weight: 500;
font-size: 20px; font-size: 20px;
line-height: 14px; line-height: 14px;
......
...@@ -23,7 +23,7 @@ export default class TableForm extends PureComponent { ...@@ -23,7 +23,7 @@ export default class TableForm extends PureComponent {
} }
index = 0; index = 0;
cacheOriginData = {}; cacheOriginData = {};
toggleEditable=(e, key) => { toggleEditable = (e, key) => {
e.preventDefault(); e.preventDefault();
const newData = this.state.data.map(item => ({ ...item })); const newData = this.state.data.map(item => ({ ...item }));
const target = this.getRowByKey(key, newData); const target = this.getRowByKey(key, newData);
...@@ -35,7 +35,7 @@ export default class TableForm extends PureComponent { ...@@ -35,7 +35,7 @@ export default class TableForm extends PureComponent {
target.editable = !target.editable; target.editable = !target.editable;
this.setState({ data: newData }); this.setState({ data: newData });
} }
} };
remove(key) { remove(key) {
const newData = this.state.data.filter(item => item.key !== key); const newData = this.state.data.filter(item => item.key !== key);
this.setState({ data: newData }); this.setState({ data: newData });
...@@ -53,7 +53,7 @@ export default class TableForm extends PureComponent { ...@@ -53,7 +53,7 @@ export default class TableForm extends PureComponent {
}); });
this.index += 1; this.index += 1;
this.setState({ data: newData }); this.setState({ data: newData });
} };
handleKeyPress(e, key) { handleKeyPress(e, key) {
if (e.key === 'Enter') { if (e.key === 'Enter') {
this.saveRow(e, key); this.saveRow(e, key);
...@@ -108,7 +108,8 @@ export default class TableForm extends PureComponent { ...@@ -108,7 +108,8 @@ export default class TableForm extends PureComponent {
this.clickedCancel = false; this.clickedCancel = false;
} }
render() { render() {
const columns = [{ const columns = [
{
title: '成员姓名', title: '成员姓名',
dataIndex: 'name', dataIndex: 'name',
key: 'name', key: 'name',
...@@ -127,7 +128,8 @@ export default class TableForm extends PureComponent { ...@@ -127,7 +128,8 @@ export default class TableForm extends PureComponent {
} }
return text; return text;
}, },
}, { },
{
title: '工号', title: '工号',
dataIndex: 'workId', dataIndex: 'workId',
key: 'workId', key: 'workId',
...@@ -145,7 +147,8 @@ export default class TableForm extends PureComponent { ...@@ -145,7 +147,8 @@ export default class TableForm extends PureComponent {
} }
return text; return text;
}, },
}, { },
{
title: '所属部门', title: '所属部门',
dataIndex: 'department', dataIndex: 'department',
key: 'department', key: 'department',
...@@ -163,7 +166,8 @@ export default class TableForm extends PureComponent { ...@@ -163,7 +166,8 @@ export default class TableForm extends PureComponent {
} }
return text; return text;
}, },
}, { },
{
title: '操作', title: '操作',
key: 'action', key: 'action',
render: (text, record) => { render: (text, record) => {
...@@ -200,7 +204,8 @@ export default class TableForm extends PureComponent { ...@@ -200,7 +204,8 @@ export default class TableForm extends PureComponent {
</span> </span>
); );
}, },
}]; },
];
return ( return (
<Fragment> <Fragment>
...@@ -209,7 +214,7 @@ export default class TableForm extends PureComponent { ...@@ -209,7 +214,7 @@ export default class TableForm extends PureComponent {
columns={columns} columns={columns}
dataSource={this.state.data} dataSource={this.state.data}
pagination={false} pagination={false}
rowClassName={(record) => { rowClassName={record => {
return record.editable ? styles.editable : ''; return record.editable ? styles.editable : '';
}} }}
/> />
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.card { .card {
margin-bottom: 24px; margin-bottom: 24px;
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
border-bottom: 1px solid @border-color-split; border-bottom: 1px solid @border-color-split;
padding: 8px 16px; padding: 8px 16px;
cursor: pointer; cursor: pointer;
transition: all .3s; transition: all 0.3s;
&:hover { &:hover {
background: @primary-1; background: @primary-1;
} }
......
...@@ -11,14 +11,19 @@ import styles from './Applications.less'; ...@@ -11,14 +11,19 @@ import styles from './Applications.less';
const { Option } = Select; const { Option } = Select;
const FormItem = Form.Item; const FormItem = Form.Item;
const formatWan = (val) => { const formatWan = val => {
const v = val * 1; const v = val * 1;
if (!v || isNaN(v)) return ''; if (!v || isNaN(v)) return '';
let result = val; let result = val;
if (val > 10000) { if (val > 10000) {
result = Math.floor(val / 10000); result = Math.floor(val / 10000);
result = <span>{result}<em className={styles.wan}>万</em></span>; result = (
<span>
{result}
<em className={styles.wan}>万</em>
</span>
);
} }
return result; return result;
}; };
...@@ -43,7 +48,7 @@ export default class FilterCardList extends PureComponent { ...@@ -43,7 +48,7 @@ export default class FilterCardList extends PureComponent {
const { form, dispatch } = this.props; const { form, dispatch } = this.props;
// setTimeout 用于保证获取表单值是在所有表单字段更新完毕的时候 // setTimeout 用于保证获取表单值是在所有表单字段更新完毕的时候
setTimeout(() => { setTimeout(() => {
form.validateFields((err) => { form.validateFields(err => {
if (!err) { if (!err) {
// eslint-disable-next-line // eslint-disable-next-line
dispatch({ dispatch({
...@@ -55,7 +60,7 @@ export default class FilterCardList extends PureComponent { ...@@ -55,7 +60,7 @@ export default class FilterCardList extends PureComponent {
} }
}); });
}, 0); }, 0);
} };
render() { render() {
const { list: { list }, loading, form } = this.props; const { list: { list }, loading, form } = this.props;
...@@ -84,13 +89,19 @@ export default class FilterCardList extends PureComponent { ...@@ -84,13 +89,19 @@ export default class FilterCardList extends PureComponent {
const itemMenu = ( const itemMenu = (
<Menu> <Menu>
<Menu.Item> <Menu.Item>
<a target="_blank" rel="noopener noreferrer" href="http://www.alipay.com/">1st menu item</a> <a target="_blank" rel="noopener noreferrer" href="http://www.alipay.com/">
1st menu item
</a>
</Menu.Item> </Menu.Item>
<Menu.Item> <Menu.Item>
<a target="_blank" rel="noopener noreferrer" href="http://www.taobao.com/">2nd menu item</a> <a target="_blank" rel="noopener noreferrer" href="http://www.taobao.com/">
2nd menu item
</a>
</Menu.Item> </Menu.Item>
<Menu.Item> <Menu.Item>
<a target="_blank" rel="noopener noreferrer" href="http://www.tmall.com/">3d menu item</a> <a target="_blank" rel="noopener noreferrer" href="http://www.tmall.com/">
3d menu item
</a>
</Menu.Item> </Menu.Item>
</Menu> </Menu>
); );
...@@ -119,17 +130,10 @@ export default class FilterCardList extends PureComponent { ...@@ -119,17 +130,10 @@ export default class FilterCardList extends PureComponent {
)} )}
</FormItem> </FormItem>
</StandardFormRow> </StandardFormRow>
<StandardFormRow <StandardFormRow title="其它选项" grid last>
title="其它选项"
grid
last
>
<Row gutter={16}> <Row gutter={16}>
<Col lg={8} md={10} sm={10} xs={24}> <Col lg={8} md={10} sm={10} xs={24}>
<FormItem <FormItem {...formItemLayout} label="作者">
{...formItemLayout}
label="作者"
>
{getFieldDecorator('author', {})( {getFieldDecorator('author', {})(
<Select <Select
onChange={this.handleFormSubmit} onChange={this.handleFormSubmit}
...@@ -142,10 +146,7 @@ export default class FilterCardList extends PureComponent { ...@@ -142,10 +146,7 @@ export default class FilterCardList extends PureComponent {
</FormItem> </FormItem>
</Col> </Col>
<Col lg={8} md={10} sm={10} xs={24}> <Col lg={8} md={10} sm={10} xs={24}>
<FormItem <FormItem {...formItemLayout} label="好评度">
{...formItemLayout}
label="好评度"
>
{getFieldDecorator('rate', {})( {getFieldDecorator('rate', {})(
<Select <Select
onChange={this.handleFormSubmit} onChange={this.handleFormSubmit}
...@@ -174,16 +175,21 @@ export default class FilterCardList extends PureComponent { ...@@ -174,16 +175,21 @@ export default class FilterCardList extends PureComponent {
hoverable hoverable
bodyStyle={{ paddingBottom: 20 }} bodyStyle={{ paddingBottom: 20 }}
actions={[ actions={[
<Tooltip title="下载"><Icon type="download" /></Tooltip>, <Tooltip title="下载">
<Tooltip title="编辑"><Icon type="edit" /></Tooltip>, <Icon type="download" />
<Tooltip title="分享"><Icon type="share-alt" /></Tooltip>, </Tooltip>,
<Dropdown overlay={itemMenu}><Icon type="ellipsis" /></Dropdown>, <Tooltip title="编辑">
<Icon type="edit" />
</Tooltip>,
<Tooltip title="分享">
<Icon type="share-alt" />
</Tooltip>,
<Dropdown overlay={itemMenu}>
<Icon type="ellipsis" />
</Dropdown>,
]} ]}
> >
<Card.Meta <Card.Meta avatar={<Avatar size="small" src={item.avatar} />} title={item.title} />
avatar={<Avatar size="small" src={item.avatar} />}
title={item.title}
/>
<div className={styles.cardItemContent}> <div className={styles.cardItemContent}>
<CardInfo <CardInfo
activeUser={formatWan(item.activeUser)} activeUser={formatWan(item.activeUser)}
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
@import "../../utils/utils.less"; @import '../../utils/utils.less';
.filterCardList { .filterCardList {
margin-bottom: -24px; margin-bottom: -24px;
......
...@@ -27,7 +27,7 @@ export default class SearchList extends Component { ...@@ -27,7 +27,7 @@ export default class SearchList extends Component {
form.setFieldsValue({ form.setFieldsValue({
owner: ['wzj'], owner: ['wzj'],
}); });
} };
fetchMore = () => { fetchMore = () => {
this.props.dispatch({ this.props.dispatch({
...@@ -36,7 +36,7 @@ export default class SearchList extends Component { ...@@ -36,7 +36,7 @@ export default class SearchList extends Component {
count: pageSize, count: pageSize,
}, },
}); });
} };
render() { render() {
const { form, list: { list }, loading } = this.props; const { form, list: { list }, loading } = this.props;
...@@ -76,7 +76,8 @@ export default class SearchList extends Component { ...@@ -76,7 +76,8 @@ export default class SearchList extends Component {
<div className={styles.listContent}> <div className={styles.listContent}>
<div className={styles.description}>{content}</div> <div className={styles.description}>{content}</div>
<div className={styles.extra}> <div className={styles.extra}>
<Avatar src={avatar} size="small" /><a href={href}>{owner}</a> 发布在 <a href={href}>{href}</a> <Avatar src={avatar} size="small" />
<a href={href}>{owner}</a> 发布在 <a href={href}>{href}</a>
<em>{moment(updatedAt).format('YYYY-MM-DD HH:mm')}</em> <em>{moment(updatedAt).format('YYYY-MM-DD HH:mm')}</em>
</div> </div>
</div> </div>
...@@ -90,10 +91,17 @@ export default class SearchList extends Component { ...@@ -90,10 +91,17 @@ export default class SearchList extends Component {
}, },
}; };
const loadMore = list.length > 0 ? ( const loadMore =
list.length > 0 ? (
<div style={{ textAlign: 'center', marginTop: 16 }}> <div style={{ textAlign: 'center', marginTop: 16 }}>
<Button onClick={this.fetchMore} style={{ paddingLeft: 48, paddingRight: 48 }}> <Button onClick={this.fetchMore} style={{ paddingLeft: 48, paddingRight: 48 }}>
{loading ? <span><Icon type="loading" /> 加载中...</span> : '加载更多'} {loading ? (
<span>
<Icon type="loading" /> 加载中...
</span>
) : (
'加载更多'
)}
</Button> </Button>
</div> </div>
) : null; ) : null;
...@@ -122,10 +130,7 @@ export default class SearchList extends Component { ...@@ -122,10 +130,7 @@ export default class SearchList extends Component {
)} )}
</FormItem> </FormItem>
</StandardFormRow> </StandardFormRow>
<StandardFormRow <StandardFormRow title="owner" grid>
title="owner"
grid
>
<Row> <Row>
<Col lg={16} md={24} sm={24} xs={24}> <Col lg={16} md={24} sm={24} xs={24}>
<FormItem> <FormItem>
...@@ -137,29 +142,24 @@ export default class SearchList extends Component { ...@@ -137,29 +142,24 @@ export default class SearchList extends Component {
style={{ maxWidth: 286, width: '100%' }} style={{ maxWidth: 286, width: '100%' }}
placeholder="选择 owner" placeholder="选择 owner"
> >
{ {owners.map(owner => (
owners.map(owner => <Option key={owner.id} value={owner.id}>
<Option key={owner.id} value={owner.id}>{owner.name}</Option> {owner.name}
) </Option>
} ))}
</Select> </Select>
)} )}
<a className={styles.selfTrigger} onClick={this.setOwner}>只看自己的</a> <a className={styles.selfTrigger} onClick={this.setOwner}>
只看自己的
</a>
</FormItem> </FormItem>
</Col> </Col>
</Row> </Row>
</StandardFormRow> </StandardFormRow>
<StandardFormRow <StandardFormRow title="其它选项" grid last>
title="其它选项"
grid
last
>
<Row gutter={16}> <Row gutter={16}>
<Col xl={8} lg={10} md={12} sm={24} xs={24}> <Col xl={8} lg={10} md={12} sm={24} xs={24}>
<FormItem <FormItem {...formItemLayout} label="活跃用户">
{...formItemLayout}
label="活跃用户"
>
{getFieldDecorator('user', {})( {getFieldDecorator('user', {})(
<Select <Select
onChange={this.handleFormSubmit} onChange={this.handleFormSubmit}
...@@ -172,10 +172,7 @@ export default class SearchList extends Component { ...@@ -172,10 +172,7 @@ export default class SearchList extends Component {
</FormItem> </FormItem>
</Col> </Col>
<Col xl={8} lg={10} md={12} sm={24} xs={24}> <Col xl={8} lg={10} md={12} sm={24} xs={24}>
<FormItem <FormItem {...formItemLayout} label="好评度">
{...formItemLayout}
label="好评度"
>
{getFieldDecorator('rate', {})( {getFieldDecorator('rate', {})(
<Select <Select
onChange={this.handleFormSubmit} onChange={this.handleFormSubmit}
...@@ -214,9 +211,11 @@ export default class SearchList extends Component { ...@@ -214,9 +211,11 @@ export default class SearchList extends Component {
extra={<div className={styles.listItemExtra} />} extra={<div className={styles.listItemExtra} />}
> >
<List.Item.Meta <List.Item.Meta
title={( title={
<a className={styles.listItemMetaTitle} href={item.href}>{item.title}</a> <a className={styles.listItemMetaTitle} href={item.href}>
)} {item.title}
</a>
}
description={ description={
<span> <span>
<Tag>Ant Design</Tag> <Tag>Ant Design</Tag>
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
@import "../../utils/utils.less"; @import '../../utils/utils.less';
.listContent { .listContent {
.description { .description {
......
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import moment from 'moment'; import moment from 'moment';
import { connect } from 'dva'; import { connect } from 'dva';
import { List, Card, Row, Col, Radio, Input, Progress, Button, Icon, Dropdown, Menu, Avatar } from 'antd'; import {
List,
Card,
Row,
Col,
Radio,
Input,
Progress,
Button,
Icon,
Dropdown,
Menu,
Avatar,
} from 'antd';
import PageHeaderLayout from '../../layouts/PageHeaderLayout'; import PageHeaderLayout from '../../layouts/PageHeaderLayout';
...@@ -43,11 +56,7 @@ export default class BasicList extends PureComponent { ...@@ -43,11 +56,7 @@ export default class BasicList extends PureComponent {
<RadioButton value="progress">进行中</RadioButton> <RadioButton value="progress">进行中</RadioButton>
<RadioButton value="waiting">等待中</RadioButton> <RadioButton value="waiting">等待中</RadioButton>
</RadioGroup> </RadioGroup>
<Search <Search className={styles.extraContentSearch} placeholder="请输入" onSearch={() => ({})} />
className={styles.extraContentSearch}
placeholder="请输入"
onSearch={() => ({})}
/>
</div> </div>
); );
...@@ -128,9 +137,7 @@ export default class BasicList extends PureComponent { ...@@ -128,9 +137,7 @@ export default class BasicList extends PureComponent {
pagination={paginationProps} pagination={paginationProps}
dataSource={list} dataSource={list}
renderItem={item => ( renderItem={item => (
<List.Item <List.Item actions={[<a>编辑</a>, <MoreBtn />]}>
actions={[<a>编辑</a>, <MoreBtn />]}
>
<List.Item.Meta <List.Item.Meta
avatar={<Avatar src={item.logo} shape="square" size="large" />} avatar={<Avatar src={item.logo} shape="square" size="large" />}
title={<a href={item.href}>{item.title}</a>} title={<a href={item.href}>{item.title}</a>}
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
@import "../../utils/utils.less"; @import '../../utils/utils.less';
.standardList { .standardList {
:global { :global {
......
...@@ -32,13 +32,16 @@ export default class CardList extends PureComponent { ...@@ -32,13 +32,16 @@ export default class CardList extends PureComponent {
</p> </p>
<div className={styles.contentLink}> <div className={styles.contentLink}>
<a> <a>
<img alt="" src="https://gw.alipayobjects.com/zos/rmsportal/MjEImQtenlyueSmVEfUD.svg" /> 快速开始 <img alt="" src="https://gw.alipayobjects.com/zos/rmsportal/MjEImQtenlyueSmVEfUD.svg" />{' '}
快速开始
</a> </a>
<a> <a>
<img alt="" src="https://gw.alipayobjects.com/zos/rmsportal/NbuDUAuBlIApFuDvWiND.svg" /> 产品简介 <img alt="" src="https://gw.alipayobjects.com/zos/rmsportal/NbuDUAuBlIApFuDvWiND.svg" />{' '}
产品简介
</a> </a>
<a> <a>
<img alt="" src="https://gw.alipayobjects.com/zos/rmsportal/ohOEPSYdDTNnyMbGuyLb.svg" /> 产品文档 <img alt="" src="https://gw.alipayobjects.com/zos/rmsportal/ohOEPSYdDTNnyMbGuyLb.svg" />{' '}
产品文档
</a> </a>
</div> </div>
</div> </div>
...@@ -46,31 +49,33 @@ export default class CardList extends PureComponent { ...@@ -46,31 +49,33 @@ export default class CardList extends PureComponent {
const extraContent = ( const extraContent = (
<div className={styles.extraImg}> <div className={styles.extraImg}>
<img alt="这是一个标题" src="https://gw.alipayobjects.com/zos/rmsportal/RzwpdLnhmvDJToTdfDPe.png" /> <img
alt="这是一个标题"
src="https://gw.alipayobjects.com/zos/rmsportal/RzwpdLnhmvDJToTdfDPe.png"
/>
</div> </div>
); );
return ( return (
<PageHeaderLayout <PageHeaderLayout title="卡片列表" content={content} extraContent={extraContent}>
title="卡片列表"
content={content}
extraContent={extraContent}
>
<div className={styles.cardList}> <div className={styles.cardList}>
<List <List
rowKey="id" rowKey="id"
loading={loading} loading={loading}
grid={{ gutter: 24, lg: 3, md: 2, sm: 1, xs: 1 }} grid={{ gutter: 24, lg: 3, md: 2, sm: 1, xs: 1 }}
dataSource={['', ...list]} dataSource={['', ...list]}
renderItem={item => (item ? ( renderItem={item =>
item ? (
<List.Item key={item.id}> <List.Item key={item.id}>
<Card hoverable className={styles.card} actions={[<a>操作一</a>, <a>操作二</a>]}> <Card hoverable className={styles.card} actions={[<a>操作一</a>, <a>操作二</a>]}>
<Card.Meta <Card.Meta
avatar={<img alt="" className={styles.cardAvatar} src={item.avatar} />} avatar={<img alt="" className={styles.cardAvatar} src={item.avatar} />}
title={<a href="#">{item.title}</a>} title={<a href="#">{item.title}</a>}
description={( description={
<Ellipsis className={styles.item} lines={3}>{item.description}</Ellipsis> <Ellipsis className={styles.item} lines={3}>
)} {item.description}
</Ellipsis>
}
/> />
</Card> </Card>
</List.Item> </List.Item>
...@@ -81,7 +86,7 @@ export default class CardList extends PureComponent { ...@@ -81,7 +86,7 @@ export default class CardList extends PureComponent {
</Button> </Button>
</List.Item> </List.Item>
) )
)} }
/> />
</div> </div>
</PageHeaderLayout> </PageHeaderLayout>
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
@import "../../utils/utils.less"; @import '../../utils/utils.less';
.cardList { .cardList {
margin-bottom: -24px; margin-bottom: -24px;
......
...@@ -7,7 +7,7 @@ import { getRoutes } from '../../utils/utils'; ...@@ -7,7 +7,7 @@ import { getRoutes } from '../../utils/utils';
@connect() @connect()
export default class SearchList extends Component { export default class SearchList extends Component {
handleTabChange = (key) => { handleTabChange = key => {
const { dispatch, match } = this.props; const { dispatch, match } = this.props;
switch (key) { switch (key) {
case 'articles': case 'articles':
...@@ -22,19 +22,23 @@ export default class SearchList extends Component { ...@@ -22,19 +22,23 @@ export default class SearchList extends Component {
default: default:
break; break;
} }
} };
render() { render() {
const tabList = [{ const tabList = [
{
key: 'articles', key: 'articles',
tab: '文章', tab: '文章',
}, { },
{
key: 'applications', key: 'applications',
tab: '应用', tab: '应用',
}, { },
{
key: 'projects', key: 'projects',
tab: '项目', tab: '项目',
}]; },
];
const mainSearch = ( const mainSearch = (
<div style={{ textAlign: 'center' }}> <div style={{ textAlign: 'center' }}>
...@@ -60,18 +64,9 @@ export default class SearchList extends Component { ...@@ -60,18 +64,9 @@ export default class SearchList extends Component {
onTabChange={this.handleTabChange} onTabChange={this.handleTabChange}
> >
<Switch> <Switch>
{ {routes.map(item => (
routes.map(item => <Route key={item.key} path={item.path} component={item.component} exact={item.exact} />
( ))}
<Route
key={item.key}
path={item.path}
component={item.component}
exact={item.exact}
/>
)
)
}
</Switch> </Switch>
</PageHeaderLayout> </PageHeaderLayout>
); );
......
...@@ -33,7 +33,7 @@ export default class CoverCardList extends PureComponent { ...@@ -33,7 +33,7 @@ export default class CoverCardList extends PureComponent {
const { form, dispatch } = this.props; const { form, dispatch } = this.props;
// setTimeout 用于保证获取表单值是在所有表单字段更新完毕的时候 // setTimeout 用于保证获取表单值是在所有表单字段更新完毕的时候
setTimeout(() => { setTimeout(() => {
form.validateFields((err) => { form.validateFields(err => {
if (!err) { if (!err) {
// eslint-disable-next-line // eslint-disable-next-line
dispatch({ dispatch({
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
@import "../../utils/utils.less"; @import '../../utils/utils.less';
.coverCardList { .coverCardList {
margin-bottom: -24px; margin-bottom: -24px;
......
import React, { PureComponent, Fragment } from 'react'; import React, { PureComponent, Fragment } from 'react';
import { connect } from 'dva'; import { connect } from 'dva';
import moment from 'moment'; import moment from 'moment';
import { Row, Col, Card, Form, Input, Select, Icon, Button, Dropdown, Menu, InputNumber, DatePicker, Modal, message, Badge, Divider } from 'antd'; import {
Row,
Col,
Card,
Form,
Input,
Select,
Icon,
Button,
Dropdown,
Menu,
InputNumber,
DatePicker,
Modal,
message,
Badge,
Divider,
} from 'antd';
import StandardTable from 'components/StandardTable'; import StandardTable from 'components/StandardTable';
import PageHeaderLayout from '../../layouts/PageHeaderLayout'; import PageHeaderLayout from '../../layouts/PageHeaderLayout';
...@@ -9,7 +26,10 @@ import styles from './TableList.less'; ...@@ -9,7 +26,10 @@ import styles from './TableList.less';
const FormItem = Form.Item; const FormItem = Form.Item;
const { Option } = Select; const { Option } = Select;
const getValue = obj => Object.keys(obj).map(key => obj[key]).join(','); const getValue = obj =>
Object.keys(obj)
.map(key => obj[key])
.join(',');
const statusMap = ['default', 'processing', 'success', 'error']; const statusMap = ['default', 'processing', 'success', 'error'];
const status = ['关闭', '运行中', '已上线', '异常']; const status = ['关闭', '运行中', '已上线', '异常'];
const columns = [ const columns = [
...@@ -73,7 +93,7 @@ const columns = [ ...@@ -73,7 +93,7 @@ const columns = [
}, },
]; ];
const CreateForm = Form.create()((props) => { const CreateForm = Form.create()(props => {
const { modalVisible, form, handleAdd, handleModalVisible } = props; const { modalVisible, form, handleAdd, handleModalVisible } = props;
const okHandle = () => { const okHandle = () => {
form.validateFields((err, fieldsValue) => { form.validateFields((err, fieldsValue) => {
...@@ -89,16 +109,10 @@ const CreateForm = Form.create()((props) => { ...@@ -89,16 +109,10 @@ const CreateForm = Form.create()((props) => {
onOk={okHandle} onOk={okHandle}
onCancel={() => handleModalVisible()} onCancel={() => handleModalVisible()}
> >
<FormItem <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="描述">
labelCol={{ span: 5 }}
wrapperCol={{ span: 15 }}
label="描述"
>
{form.getFieldDecorator('desc', { {form.getFieldDecorator('desc', {
rules: [{ required: true, message: 'Please input some description...' }], rules: [{ required: true, message: 'Please input some description...' }],
})( })(<Input placeholder="请输入" />)}
<Input placeholder="请输入" />
)}
</FormItem> </FormItem>
</Modal> </Modal>
); );
...@@ -148,7 +162,7 @@ export default class TableList extends PureComponent { ...@@ -148,7 +162,7 @@ export default class TableList extends PureComponent {
type: 'rule/fetch', type: 'rule/fetch',
payload: params, payload: params,
}); });
} };
handleFormReset = () => { handleFormReset = () => {
const { form, dispatch } = this.props; const { form, dispatch } = this.props;
...@@ -160,15 +174,15 @@ export default class TableList extends PureComponent { ...@@ -160,15 +174,15 @@ export default class TableList extends PureComponent {
type: 'rule/fetch', type: 'rule/fetch',
payload: {}, payload: {},
}); });
} };
toggleForm = () => { toggleForm = () => {
this.setState({ this.setState({
expandForm: !this.state.expandForm, expandForm: !this.state.expandForm,
}); });
} };
handleMenuClick = (e) => { handleMenuClick = e => {
const { dispatch } = this.props; const { dispatch } = this.props;
const { selectedRows } = this.state; const { selectedRows } = this.state;
...@@ -191,15 +205,15 @@ export default class TableList extends PureComponent { ...@@ -191,15 +205,15 @@ export default class TableList extends PureComponent {
default: default:
break; break;
} }
} };
handleSelectRows = (rows) => { handleSelectRows = rows => {
this.setState({ this.setState({
selectedRows: rows, selectedRows: rows,
}); });
} };
handleSearch = (e) => { handleSearch = e => {
e.preventDefault(); e.preventDefault();
const { dispatch, form } = this.props; const { dispatch, form } = this.props;
...@@ -221,15 +235,15 @@ export default class TableList extends PureComponent { ...@@ -221,15 +235,15 @@ export default class TableList extends PureComponent {
payload: values, payload: values,
}); });
}); });
} };
handleModalVisible = (flag) => { handleModalVisible = flag => {
this.setState({ this.setState({
modalVisible: !!flag, modalVisible: !!flag,
}); });
} };
handleAdd = (fields) => { handleAdd = fields => {
this.props.dispatch({ this.props.dispatch({
type: 'rule/add', type: 'rule/add',
payload: { payload: {
...@@ -241,7 +255,7 @@ export default class TableList extends PureComponent { ...@@ -241,7 +255,7 @@ export default class TableList extends PureComponent {
this.setState({ this.setState({
modalVisible: false, modalVisible: false,
}); });
} };
renderSimpleForm() { renderSimpleForm() {
const { getFieldDecorator } = this.props.form; const { getFieldDecorator } = this.props.form;
...@@ -250,9 +264,7 @@ export default class TableList extends PureComponent { ...@@ -250,9 +264,7 @@ export default class TableList extends PureComponent {
<Row gutter={{ md: 8, lg: 24, xl: 48 }}> <Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={8} sm={24}> <Col md={8} sm={24}>
<FormItem label="规则编号"> <FormItem label="规则编号">
{getFieldDecorator('no')( {getFieldDecorator('no')(<Input placeholder="请输入" />)}
<Input placeholder="请输入" />
)}
</FormItem> </FormItem>
</Col> </Col>
<Col md={8} sm={24}> <Col md={8} sm={24}>
...@@ -267,8 +279,12 @@ export default class TableList extends PureComponent { ...@@ -267,8 +279,12 @@ export default class TableList extends PureComponent {
</Col> </Col>
<Col md={8} sm={24}> <Col md={8} sm={24}>
<span className={styles.submitButtons}> <span className={styles.submitButtons}>
<Button type="primary" htmlType="submit">查询</Button> <Button type="primary" htmlType="submit">
<Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}>重置</Button> 查询
</Button>
<Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}>
重置
</Button>
<a style={{ marginLeft: 8 }} onClick={this.toggleForm}> <a style={{ marginLeft: 8 }} onClick={this.toggleForm}>
展开 <Icon type="down" /> 展开 <Icon type="down" />
</a> </a>
...@@ -286,9 +302,7 @@ export default class TableList extends PureComponent { ...@@ -286,9 +302,7 @@ export default class TableList extends PureComponent {
<Row gutter={{ md: 8, lg: 24, xl: 48 }}> <Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={8} sm={24}> <Col md={8} sm={24}>
<FormItem label="规则编号"> <FormItem label="规则编号">
{getFieldDecorator('no')( {getFieldDecorator('no')(<Input placeholder="请输入" />)}
<Input placeholder="请输入" />
)}
</FormItem> </FormItem>
</Col> </Col>
<Col md={8} sm={24}> <Col md={8} sm={24}>
...@@ -303,9 +317,7 @@ export default class TableList extends PureComponent { ...@@ -303,9 +317,7 @@ export default class TableList extends PureComponent {
</Col> </Col>
<Col md={8} sm={24}> <Col md={8} sm={24}>
<FormItem label="调用次数"> <FormItem label="调用次数">
{getFieldDecorator('number')( {getFieldDecorator('number')(<InputNumber style={{ width: '100%' }} />)}
<InputNumber style={{ width: '100%' }} />
)}
</FormItem> </FormItem>
</Col> </Col>
</Row> </Row>
...@@ -340,8 +352,12 @@ export default class TableList extends PureComponent { ...@@ -340,8 +352,12 @@ export default class TableList extends PureComponent {
</Row> </Row>
<div style={{ overflow: 'hidden' }}> <div style={{ overflow: 'hidden' }}>
<span style={{ float: 'right', marginBottom: 24 }}> <span style={{ float: 'right', marginBottom: 24 }}>
<Button type="primary" htmlType="submit">查询</Button> <Button type="primary" htmlType="submit">
<Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}>重置</Button> 查询
</Button>
<Button style={{ marginLeft: 8 }} onClick={this.handleFormReset}>
重置
</Button>
<a style={{ marginLeft: 8 }} onClick={this.toggleForm}> <a style={{ marginLeft: 8 }} onClick={this.toggleForm}>
收起 <Icon type="up" /> 收起 <Icon type="up" />
</a> </a>
...@@ -375,15 +391,12 @@ export default class TableList extends PureComponent { ...@@ -375,15 +391,12 @@ export default class TableList extends PureComponent {
<PageHeaderLayout title="查询表格"> <PageHeaderLayout title="查询表格">
<Card bordered={false}> <Card bordered={false}>
<div className={styles.tableList}> <div className={styles.tableList}>
<div className={styles.tableListForm}> <div className={styles.tableListForm}>{this.renderForm()}</div>
{this.renderForm()}
</div>
<div className={styles.tableListOperator}> <div className={styles.tableListOperator}>
<Button icon="plus" type="primary" onClick={() => this.handleModalVisible(true)}> <Button icon="plus" type="primary" onClick={() => this.handleModalVisible(true)}>
新建 新建
</Button> </Button>
{ {selectedRows.length > 0 && (
selectedRows.length > 0 && (
<span> <span>
<Button>批量操作</Button> <Button>批量操作</Button>
<Dropdown overlay={menu}> <Dropdown overlay={menu}>
...@@ -392,8 +405,7 @@ export default class TableList extends PureComponent { ...@@ -392,8 +405,7 @@ export default class TableList extends PureComponent {
</Button> </Button>
</Dropdown> </Dropdown>
</span> </span>
) )}
}
</div> </div>
<StandardTable <StandardTable
selectedRows={selectedRows} selectedRows={selectedRows}
...@@ -405,10 +417,7 @@ export default class TableList extends PureComponent { ...@@ -405,10 +417,7 @@ export default class TableList extends PureComponent {
/> />
</div> </div>
</Card> </Card>
<CreateForm <CreateForm {...parentMethods} modalVisible={modalVisible} />
{...parentMethods}
modalVisible={modalVisible}
/>
</PageHeaderLayout> </PageHeaderLayout>
); );
} }
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
@import "../../utils/utils.less"; @import '../../utils/utils.less';
.tableList { .tableList {
.tableListOperator { .tableListOperator {
......
...@@ -2,7 +2,21 @@ import React, { Component, Fragment } from 'react'; ...@@ -2,7 +2,21 @@ import React, { Component, Fragment } from 'react';
import Debounce from 'lodash-decorators/debounce'; import Debounce from 'lodash-decorators/debounce';
import Bind from 'lodash-decorators/bind'; import Bind from 'lodash-decorators/bind';
import { connect } from 'dva'; import { connect } from 'dva';
import { Button, Menu, Dropdown, Icon, Row, Col, Steps, Card, Popover, Badge, Table, Tooltip, Divider } from 'antd'; import {
Button,
Menu,
Dropdown,
Icon,
Row,
Col,
Steps,
Card,
Popover,
Badge,
Table,
Tooltip,
Divider,
} from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import DescriptionList from 'components/DescriptionList'; import DescriptionList from 'components/DescriptionList';
import PageHeaderLayout from '../../layouts/PageHeaderLayout'; import PageHeaderLayout from '../../layouts/PageHeaderLayout';
...@@ -12,7 +26,7 @@ const { Step } = Steps; ...@@ -12,7 +26,7 @@ const { Step } = Steps;
const { Description } = DescriptionList; const { Description } = DescriptionList;
const ButtonGroup = Button.Group; const ButtonGroup = Button.Group;
const getWindowWidth = () => (window.innerWidth || document.documentElement.clientWidth); const getWindowWidth = () => window.innerWidth || document.documentElement.clientWidth;
const menu = ( const menu = (
<Menu> <Menu>
...@@ -28,7 +42,9 @@ const action = ( ...@@ -28,7 +42,9 @@ const action = (
<Button>操作</Button> <Button>操作</Button>
<Button>操作</Button> <Button>操作</Button>
<Dropdown overlay={menu} placement="bottomRight"> <Dropdown overlay={menu} placement="bottomRight">
<Button><Icon type="ellipsis" /></Button> <Button>
<Icon type="ellipsis" />
</Button>
</Dropdown> </Dropdown>
</ButtonGroup> </ButtonGroup>
<Button type="primary">主操作</Button> <Button type="primary">主操作</Button>
...@@ -53,19 +69,24 @@ const description = ( ...@@ -53,19 +69,24 @@ const description = (
<Description term="创建人">曲丽丽</Description> <Description term="创建人">曲丽丽</Description>
<Description term="订购产品">XX 服务</Description> <Description term="订购产品">XX 服务</Description>
<Description term="创建时间">2017-07-07</Description> <Description term="创建时间">2017-07-07</Description>
<Description term="关联单据"><a href="">12421</a></Description> <Description term="关联单据">
<a href="">12421</a>
</Description>
<Description term="生效日期">2017-07-07 ~ 2017-08-08</Description> <Description term="生效日期">2017-07-07 ~ 2017-08-08</Description>
<Description term="备注">请于两个工作日内确认</Description> <Description term="备注">请于两个工作日内确认</Description>
</DescriptionList> </DescriptionList>
); );
const tabList = [{ const tabList = [
{
key: 'detail', key: 'detail',
tab: '详情', tab: '详情',
}, { },
{
key: 'rule', key: 'rule',
tab: '规则', tab: '规则',
}]; },
];
const desc1 = ( const desc1 = (
<div className={classNames(styles.textSecondary, styles.stepDescription)}> <div className={classNames(styles.textSecondary, styles.stepDescription)}>
...@@ -83,7 +104,9 @@ const desc2 = ( ...@@ -83,7 +104,9 @@ const desc2 = (
周毛毛 周毛毛
<Icon type="dingding-o" style={{ color: '#00A0E9', marginLeft: 8 }} /> <Icon type="dingding-o" style={{ color: '#00A0E9', marginLeft: 8 }} />
</Fragment> </Fragment>
<div><a href="">催一下</a></div> <div>
<a href="">催一下</a>
</div>
</div> </div>
); );
...@@ -93,51 +116,69 @@ const popoverContent = ( ...@@ -93,51 +116,69 @@ const popoverContent = (
<span className={styles.textSecondary} style={{ float: 'right' }}> <span className={styles.textSecondary} style={{ float: 'right' }}>
<Badge status="default" text={<span style={{ color: 'rgba(0, 0, 0, 0.45)' }}>未响应</span>} /> <Badge status="default" text={<span style={{ color: 'rgba(0, 0, 0, 0.45)' }}>未响应</span>} />
</span> </span>
<div className={styles.textSecondary} style={{ marginTop: 4 }}>耗时:2小时25分钟</div> <div className={styles.textSecondary} style={{ marginTop: 4 }}>
耗时:2小时25分钟
</div>
</div> </div>
); );
const customDot = (dot, { status }) => (status === 'process' ? ( const customDot = (dot, { status }) =>
status === 'process' ? (
<Popover placement="topLeft" arrowPointAtCenter content={popoverContent}> <Popover placement="topLeft" arrowPointAtCenter content={popoverContent}>
{dot} {dot}
</Popover> </Popover>
) : dot); ) : (
dot
);
const operationTabList = [{ const operationTabList = [
{
key: 'tab1', key: 'tab1',
tab: '操作日志一', tab: '操作日志一',
}, { },
{
key: 'tab2', key: 'tab2',
tab: '操作日志二', tab: '操作日志二',
}, { },
{
key: 'tab3', key: 'tab3',
tab: '操作日志三', tab: '操作日志三',
}]; },
];
const columns = [{ const columns = [
{
title: '操作类型', title: '操作类型',
dataIndex: 'type', dataIndex: 'type',
key: 'type', key: 'type',
}, { },
{
title: '操作人', title: '操作人',
dataIndex: 'name', dataIndex: 'name',
key: 'name', key: 'name',
}, { },
{
title: '执行结果', title: '执行结果',
dataIndex: 'status', dataIndex: 'status',
key: 'status', key: 'status',
render: text => ( render: text =>
text === 'agree' ? <Badge status="success" text="成功" /> : <Badge status="error" text="驳回" /> text === 'agree' ? (
<Badge status="success" text="成功" />
) : (
<Badge status="error" text="驳回" />
), ),
}, { },
{
title: '操作时间', title: '操作时间',
dataIndex: 'updatedAt', dataIndex: 'updatedAt',
key: 'updatedAt', key: 'updatedAt',
}, { },
{
title: '备注', title: '备注',
dataIndex: 'memo', dataIndex: 'memo',
key: 'memo', key: 'memo',
}]; },
];
@connect(({ profile, loading }) => ({ @connect(({ profile, loading }) => ({
profile, profile,
...@@ -147,7 +188,7 @@ export default class AdvancedProfile extends Component { ...@@ -147,7 +188,7 @@ export default class AdvancedProfile extends Component {
state = { state = {
operationkey: 'tab1', operationkey: 'tab1',
stepDirection: 'horizontal', stepDirection: 'horizontal',
} };
componentDidMount() { componentDidMount() {
const { dispatch } = this.props; const { dispatch } = this.props;
...@@ -164,9 +205,9 @@ export default class AdvancedProfile extends Component { ...@@ -164,9 +205,9 @@ export default class AdvancedProfile extends Component {
this.setStepDirection.cancel(); this.setStepDirection.cancel();
} }
onOperationTabChange = (key) => { onOperationTabChange = key => {
this.setState({ operationkey: key }); this.setState({ operationkey: key });
} };
@Bind() @Bind()
@Debounce(200) @Debounce(200)
...@@ -189,30 +230,38 @@ export default class AdvancedProfile extends Component { ...@@ -189,30 +230,38 @@ export default class AdvancedProfile extends Component {
const { profile, loading } = this.props; const { profile, loading } = this.props;
const { advancedOperation1, advancedOperation2, advancedOperation3 } = profile; const { advancedOperation1, advancedOperation2, advancedOperation3 } = profile;
const contentList = { const contentList = {
tab1: <Table tab1: (
<Table
pagination={false} pagination={false}
loading={loading} loading={loading}
dataSource={advancedOperation1} dataSource={advancedOperation1}
columns={columns} columns={columns}
/>, />
tab2: <Table ),
tab2: (
<Table
pagination={false} pagination={false}
loading={loading} loading={loading}
dataSource={advancedOperation2} dataSource={advancedOperation2}
columns={columns} columns={columns}
/>, />
tab3: <Table ),
tab3: (
<Table
pagination={false} pagination={false}
loading={loading} loading={loading}
dataSource={advancedOperation3} dataSource={advancedOperation3}
columns={columns} columns={columns}
/>, />
),
}; };
return ( return (
<PageHeaderLayout <PageHeaderLayout
title="单号:234231029431" title="单号:234231029431"
logo={<img alt="" src="https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png" />} logo={
<img alt="" src="https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png" />
}
action={action} action={action}
content={description} content={description}
extraContent={extra} extraContent={extra}
...@@ -232,17 +281,23 @@ export default class AdvancedProfile extends Component { ...@@ -232,17 +281,23 @@ export default class AdvancedProfile extends Component {
<Description term="会员卡号">32943898021309809423</Description> <Description term="会员卡号">32943898021309809423</Description>
<Description term="身份证">3321944288191034921</Description> <Description term="身份证">3321944288191034921</Description>
<Description term="联系方式">18112345678</Description> <Description term="联系方式">18112345678</Description>
<Description term="联系地址">曲丽丽 18100000000 浙江省杭州市西湖区黄姑山路工专路交叉路口</Description> <Description term="联系地址">
曲丽丽 18100000000 浙江省杭州市西湖区黄姑山路工专路交叉路口
</Description>
</DescriptionList> </DescriptionList>
<DescriptionList style={{ marginBottom: 24 }} title="信息组"> <DescriptionList style={{ marginBottom: 24 }} title="信息组">
<Description term="某某数据">725</Description> <Description term="某某数据">725</Description>
<Description term="该数据更新时间">2017-08-08</Description> <Description term="该数据更新时间">2017-08-08</Description>
<Description>&nbsp;</Description> <Description>&nbsp;</Description>
<Description term={ <Description
term={
<span> <span>
某某数据 某某数据
<Tooltip title="数据说明"> <Tooltip title="数据说明">
<Icon style={{ color: 'rgba(0, 0, 0, 0.43)', marginLeft: 4 }} type="info-circle-o" /> <Icon
style={{ color: 'rgba(0, 0, 0, 0.43)', marginLeft: 4 }}
type="info-circle-o"
/>
</Tooltip> </Tooltip>
</span> </span>
} }
...@@ -258,12 +313,15 @@ export default class AdvancedProfile extends Component { ...@@ -258,12 +313,15 @@ export default class AdvancedProfile extends Component {
<Description term="角色码">1234567</Description> <Description term="角色码">1234567</Description>
<Description term="所属部门">XX公司 - YY部</Description> <Description term="所属部门">XX公司 - YY部</Description>
<Description term="过期时间">2017-08-08</Description> <Description term="过期时间">2017-08-08</Description>
<Description term="描述">这段描述很长很长很长很长很长很长很长很长很长很长很长很长很长很长...</Description> <Description term="描述">
这段描述很长很长很长很长很长很长很长很长很长很长很长很长很长很长...
</Description>
</DescriptionList> </DescriptionList>
<Divider style={{ margin: '16px 0' }} /> <Divider style={{ margin: '16px 0' }} />
<DescriptionList size="small" style={{ marginBottom: 16 }} title="组名称" col="1"> <DescriptionList size="small" style={{ marginBottom: 16 }} title="组名称" col="1">
<Description term="学名"> <Description term="学名">
Citrullus lanatus (Thunb.) Matsum. et Nakai一年生蔓生藤本;茎、枝粗壮,具明显的棱。卷须较粗.. Citrullus lanatus (Thunb.) Matsum. et
Nakai一年生蔓生藤本;茎、枝粗壮,具明显的棱。卷须较粗..
</Description> </Description>
</DescriptionList> </DescriptionList>
<Divider style={{ margin: '16px 0' }} /> <Divider style={{ margin: '16px 0' }} />
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.headerList { .headerList {
margin-bottom: 4px; margin-bottom: 4px;
......
...@@ -23,11 +23,11 @@ const progressColumns = [ ...@@ -23,11 +23,11 @@ const progressColumns = [
dataIndex: 'status', dataIndex: 'status',
key: 'status', key: 'status',
render: text => render: text =>
(text === 'success' ? ( text === 'success' ? (
<Badge status="success" text="成功" /> <Badge status="success" text="成功" />
) : ( ) : (
<Badge status="processing" text="进行中" /> <Badge status="processing" text="进行中" />
)), ),
}, },
{ {
title: '操作员ID', title: '操作员ID',
...@@ -60,7 +60,7 @@ export default class BasicProfile extends Component { ...@@ -60,7 +60,7 @@ export default class BasicProfile extends Component {
if (basicGoods.length) { if (basicGoods.length) {
let num = 0; let num = 0;
let amount = 0; let amount = 0;
basicGoods.forEach((item) => { basicGoods.forEach(item => {
num += Number(item.num); num += Number(item.num);
amount += Number(item.amount); amount += Number(item.amount);
}); });
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.title { .title {
color: @heading-color; color: @heading-color;
......
...@@ -5,16 +5,27 @@ import PageHeaderLayout from '../../layouts/PageHeaderLayout'; ...@@ -5,16 +5,27 @@ import PageHeaderLayout from '../../layouts/PageHeaderLayout';
const extra = ( const extra = (
<Fragment> <Fragment>
<div style={{ fontSize: 16, color: 'rgba(0, 0, 0, 0.85)', fontWeight: '500', marginBottom: 16 }}> <div
style={{
fontSize: 16,
color: 'rgba(0, 0, 0, 0.85)',
fontWeight: '500',
marginBottom: 16,
}}
>
您提交的内容有如下错误: 您提交的内容有如下错误:
</div> </div>
<div style={{ marginBottom: 16 }}> <div style={{ marginBottom: 16 }}>
<Icon style={{ color: '#f5222d', marginRight: 8 }} type="close-circle-o" />您的账户已被冻结 <Icon style={{ color: '#f5222d', marginRight: 8 }} type="close-circle-o" />您的账户已被冻结
<a style={{ marginLeft: 16 }}>立即解冻 <Icon type="right" /></a> <a style={{ marginLeft: 16 }}>
立即解冻 <Icon type="right" />
</a>
</div> </div>
<div> <div>
<Icon style={{ color: '#f5222d', marginRight: 8 }} type="close-circle-o" />您的账户还不具备申请资格 <Icon style={{ color: '#f5222d', marginRight: 8 }} type="close-circle-o" />您的账户还不具备申请资格
<a style={{ marginLeft: 16 }}>立即升级 <Icon type="right" /></a> <a style={{ marginLeft: 16 }}>
立即升级 <Icon type="right" />
</a>
</div> </div>
</Fragment> </Fragment>
); );
......
...@@ -6,7 +6,14 @@ import PageHeaderLayout from '../../layouts/PageHeaderLayout'; ...@@ -6,7 +6,14 @@ import PageHeaderLayout from '../../layouts/PageHeaderLayout';
const { Step } = Steps; const { Step } = Steps;
const desc1 = ( const desc1 = (
<div style={{ fontSize: 12, color: 'rgba(0, 0, 0, 0.45)', position: 'relative', left: 42 }}> <div
style={{
fontSize: 12,
color: 'rgba(0, 0, 0, 0.45)',
position: 'relative',
left: 42,
}}
>
<div style={{ margin: '8px 0 4px' }}> <div style={{ margin: '8px 0 4px' }}>
曲丽丽<Icon style={{ marginLeft: 8 }} type="dingding-o" /> 曲丽丽<Icon style={{ marginLeft: 8 }} type="dingding-o" />
</div> </div>
...@@ -19,13 +26,22 @@ const desc2 = ( ...@@ -19,13 +26,22 @@ const desc2 = (
<div style={{ margin: '8px 0 4px' }}> <div style={{ margin: '8px 0 4px' }}>
周毛毛<Icon type="dingding-o" style={{ color: '#00A0E9', marginLeft: 8 }} /> 周毛毛<Icon type="dingding-o" style={{ color: '#00A0E9', marginLeft: 8 }} />
</div> </div>
<div><a href="">催一下</a></div> <div>
<a href="">催一下</a>
</div>
</div> </div>
); );
const extra = ( const extra = (
<Fragment> <Fragment>
<div style={{ fontSize: 16, color: 'rgba(0, 0, 0, 0.85)', fontWeight: '500', marginBottom: 20 }}> <div
style={{
fontSize: 16,
color: 'rgba(0, 0, 0, 0.85)',
fontWeight: '500',
marginBottom: 20,
}}
>
项目名称 项目名称
</div> </div>
<Row style={{ marginBottom: 16 }}> <Row style={{ marginBottom: 16 }}>
......
...@@ -15,11 +15,11 @@ export default class LoginPage extends Component { ...@@ -15,11 +15,11 @@ export default class LoginPage extends Component {
state = { state = {
type: 'account', type: 'account',
autoLogin: true, autoLogin: true,
} };
onTabChange = (type) => { onTabChange = type => {
this.setState({ type }); this.setState({ type });
} };
handleSubmit = (err, values) => { handleSubmit = (err, values) => {
const { type } = this.state; const { type } = this.state;
...@@ -32,53 +32,47 @@ export default class LoginPage extends Component { ...@@ -32,53 +32,47 @@ export default class LoginPage extends Component {
}, },
}); });
} }
} };
changeAutoLogin = (e) => { changeAutoLogin = e => {
this.setState({ this.setState({
autoLogin: e.target.checked, autoLogin: e.target.checked,
}); });
} };
renderMessage = (content) => { renderMessage = content => {
return ( return <Alert style={{ marginBottom: 24 }} message={content} type="error" showIcon />;
<Alert style={{ marginBottom: 24 }} message={content} type="error" showIcon /> };
);
}
render() { render() {
const { login, submitting } = this.props; const { login, submitting } = this.props;
const { type } = this.state; const { type } = this.state;
return ( return (
<div className={styles.main}> <div className={styles.main}>
<Login <Login defaultActiveKey={type} onTabChange={this.onTabChange} onSubmit={this.handleSubmit}>
defaultActiveKey={type}
onTabChange={this.onTabChange}
onSubmit={this.handleSubmit}
>
<Tab key="account" tab="账户密码登录"> <Tab key="account" tab="账户密码登录">
{ {login.status === 'error' &&
login.status === 'error' &&
login.type === 'account' && login.type === 'account' &&
!login.submitting && !login.submitting &&
this.renderMessage('账户或密码错误(admin/888888)') this.renderMessage('账户或密码错误(admin/888888)')}
}
<UserName name="userName" placeholder="admin/user" /> <UserName name="userName" placeholder="admin/user" />
<Password name="password" placeholder="888888/123456" /> <Password name="password" placeholder="888888/123456" />
</Tab> </Tab>
<Tab key="mobile" tab="手机号登录"> <Tab key="mobile" tab="手机号登录">
{ {login.status === 'error' &&
login.status === 'error' &&
login.type === 'mobile' && login.type === 'mobile' &&
!login.submitting && !login.submitting &&
this.renderMessage('验证码错误') this.renderMessage('验证码错误')}
}
<Mobile name="mobile" /> <Mobile name="mobile" />
<Captcha name="captcha" /> <Captcha name="captcha" />
</Tab> </Tab>
<div> <div>
<Checkbox checked={this.state.autoLogin} onChange={this.changeAutoLogin}>自动登录</Checkbox> <Checkbox checked={this.state.autoLogin} onChange={this.changeAutoLogin}>
<a style={{ float: 'right' }} href="">忘记密码</a> 自动登录
</Checkbox>
<a style={{ float: 'right' }} href="">
忘记密码
</a>
</div> </div>
<Submit loading={submitting}>登录</Submit> <Submit loading={submitting}>登录</Submit>
<div className={styles.other}> <div className={styles.other}>
...@@ -86,7 +80,9 @@ export default class LoginPage extends Component { ...@@ -86,7 +80,9 @@ export default class LoginPage extends Component {
<Icon className={styles.icon} type="alipay-circle" /> <Icon className={styles.icon} type="alipay-circle" />
<Icon className={styles.icon} type="taobao-circle" /> <Icon className={styles.icon} type="taobao-circle" />
<Icon className={styles.icon} type="weibo-circle" /> <Icon className={styles.icon} type="weibo-circle" />
<Link className={styles.register} to="/user/register">注册账户</Link> <Link className={styles.register} to="/user/register">
注册账户
</Link>
</div> </div>
</Login> </Login>
</div> </div>
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.main { .main {
width: 368px; width: 368px;
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
margin-left: 16px; margin-left: 16px;
vertical-align: middle; vertical-align: middle;
cursor: pointer; cursor: pointer;
transition: color .3s; transition: color 0.3s;
&:hover { &:hover {
color: @primary-color; color: @primary-color;
......
...@@ -37,12 +37,14 @@ export default class Register extends Component { ...@@ -37,12 +37,14 @@ export default class Register extends Component {
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
const account = this.props.form.getFieldValue('mail'); const account = this.props.form.getFieldValue('mail');
if (nextProps.register.status === 'ok') { if (nextProps.register.status === 'ok') {
this.props.dispatch(routerRedux.push({ this.props.dispatch(
routerRedux.push({
pathname: '/user/register-result', pathname: '/user/register-result',
state: { state: {
account, account,
}, },
})); })
);
} }
} }
...@@ -74,7 +76,7 @@ export default class Register extends Component { ...@@ -74,7 +76,7 @@ export default class Register extends Component {
return 'poor'; return 'poor';
}; };
handleSubmit = (e) => { handleSubmit = e => {
e.preventDefault(); e.preventDefault();
this.props.form.validateFields({ force: true }, (err, values) => { this.props.form.validateFields({ force: true }, (err, values) => {
if (!err) { if (!err) {
...@@ -89,7 +91,7 @@ export default class Register extends Component { ...@@ -89,7 +91,7 @@ export default class Register extends Component {
}); });
}; };
handleConfirmBlur = (e) => { handleConfirmBlur = e => {
const { value } = e.target; const { value } = e.target;
this.setState({ confirmDirty: this.state.confirmDirty || !!value }); this.setState({ confirmDirty: this.state.confirmDirty || !!value });
}; };
...@@ -131,7 +133,7 @@ export default class Register extends Component { ...@@ -131,7 +133,7 @@ export default class Register extends Component {
} }
}; };
changePrefix = (value) => { changePrefix = value => {
this.setState({ this.setState({
prefix: value, prefix: value,
}); });
...@@ -197,13 +199,7 @@ export default class Register extends Component { ...@@ -197,13 +199,7 @@ export default class Register extends Component {
validator: this.checkPassword, validator: this.checkPassword,
}, },
], ],
})( })(<Input size="large" type="password" placeholder="至少6位密码,区分大小写" />)}
<Input
size="large"
type="password"
placeholder="至少6位密码,区分大小写"
/>
)}
</Popover> </Popover>
</FormItem> </FormItem>
<FormItem> <FormItem>
...@@ -241,13 +237,7 @@ export default class Register extends Component { ...@@ -241,13 +237,7 @@ export default class Register extends Component {
message: '手机号格式错误!', message: '手机号格式错误!',
}, },
], ],
})( })(<Input size="large" style={{ width: '80%' }} placeholder="11位手机号" />)}
<Input
size="large"
style={{ width: '80%' }}
placeholder="11位手机号"
/>
)}
</InputGroup> </InputGroup>
</FormItem> </FormItem>
<FormItem> <FormItem>
......
@import "~antd/lib/style/themes/default.less"; @import '~antd/lib/style/themes/default.less';
.main { .main {
width: 368px; width: 368px;
......
...@@ -6,8 +6,14 @@ import styles from './RegisterResult.less'; ...@@ -6,8 +6,14 @@ import styles from './RegisterResult.less';
const actions = ( const actions = (
<div className={styles.actions}> <div className={styles.actions}>
<a href=""><Button size="large" type="primary">查看邮箱</Button></a> <a href="">
<Link to="/"><Button size="large">返回首页</Button></Link> <Button size="large" type="primary">
查看邮箱
</Button>
</a>
<Link to="/">
<Button size="large">返回首页</Button>
</Link>
</div> </div>
); );
......
...@@ -67,13 +67,13 @@ export default function request(url, options) { ...@@ -67,13 +67,13 @@ export default function request(url, options) {
return fetch(url, newOptions) return fetch(url, newOptions)
.then(checkStatus) .then(checkStatus)
.then((response) => { .then(response => {
if (newOptions.method === 'DELETE' || response.status === 204) { if (newOptions.method === 'DELETE' || response.status === 204) {
return response.text(); return response.text();
} }
return response.json(); return response.json();
}) })
.catch((e) => { .catch(e => {
const { dispatch } = store; const { dispatch } = store;
const status = e.name; const status = e.name;
if (status === 401) { if (status === 401) {
......
...@@ -27,9 +27,9 @@ export function getTimeDistance(type) { ...@@ -27,9 +27,9 @@ export function getTimeDistance(type) {
day -= 1; day -= 1;
} }
const beginTime = now.getTime() - (day * oneDay); const beginTime = now.getTime() - day * oneDay;
return [moment(beginTime), moment(beginTime + ((7 * oneDay) - 1000))]; return [moment(beginTime), moment(beginTime + (7 * oneDay - 1000))];
} }
if (type === 'month') { if (type === 'month') {
...@@ -39,7 +39,10 @@ export function getTimeDistance(type) { ...@@ -39,7 +39,10 @@ export function getTimeDistance(type) {
const nextYear = nextDate.year(); const nextYear = nextDate.year();
const nextMonth = nextDate.month(); const nextMonth = nextDate.month();
return [moment(`${year}-${fixedZero(month + 1)}-01 00:00:00`), moment(moment(`${nextYear}-${fixedZero(nextMonth + 1)}-01 00:00:00`).valueOf() - 1000)]; return [
moment(`${year}-${fixedZero(month + 1)}-01 00:00:00`),
moment(moment(`${nextYear}-${fixedZero(nextMonth + 1)}-01 00:00:00`).valueOf() - 1000),
];
} }
if (type === 'year') { if (type === 'year') {
...@@ -51,7 +54,7 @@ export function getTimeDistance(type) { ...@@ -51,7 +54,7 @@ export function getTimeDistance(type) {
export function getPlainNode(nodeList, parentPath = '') { export function getPlainNode(nodeList, parentPath = '') {
const arr = []; const arr = [];
nodeList.forEach((node) => { nodeList.forEach(node => {
const item = node; const item = node;
item.path = `${parentPath}/${item.path || ''}`.replace(/\/+/g, '/'); item.path = `${parentPath}/${item.path || ''}`.replace(/\/+/g, '/');
item.exact = true; item.exact = true;
...@@ -70,14 +73,11 @@ export function getPlainNode(nodeList, parentPath = '') { ...@@ -70,14 +73,11 @@ export function getPlainNode(nodeList, parentPath = '') {
export function digitUppercase(n) { export function digitUppercase(n) {
const fraction = ['角', '分']; const fraction = ['角', '分'];
const digit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']; const digit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
const unit = [ const unit = [['元', '万', '亿'], ['', '拾', '佰', '仟']];
['元', '万', '亿'],
['', '拾', '佰', '仟'],
];
let num = Math.abs(n); let num = Math.abs(n);
let s = ''; let s = '';
fraction.forEach((item, index) => { fraction.forEach((item, index) => {
s += (digit[Math.floor(num * 10 * (10 ** index)) % 10] + item).replace(/零./, ''); s += (digit[Math.floor(num * 10 * 10 ** index) % 10] + item).replace(/零./, '');
}); });
s = s || '整'; s = s || '整';
num = Math.floor(num); num = Math.floor(num);
...@@ -90,10 +90,12 @@ export function digitUppercase(n) { ...@@ -90,10 +90,12 @@ export function digitUppercase(n) {
s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s; s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;
} }
return s.replace(/(零.)*零元/, '元').replace(/(零.)+/g, '零').replace(/^整$/, '零元整'); return s
.replace(/(零.)*零元/, '元')
.replace(/(零.)+/g, '零')
.replace(/^整$/, '零元整');
} }
function getRelation(str1, str2) { function getRelation(str1, str2) {
if (str1 === str2) { if (str1 === str2) {
console.warn('Two path are equal!'); // eslint-disable-line console.warn('Two path are equal!'); // eslint-disable-line
...@@ -131,14 +133,15 @@ function getRenderArr(routes) { ...@@ -131,14 +133,15 @@ function getRenderArr(routes) {
* @param {routerData} routerData * @param {routerData} routerData
*/ */
export function getRoutes(path, routerData) { export function getRoutes(path, routerData) {
let routes = Object.keys(routerData).filter(routePath => let routes = Object.keys(routerData).filter(
routePath.indexOf(path) === 0 && routePath !== path); routePath => routePath.indexOf(path) === 0 && routePath !== path
);
// Replace path to '' eg. path='user' /user/name => name // Replace path to '' eg. path='user' /user/name => name
routes = routes.map(item => item.replace(path, '')); routes = routes.map(item => item.replace(path, ''));
// Get the route to be rendered to remove the deep rendering // Get the route to be rendered to remove the deep rendering
const renderArr = getRenderArr(routes); const renderArr = getRenderArr(routes);
// Conversion and stitching parameters // Conversion and stitching parameters
const renderRoutes = renderArr.map((item) => { const renderRoutes = renderArr.map(item => {
const exact = !routes.some(route => route !== item && getRelation(route, item) === 1); const exact = !routes.some(route => route !== item && getRelation(route, item) === 1);
return { return {
exact, exact,
...@@ -150,7 +153,6 @@ export function getRoutes(path, routerData) { ...@@ -150,7 +153,6 @@ export function getRoutes(path, routerData) {
return renderRoutes; return renderRoutes;
} }
/* eslint no-useless-escape:0 */ /* eslint no-useless-escape:0 */
const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/g; const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/g;
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
zoom: 1; zoom: 1;
&:before, &:before,
&:after { &:after {
content: " "; content: ' ';
display: table; display: table;
} }
&:after { &:after {
......
...@@ -7,7 +7,7 @@ const startServer = spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['s ...@@ -7,7 +7,7 @@ const startServer = spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['s
env, env,
}); });
startServer.stderr.on('data', (data) => { startServer.stderr.on('data', data => {
// eslint-disable-next-line // eslint-disable-next-line
console.log(data); console.log(data);
}); });
...@@ -18,11 +18,13 @@ startServer.on('exit', () => { ...@@ -18,11 +18,13 @@ startServer.on('exit', () => {
// eslint-disable-next-line // eslint-disable-next-line
console.log('Starting development server for e2e tests...'); console.log('Starting development server for e2e tests...');
startServer.stdout.on('data', (data) => { startServer.stdout.on('data', data => {
// eslint-disable-next-line // eslint-disable-next-line
console.log(data.toString()); console.log(data.toString());
if (data.toString().indexOf('Compiled successfully') >= 0 || if (
data.toString().indexOf('Compiled with warnings') >= 0) { data.toString().indexOf('Compiled successfully') >= 0 ||
data.toString().indexOf('Compiled with warnings') >= 0
) {
// eslint-disable-next-line // eslint-disable-next-line
console.log('Development server is started, ready to run tests.'); console.log('Development server is started, ready to run tests.');
const testCmd = spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['test'], { const testCmd = spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['test'], {
......
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