From 0e2cd76a412dca535c1d037fa7fa6d7a001d25b8 Mon Sep 17 00:00:00 2001 From: jim Date: Fri, 18 May 2018 22:20:24 +0800 Subject: [PATCH] fix default setting bug --- .babelrc.js | 2 +- .gitignore | 1 + .prettierignore | 1 + package.json | 12 +-- src/components/Charts/index.js | 2 +- .../DescriptionList/DescriptionList.js | 5 +- src/components/Login/index.d.ts | 1 + src/components/Login/index.less | 1 + src/components/PageHeader/index.js | 8 +- src/components/Result/index.less | 7 ++ src/components/Sidebar/index.js | 2 +- src/components/SiderMenu/BaseMenu.js | 17 +++- src/components/SiderMenu/SiderMenu.js | 79 +++++++++++++++++++ src/components/SiderMenu/SilderMenu.test.js | 72 +++++++++++++++++ src/e2e/home.e2e.js | 2 +- src/e2e/login.e2e.js | 2 +- src/layouts/BasicLayout.js | 12 ++- src/layouts/LoadingPage.js | 4 +- src/models/setting.js | 10 ++- src/routes/Dashboard/Analysis.js | 22 +++--- src/routes/Forms/StepForm/Step3.js | 22 ++++-- src/routes/Forms/StepForm/index.js | 3 +- src/routes/Forms/StepForm/style.less | 3 + src/routes/Result/Success.js | 2 +- src/routes/User/Login.less | 3 + tests/run-tests.js | 3 +- 26 files changed, 249 insertions(+), 49 deletions(-) create mode 100644 src/components/SiderMenu/SilderMenu.test.js diff --git a/.babelrc.js b/.babelrc.js index e89d2204..20a0892b 100644 --- a/.babelrc.js +++ b/.babelrc.js @@ -3,7 +3,7 @@ const path = require('path'); module.exports = { plugins: [ [ - 'babel-plugin-module-resolver', + 'module-resolver', { alias: { components: path.join(__dirname, './src/components'), diff --git a/.gitignore b/.gitignore index fd9bf875..4770ad5a 100755 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ yarn.lock package-lock.json *bak jsconfig.json +.vscode/settings.json diff --git a/.prettierignore b/.prettierignore index 10e1da6a..95765e94 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,5 @@ **/*.md **/*.svg **/*.ejs +**/*.html package.json diff --git a/package.json b/package.json index c1c2c013..8cd618ff 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ant-design-pro", - "version": "1.3.0", + "version": "2.0.0-beta.1", "description": "An out-of-box UI solution for enterprise applications", "private": true, "scripts": { @@ -78,18 +78,18 @@ "pro-download": "^1.0.1", "redbox-react": "^1.5.0", "regenerator-runtime": "^0.11.1", - "roadhog": "^2.3.0", - "roadhog-api-doc": "^1.0.2", - "stylelint": "^9.2.0", + "roadhog": "^2.4.1", + "roadhog-api-doc": "^1.0.3", + "stylelint": "^8.4.0", "stylelint-config-prettier": "^3.0.4", "stylelint-config-standard": "^18.0.0" }, "optionalDependencies": { - "puppeteer": "^1.3.0" + "puppeteer": "^1.4.0" }, "lint-staged": { "**/*.{js,jsx,less}": [ - "prettier --wirter", + "prettier --write", "git add" ], "**/*.{js,jsx}": "npm run lint-staged:js", diff --git a/src/components/Charts/index.js b/src/components/Charts/index.js index cacedbce..78863fab 100644 --- a/src/components/Charts/index.js +++ b/src/components/Charts/index.js @@ -13,7 +13,7 @@ import WaterWave from './WaterWave'; import TagCloud from './TagCloud'; import TimelineChart from './TimelineChart'; -const yuan = val => `¥ ${numeral(val).format('0,0')}`; +const yuan = val => `¥ ${numeral(val).format('0,0')}`; const Charts = { yuan, diff --git a/src/components/DescriptionList/DescriptionList.js b/src/components/DescriptionList/DescriptionList.js index 73ba989c..73bb5f5f 100644 --- a/src/components/DescriptionList/DescriptionList.js +++ b/src/components/DescriptionList/DescriptionList.js @@ -22,7 +22,10 @@ const DescriptionList = ({
{title ?
{title}
: null} - {React.Children.map(children, child => React.cloneElement(child, { column }))} + {React.Children.map( + children, + child => (child ? React.cloneElement(child, { column }) : child) + )}
); diff --git a/src/components/Login/index.d.ts b/src/components/Login/index.d.ts index 2c0fd01a..cd88a8b6 100644 --- a/src/components/Login/index.d.ts +++ b/src/components/Login/index.d.ts @@ -18,6 +18,7 @@ export interface LoginItemProps { rules?: any[]; style?: React.CSSProperties; onGetCaptcha?: () => void; + placeholder?: string; } export class LoginItem extends React.Component {} diff --git a/src/components/Login/index.less b/src/components/Login/index.less index e0a984cd..2894749b 100644 --- a/src/components/Login/index.less +++ b/src/components/Login/index.less @@ -35,6 +35,7 @@ .getCaptcha { display: block; width: 100%; + height: 42px; } .submit { diff --git a/src/components/PageHeader/index.js b/src/components/PageHeader/index.js index 0d3f63f2..81ef6c1c 100644 --- a/src/components/PageHeader/index.js +++ b/src/components/PageHeader/index.js @@ -25,10 +25,12 @@ export default class PageHeader extends PureComponent { componentDidMount() { this.getBreadcrumbDom(); } - componentWillReceiveProps() { - this.getBreadcrumbDom(); - } + componentDidUpdate(preProps) { + if (preProps.tabActiveKey !== this.props.tabActiveKey) { + this.getBreadcrumbDom(); + } + } onChange = key => { if (this.props.onTabChange) { this.props.onTabChange(key); diff --git a/src/components/Result/index.less b/src/components/Result/index.less index 9953392c..5cd2aff5 100644 --- a/src/components/Result/index.less +++ b/src/components/Result/index.less @@ -4,6 +4,9 @@ text-align: center; width: 72%; margin: 0 auto; + @media screen and (max-width: @screen-xs) { + width: 100%; + } .icon { font-size: 72px; @@ -39,6 +42,10 @@ padding: 24px 40px; border-radius: @border-radius-sm; text-align: left; + + @media screen and (max-width: @screen-xs) { + padding: 18px 20px; + } } .actions { diff --git a/src/components/Sidebar/index.js b/src/components/Sidebar/index.js index 3635912f..ef448460 100644 --- a/src/components/Sidebar/index.js +++ b/src/components/Sidebar/index.js @@ -87,7 +87,7 @@ class Sidebar extends PureComponent { this.changeSetting('fixSiderbar', checked); }; changeSetting = (key, value) => { - const nextState = {}; + const nextState = { ...this.props.setting }; nextState[key] = value; if (key === 'layout') { if (value === 'topmenu') { diff --git a/src/components/SiderMenu/BaseMenu.js b/src/components/SiderMenu/BaseMenu.js index 7c074d38..cbbdd386 100644 --- a/src/components/SiderMenu/BaseMenu.js +++ b/src/components/SiderMenu/BaseMenu.js @@ -67,7 +67,9 @@ export default class BaseMenu extends PureComponent { }; // Get the currently selected menu getSelectedMenuKeys = () => { - const { location: { pathname } } = this.props; + const { + location: { pathname }, + } = this.props; return urlToList(pathname).map(itemPath => getMenuMatches(this.flatMenuKeys, itemPath).pop()); }; /** @@ -148,20 +150,27 @@ export default class BaseMenu extends PureComponent { } }; render() { - const { openKeys } = this.props; + const { openKeys, theme, mode } = this.props; // if pathname can't match, use the nearest parent's key let selectedKeys = this.getSelectedMenuKeys(); if (!selectedKeys.length && openKeys) { selectedKeys = [openKeys[openKeys.length - 1]]; } + let props = {}; + if (openKeys) { + props = { + openKeys, + }; + } return ( {this.getNavMenuItems(this.menus)} diff --git a/src/components/SiderMenu/SiderMenu.js b/src/components/SiderMenu/SiderMenu.js index 176b5f66..cb308d40 100644 --- a/src/components/SiderMenu/SiderMenu.js +++ b/src/components/SiderMenu/SiderMenu.js @@ -1,5 +1,6 @@ import React, { PureComponent } from 'react'; import { Layout, Menu, Icon } from 'antd'; +import pathToRegexp from 'path-to-regexp'; import { Link } from 'dva/router'; import styles from './index.less'; import BaseMenu, { getMenuMatches } from './BaseMenu'; @@ -37,6 +38,32 @@ const getIcon = icon => { return icon; }; +/** + * Recursively flatten the data + * [{path:string},{path:string}] => {path,path2} + * @param menu + */ +export const getFlatMenuKeys = menu => + menu.reduce((keys, item) => { + keys.push(item.path); + if (item.children) { + return keys.concat(getFlatMenuKeys(item.children)); + } + return keys; + }, []); + +/** + * Find all matched menu keys based on paths + * @param flatMenuKeys: [/abc, /abc/:id, /abc/:id/info] + * @param paths: [/abc, /abc/11, /abc/11/info] + */ +export const getMenuMatchKeys = (flatMenuKeys, paths) => + paths.reduce( + (matchKeys, path) => + matchKeys.concat(flatMenuKeys.filter(item => pathToRegexp(item).test(path))), + [] + ); + export default class SiderMenu extends PureComponent { static getDerivedStateFromProps(nextProps) { return { @@ -45,6 +72,8 @@ export default class SiderMenu extends PureComponent { } constructor(props) { super(props); + this.menus = props.menuData; + this.flatMenuKeys = getFlatMenuKeys(props.menuData); this.state = { openKeys: getDefaultCollapsedSubMenus(props), }; @@ -54,6 +83,15 @@ export default class SiderMenu extends PureComponent { * Convert pathname to openKeys * /list/search/articles = > ['list','/list/search'] * @param props + */ + getDefaultCollapsedSubMenus(props) { + const { + location: { pathname }, + } = + props || this.props; + return getMenuMatchKeys(this.flatMenuKeys, urlToList(pathname)); + } + /** * 判断是否是http链接.返回 Link 或 a * Judge whether it is http link.return a or Link * @memberof SiderMenu @@ -120,6 +158,47 @@ export default class SiderMenu extends PureComponent { return {this.getMenuItemPath(item)}; } }; + /** + * 获得菜单子节点 + * @memberof SiderMenu + */ + getNavMenuItems = menusData => { + if (!menusData) { + return []; + } + return menusData + .filter(item => item.name && !item.hideInMenu) + .map(item => { + // make dom + const ItemDom = this.getSubMenuOrItem(item); + return this.checkPermissionItem(item.authority, ItemDom); + }) + .filter(item => item); + }; + // Get the currently selected menu + getSelectedMenuKeys = () => { + const { + location: { pathname }, + } = this.props; + return getMenuMatchKeys(this.flatMenuKeys, urlToList(pathname)); + }; + // conversion Path + // 转化路径 + conversionPath = path => { + if (path && path.indexOf('http') === 0) { + return path; + } else { + return `/${path || ''}`.replace(/\/+/g, '/'); + } + }; + // permission to check + checkPermissionItem = (authority, ItemDom) => { + if (this.props.Authorized && this.props.Authorized.check) { + const { check } = this.props.Authorized; + return check(authority, ItemDom); + } + return ItemDom; + }; isMainMenu = key => { return this.props.menuData.some(item => key && (item.key === key || item.path === key)); }; diff --git a/src/components/SiderMenu/SilderMenu.test.js b/src/components/SiderMenu/SilderMenu.test.js new file mode 100644 index 00000000..8f01f669 --- /dev/null +++ b/src/components/SiderMenu/SilderMenu.test.js @@ -0,0 +1,72 @@ +import { urlToList } from '../_utils/pathTools'; +import { getFlatMenuKeys, getMenuMatchKeys } from './SiderMenu'; + +const menu = [ + { + path: '/dashboard', + children: [ + { + path: '/dashboard/name', + }, + ], + }, + { + path: '/userinfo', + children: [ + { + path: '/userinfo/:id', + children: [ + { + path: '/userinfo/:id/info', + }, + ], + }, + ], + }, +]; + +const flatMenuKeys = getFlatMenuKeys(menu); + +describe('test convert nested menu to flat menu', () => { + it('simple menu', () => { + expect(flatMenuKeys).toEqual([ + '/dashboard', + '/dashboard/name', + '/userinfo', + '/userinfo/:id', + '/userinfo/:id/info', + ]); + }); +}); + +describe('test menu match', () => { + it('simple path', () => { + expect(getMenuMatchKeys(flatMenuKeys, urlToList('/dashboard'))).toEqual(['/dashboard']); + }); + + it('error path', () => { + expect(getMenuMatchKeys(flatMenuKeys, urlToList('/dashboardname'))).toEqual([]); + }); + + it('Secondary path', () => { + expect(getMenuMatchKeys(flatMenuKeys, urlToList('/dashboard/name'))).toEqual([ + '/dashboard', + '/dashboard/name', + ]); + }); + + it('Parameter path', () => { + expect(getMenuMatchKeys(flatMenuKeys, urlToList('/userinfo/2144'))).toEqual([ + '/userinfo', + '/userinfo/:id', + ]); + }); + + it('three parameter path', () => { + expect(getMenuMatchKeys(flatMenuKeys, urlToList('/userinfo/2144/info'))).toEqual([ + '/userinfo', + '/userinfo/:id', + '/userinfo/:id/info', + ]); + }); +}); diff --git a/src/e2e/home.e2e.js b/src/e2e/home.e2e.js index 05377e85..50447a4a 100644 --- a/src/e2e/home.e2e.js +++ b/src/e2e/home.e2e.js @@ -2,7 +2,7 @@ import puppeteer from 'puppeteer'; describe('Homepage', () => { it('it should have logo text', async () => { - const browser = await puppeteer.launch(); + const browser = await puppeteer.launch({ args: ['--no-sandbox'] }); const page = await browser.newPage(); await page.goto('http://localhost:8000', { waitUntil: 'networkidle2' }); await page.waitForSelector('h1'); diff --git a/src/e2e/login.e2e.js b/src/e2e/login.e2e.js index 6095b9e5..a102a351 100644 --- a/src/e2e/login.e2e.js +++ b/src/e2e/login.e2e.js @@ -5,7 +5,7 @@ describe('Login', () => { let page; beforeAll(async () => { - browser = await puppeteer.launch(); + browser = await puppeteer.launch({ args: ['--no-sandbox'] }); }); beforeEach(async () => { diff --git a/src/layouts/BasicLayout.js b/src/layouts/BasicLayout.js index 21d2a420..d4853390 100644 --- a/src/layouts/BasicLayout.js +++ b/src/layouts/BasicLayout.js @@ -5,6 +5,7 @@ import { connect } from 'dva'; import { Route, Redirect, Switch } from 'dva/router'; import { ContainerQuery } from 'react-container-query'; import classNames from 'classnames'; +import pathToRegexp from 'path-to-regexp'; import SiderMenu from '../components/SiderMenu'; import NotFound from '../routes/Exception/404'; import { getRoutes } from '../utils/utils'; @@ -70,8 +71,15 @@ class BasicLayout extends React.PureComponent { const { routerData, location } = this.props; const { pathname } = location; let title = 'Ant Design Pro'; - if (routerData[pathname] && routerData[pathname].name) { - title = `${routerData[pathname].name} - Ant Design Pro`; + let currRouterData = null; + // match params path + Object.keys(routerData).forEach(key => { + if (pathToRegexp(key).test(pathname)) { + currRouterData = routerData[key]; + } + }); + if (currRouterData && currRouterData.name) { + title = `${currRouterData.name} - Ant Design Pro`; } return title; } diff --git a/src/layouts/LoadingPage.js b/src/layouts/LoadingPage.js index f5a110b8..ee7029b3 100644 --- a/src/layouts/LoadingPage.js +++ b/src/layouts/LoadingPage.js @@ -2,7 +2,6 @@ import React, { PureComponent } from 'react'; import { Spin } from 'antd'; import { connect } from 'dva'; import { enquireScreen, unenquireScreen } from 'enquire-js'; - import BasicLayout from './BasicLayout'; import { getMenuData } from '../common/menu'; /** @@ -35,7 +34,6 @@ class LoadingPage extends PureComponent { loading: true, isMobile: false, }; - componentDidMount() { this.enquireHandler = enquireScreen(mobile => { this.setState({ @@ -45,8 +43,8 @@ class LoadingPage extends PureComponent { this.props.dispatch({ type: 'user/fetchCurrent', }); - this.initSetting(); this.hideLoading(); + this.initSetting(); } componentWillUnmount() { unenquireScreen(this.enquireHandler); diff --git a/src/models/setting.js b/src/models/setting.js index fe9fdb03..cf5a8380 100644 --- a/src/models/setting.js +++ b/src/models/setting.js @@ -11,19 +11,21 @@ const defaultSetting = { }; export default { namespace: 'setting', - state: defaultSetting, reducers: { getSetting(state) { - const setting = { ...state }; + const setting = {}; const urlParams = new URL(window.location.href); Object.keys(state).forEach(key => { if (urlParams.searchParams.has(key)) { const value = urlParams.searchParams.get(key); - setting[key] = value === '1' ? true : '1'; + setting[key] = value === '1' ? true : value; } }); - return setting; + return { + ...state, + ...setting, + }; }, changeSetting(state, { payload }) { const urlParams = new URL(window.location.href); diff --git a/src/routes/Dashboard/Analysis.js b/src/routes/Dashboard/Analysis.js index 65354a4a..d04c4570 100644 --- a/src/routes/Dashboard/Analysis.js +++ b/src/routes/Dashboard/Analysis.js @@ -44,6 +44,12 @@ for (let i = 0; i < 7; i += 1) { }); } +const Yuan = ({ children }) => ( + /* eslint-disable-line react/no-danger */ +); + @connect(({ chart, loading }) => ({ chart, loading: loading.effects['chart/fetch'], @@ -132,7 +138,9 @@ export default class Analysis extends Component { const salesPieData = salesType === 'all' ? salesTypeData - : salesType === 'online' ? salesTypeDataOnline : salesTypeDataOffline; + : salesType === 'online' + ? salesTypeDataOnline + : salesTypeDataOffline; const menu = ( @@ -254,7 +262,7 @@ export default class Analysis extends Component { } - total={() => } + total={() => 126560} footer={} contentHeight={46} > @@ -453,15 +461,9 @@ export default class Analysis extends Component { ( - now.y + pre, 0)), - }} - /> - )} + total={() => {salesPieData.reduce((pre, now) => now.y + pre, 0)}} data={salesPieData} - valueFormat={val => } + valueFormat={value => {value}} height={248} lineWidth={4} /> diff --git a/src/routes/Forms/StepForm/Step3.js b/src/routes/Forms/StepForm/Step3.js index 08fc5d90..9a8d6d46 100644 --- a/src/routes/Forms/StepForm/Step3.js +++ b/src/routes/Forms/StepForm/Step3.js @@ -14,28 +14,34 @@ class Step3 extends React.PureComponent { const information = (
- + 付款账户: - {data.payAccount} + + {data.payAccount} + - + 收款账户: - {data.receiverAccount} + + {data.receiverAccount} + - + 收款人姓名: - {data.receiverName} + + {data.receiverName} + - + 转账金额: - + {data.amount} diff --git a/src/routes/Forms/StepForm/index.js b/src/routes/Forms/StepForm/index.js index 23c660d9..273bfad1 100644 --- a/src/routes/Forms/StepForm/index.js +++ b/src/routes/Forms/StepForm/index.js @@ -24,10 +24,11 @@ export default class StepForm extends PureComponent { } } render() { - const { match, routerData } = this.props; + const { match, routerData, location } = this.props; return ( diff --git a/src/routes/Forms/StepForm/style.less b/src/routes/Forms/StepForm/style.less index 6dbbd629..713dd54c 100644 --- a/src/routes/Forms/StepForm/style.less +++ b/src/routes/Forms/StepForm/style.less @@ -60,6 +60,9 @@ color: @heading-color; text-align: right; padding-right: 8px; + @media screen and (max-width: @screen-sm) { + text-align: left; + } } } diff --git a/src/routes/Result/Success.js b/src/routes/Result/Success.js index c27567a8..9e20e278 100644 --- a/src/routes/Result/Success.js +++ b/src/routes/Result/Success.js @@ -1,6 +1,6 @@ import React, { Fragment } from 'react'; import { Button, Row, Col, Icon, Steps, Card } from 'antd'; -import Result from '../../components/Result'; +import Result from 'components/Result'; import PageHeaderLayout from '../../layouts/PageHeaderLayout'; const { Step } = Steps; diff --git a/src/routes/User/Login.less b/src/routes/User/Login.less index c34ab3d8..14a99ff1 100644 --- a/src/routes/User/Login.less +++ b/src/routes/User/Login.less @@ -3,6 +3,9 @@ .main { width: 368px; margin: 0 auto; + @media screen and (max-width: @screen-sm) { + width: 95%; + } .icon { font-size: 24px; diff --git a/tests/run-tests.js b/tests/run-tests.js index d48a759f..7a51228c 100644 --- a/tests/run-tests.js +++ b/tests/run-tests.js @@ -30,8 +30,9 @@ startServer.stdout.on('data', data => { const testCmd = spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['test'], { stdio: 'inherit', }); - testCmd.on('exit', () => { + testCmd.on('exit', code => { startServer.kill(); + process.exit(code); }); } }); -- GitLab