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,15 +19,18 @@ ...@@ -20,15 +19,18 @@
"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": [
"declaration": "parens-new-line", "error",
"assignment": "parens-new-line", {
"return": "parens-new-line", "declaration": "parens-new-line",
"arrow": "parens-new-line", "assignment": "parens-new-line",
"condition": "parens-new-line", "return": "parens-new-line",
"logical": "parens-new-line", "arrow": "parens-new-line",
"prop": "ignore" "condition": "parens-new-line",
}], "logical": "parens-new-line",
"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": [
"arrays": "always-multiline", "error",
"objects": "always-multiline", {
"imports": "always-multiline", "arrays": "always-multiline",
"exports": "always-multiline", "objects": "always-multiline",
"functions": "ignore" "imports": "always-multiline",
}], "exports": "always-multiline",
"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', {
name: 'John Brown', key: '1',
age: 32, name: 'John Brown',
address: 'New York No. 1 Lake Park', age: 32,
}, { address: 'New York No. 1 Lake Park',
key: '2', },
name: 'Jim Green', {
age: 42, key: '2',
address: 'London No. 1 Lake Park', name: 'Jim Green',
}, { age: 42,
key: '3', address: 'London No. 1 Lake Park',
name: 'Joe Black', },
age: 32, {
address: 'Sidney No. 1 Lake Park', key: '3',
}], name: 'Joe Black',
age: 32,
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', {
icon: 'dashboard', name: 'dashboard',
path: 'dashboard', icon: 'dashboard',
children: [{ path: 'dashboard',
name: '分析页', children: [
path: 'analysis', {
}, { name: '分析页',
name: '监控页', path: 'analysis',
path: 'monitor', },
}, { {
name: '工作台', name: '监控页',
path: 'workplace', path: 'monitor',
// hideInBreadcrumb: true, },
// hideInMenu: true, {
}], name: '工作台',
}, { path: 'workplace',
name: '表单页', // hideInBreadcrumb: true,
icon: 'form', // hideInMenu: true,
path: 'form', },
children: [{ ],
name: '基础表单', },
path: 'basic-form', {
}, { name: '表单页',
name: '分步表单', icon: 'form',
path: 'step-form', path: 'form',
}, { children: [
name: '高级表单', {
authority: 'admin', name: '基础表单',
path: 'advanced-form', path: 'basic-form',
}], },
}, { {
name: '列表页', name: '分步表单',
icon: 'table', path: 'step-form',
path: 'list', },
children: [{ {
name: '查询表格', name: '高级表单',
path: 'table-list', authority: 'admin',
}, { path: 'advanced-form',
name: '标准列表', },
path: 'basic-list', ],
}, { },
name: '卡片列表', {
path: 'card-list', name: '列表页',
}, { icon: 'table',
name: '搜索列表', path: 'list',
path: 'search', children: [
children: [{ {
name: '搜索列表(文章)', name: '查询表格',
path: 'articles', path: 'table-list',
}, { },
name: '搜索列表(项目)', {
path: 'projects', name: '标准列表',
}, { path: 'basic-list',
name: '搜索列表(应用)', },
path: 'applications', {
}], name: '卡片列表',
}], path: 'card-list',
}, { },
name: '详情页', {
icon: 'profile', name: '搜索列表',
path: 'profile', path: 'search',
children: [{ children: [
name: '基础详情页', {
path: 'basic', name: '搜索列表(文章)',
}, { path: 'articles',
name: '高级详情页', },
path: 'advanced', {
authority: 'admin', name: '搜索列表(项目)',
}], path: 'projects',
}, { },
name: '结果页', {
icon: 'check-circle-o', name: '搜索列表(应用)',
path: 'result', path: 'applications',
children: [{ },
name: '成功', ],
path: 'success', },
}, { ],
name: '失败', },
path: 'fail', {
}], name: '详情页',
}, { icon: 'profile',
name: '异常页', path: 'profile',
icon: 'warning', children: [
path: 'exception', {
children: [{ name: '基础详情页',
name: '403', path: 'basic',
path: '403', },
}, { {
name: '404', name: '高级详情页',
path: '404', path: 'advanced',
}, { authority: 'admin',
name: '500', },
path: '500', ],
}, { },
name: '触发异常', {
path: 'trigger', name: '结果页',
hideInMenu: true, icon: 'check-circle-o',
}], path: 'result',
}, { children: [
name: '账户', {
icon: 'user', name: '成功',
path: 'user', path: 'success',
authority: 'guest', },
children: [{ {
name: '登录', name: '失败',
path: 'login', path: 'fail',
}, { },
name: '注册', ],
path: 'register', },
}, { {
name: '注册结果', name: '异常页',
path: 'register-result', icon: 'warning',
}], path: 'exception',
}]; children: [
{
name: '403',
path: '403',
},
{
name: '404',
path: '404',
},
{
name: '500',
path: '500',
},
{
name: '触发异常',
path: 'trigger',
hideInMenu: true,
},
],
},
{
name: '账户',
icon: 'user',
path: 'user',
authority: 'guest',
children: [
{
name: '登录',
path: 'login',
},
{
name: '注册',
path: 'register',
},
{
name: '注册结果',
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,20 +35,20 @@ const dynamicWrapper = (app, models, component) => { ...@@ -36,20 +35,20 @@ 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 =>
...props, createElement(Component, {
routerData: routerDataCache, ...props,
}); 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"
...@@ -178,7 +171,7 @@ export default class Radar extends Component { ...@@ -178,7 +171,7 @@ export default class Radar extends Component {
<h6>{item.value}</h6> <h6>{item.value}</h6>
</div> </div>
</Col> </Col>
))} ))}
</Row> </Row>
)} )}
</div> </div>
......
@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) { },
onEnd(); () => {
if (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 value={value} onChange={this.handleChange} onPressEnter={this.check} />
<Input <Icon type="check" className={styles.icon} onClick={this.check} />
value={value} </div>
onChange={this.handleChange} ) : (
onPressEnter={this.check} <div className={styles.wrapper}>
/> <span>{value || ' '}</span>
<Icon <Icon type="edit" className={styles.icon} onClick={this.edit} />
type="check" </div>
className={styles.icon} )}
onClick={this.check}
/>
</div>
) : (
<div className={styles.wrapper}>
<span>{value || ' '}</span>
<Icon
type="edit"
className={styles.icon}
onClick={this.edit}
/>
</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 =>
links.map(link => ( createElement(
createElement(linkElement, { 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 ||
actions || createElement(
createElement(linkElement, { 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 key={link.key} target={link.blankTarget ? '_blank' : '_self'} href={link.href}>
<a {link.title}
key={link.key} </a>
target={link.blankTarget ? '_blank' : '_self'} ))}
href={link.href} </div>
> )}
{link.title}
</a>
))}
</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">
( <img src={logo} alt="logo" width="32" />
<Link to="/" className={styles.logo} key="logo"> </Link>,
<img src={logo} alt="logo" width="32" /> <Divider type="vertical" key="line" />,
</Link> ]}
),
<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,21 +92,21 @@ class Login extends Component { ...@@ -94,21 +92,21 @@ 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} className={styles.tabs}
className={styles.tabs} activeKey={type}
activeKey={type} onChange={this.onSwitch}
onChange={this.onSwitch} >
> {TabChildren}
{TabChildren} </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);
// 当无子菜单时就不展示菜单 // 当无子菜单时就不展示菜单
...@@ -125,8 +125,8 @@ export default class SiderMenu extends PureComponent { ...@@ -125,8 +125,8 @@ export default class SiderMenu extends PureComponent {
<span>{item.name}</span> <span>{item.name}</span>
</span> </span>
) : ( ) : (
item.name item.name
) )
} }
key={item.path} key={item.path}
> >
...@@ -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({
...@@ -202,8 +195,8 @@ export default class SiderMenu extends PureComponent { ...@@ -202,8 +195,8 @@ export default class SiderMenu extends PureComponent {
const menuProps = collapsed const menuProps = collapsed
? {} ? {}
: { : {
openKeys, openKeys,
}; };
// if pathname can't match, use the nearest parent's key // if pathname can't match, use the nearest parent's key
let selectedKeys = this.getSelectedMenuKeys(); let selectedKeys = this.getSelectedMenuKeys();
if (!selectedKeys.length) { if (!selectedKeys.length) {
......
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 && (
{ <a className={styles.trigger} onClick={this.handleExpand}>
expandable && ( {expand ? '收起' : '展开'} <Icon type={expand ? 'up' : 'down'} />
<a className={styles.trigger} onClick={this.handleExpand}> </a>
{expand ? '收起' : '展开'} <Icon type={expand ? 'up' : 'down'} /> )}
</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 {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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