Commit 0e2cd76a authored by jim's avatar jim

fix default setting bug

parent 255a70b6
...@@ -3,7 +3,7 @@ const path = require('path'); ...@@ -3,7 +3,7 @@ const path = require('path');
module.exports = { module.exports = {
plugins: [ plugins: [
[ [
'babel-plugin-module-resolver', 'module-resolver',
{ {
alias: { alias: {
components: path.join(__dirname, './src/components'), components: path.join(__dirname, './src/components'),
......
...@@ -21,3 +21,4 @@ yarn.lock ...@@ -21,3 +21,4 @@ yarn.lock
package-lock.json package-lock.json
*bak *bak
jsconfig.json jsconfig.json
.vscode/settings.json
**/*.md **/*.md
**/*.svg **/*.svg
**/*.ejs **/*.ejs
**/*.html
package.json package.json
{ {
"name": "ant-design-pro", "name": "ant-design-pro",
"version": "1.3.0", "version": "2.0.0-beta.1",
"description": "An out-of-box UI solution for enterprise applications", "description": "An out-of-box UI solution for enterprise applications",
"private": true, "private": true,
"scripts": { "scripts": {
...@@ -78,18 +78,18 @@ ...@@ -78,18 +78,18 @@
"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.4.1",
"roadhog-api-doc": "^1.0.2", "roadhog-api-doc": "^1.0.3",
"stylelint": "^9.2.0", "stylelint": "^8.4.0",
"stylelint-config-prettier": "^3.0.4", "stylelint-config-prettier": "^3.0.4",
"stylelint-config-standard": "^18.0.0" "stylelint-config-standard": "^18.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"puppeteer": "^1.3.0" "puppeteer": "^1.4.0"
}, },
"lint-staged": { "lint-staged": {
"**/*.{js,jsx,less}": [ "**/*.{js,jsx,less}": [
"prettier --wirter", "prettier --write",
"git add" "git add"
], ],
"**/*.{js,jsx}": "npm run lint-staged:js", "**/*.{js,jsx}": "npm run lint-staged:js",
......
...@@ -13,7 +13,7 @@ import WaterWave from './WaterWave'; ...@@ -13,7 +13,7 @@ import WaterWave from './WaterWave';
import TagCloud from './TagCloud'; import TagCloud from './TagCloud';
import TimelineChart from './TimelineChart'; import TimelineChart from './TimelineChart';
const yuan = val => `¥ ${numeral(val).format('0,0')}`; const yuan = val => `¥ ${numeral(val).format('0,0')}`;
const Charts = { const Charts = {
yuan, yuan,
......
...@@ -22,7 +22,10 @@ const DescriptionList = ({ ...@@ -22,7 +22,10 @@ const DescriptionList = ({
<div className={clsString} {...restProps}> <div className={clsString} {...restProps}>
{title ? <div className={styles.title}>{title}</div> : null} {title ? <div className={styles.title}>{title}</div> : null}
<Row gutter={gutter}> <Row gutter={gutter}>
{React.Children.map(children, child => React.cloneElement(child, { column }))} {React.Children.map(
children,
child => (child ? React.cloneElement(child, { column }) : child)
)}
</Row> </Row>
</div> </div>
); );
......
...@@ -18,6 +18,7 @@ export interface LoginItemProps { ...@@ -18,6 +18,7 @@ export interface LoginItemProps {
rules?: any[]; rules?: any[];
style?: React.CSSProperties; style?: React.CSSProperties;
onGetCaptcha?: () => void; onGetCaptcha?: () => void;
placeholder?: string;
} }
export class LoginItem extends React.Component<LoginItemProps, any> {} export class LoginItem extends React.Component<LoginItemProps, any> {}
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
.getCaptcha { .getCaptcha {
display: block; display: block;
width: 100%; width: 100%;
height: 42px;
} }
.submit { .submit {
......
...@@ -25,10 +25,12 @@ export default class PageHeader extends PureComponent { ...@@ -25,10 +25,12 @@ export default class PageHeader extends PureComponent {
componentDidMount() { componentDidMount() {
this.getBreadcrumbDom(); this.getBreadcrumbDom();
} }
componentWillReceiveProps() {
componentDidUpdate(preProps) {
if (preProps.tabActiveKey !== this.props.tabActiveKey) {
this.getBreadcrumbDom(); this.getBreadcrumbDom();
} }
}
onChange = key => { onChange = key => {
if (this.props.onTabChange) { if (this.props.onTabChange) {
this.props.onTabChange(key); this.props.onTabChange(key);
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
text-align: center; text-align: center;
width: 72%; width: 72%;
margin: 0 auto; margin: 0 auto;
@media screen and (max-width: @screen-xs) {
width: 100%;
}
.icon { .icon {
font-size: 72px; font-size: 72px;
...@@ -39,6 +42,10 @@ ...@@ -39,6 +42,10 @@
padding: 24px 40px; padding: 24px 40px;
border-radius: @border-radius-sm; border-radius: @border-radius-sm;
text-align: left; text-align: left;
@media screen and (max-width: @screen-xs) {
padding: 18px 20px;
}
} }
.actions { .actions {
......
...@@ -87,7 +87,7 @@ class Sidebar extends PureComponent { ...@@ -87,7 +87,7 @@ class Sidebar extends PureComponent {
this.changeSetting('fixSiderbar', checked); this.changeSetting('fixSiderbar', checked);
}; };
changeSetting = (key, value) => { changeSetting = (key, value) => {
const nextState = {}; const nextState = { ...this.props.setting };
nextState[key] = value; nextState[key] = value;
if (key === 'layout') { if (key === 'layout') {
if (value === 'topmenu') { if (value === 'topmenu') {
......
...@@ -67,7 +67,9 @@ export default class BaseMenu extends PureComponent { ...@@ -67,7 +67,9 @@ export default class BaseMenu 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 => getMenuMatches(this.flatMenuKeys, itemPath).pop()); return urlToList(pathname).map(itemPath => getMenuMatches(this.flatMenuKeys, itemPath).pop());
}; };
/** /**
...@@ -148,20 +150,27 @@ export default class BaseMenu extends PureComponent { ...@@ -148,20 +150,27 @@ export default class BaseMenu extends PureComponent {
} }
}; };
render() { render() {
const { openKeys } = this.props; const { openKeys, theme, mode } = this.props;
// 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 && openKeys) { if (!selectedKeys.length && openKeys) {
selectedKeys = [openKeys[openKeys.length - 1]]; selectedKeys = [openKeys[openKeys.length - 1]];
} }
let props = {};
if (openKeys) {
props = {
openKeys,
};
}
return ( return (
<Menu <Menu
key="Menu" key="Menu"
mode="inline" mode={mode}
theme={theme}
onOpenChange={this.props.handleOpenChange} onOpenChange={this.props.handleOpenChange}
selectedKeys={selectedKeys} selectedKeys={selectedKeys}
style={this.props.style} style={this.props.style}
{...this.props} {...props}
> >
{this.getNavMenuItems(this.menus)} {this.getNavMenuItems(this.menus)}
</Menu> </Menu>
......
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { Layout, Menu, Icon } from 'antd'; import { Layout, Menu, Icon } from 'antd';
import pathToRegexp from 'path-to-regexp';
import { Link } from 'dva/router'; import { Link } from 'dva/router';
import styles from './index.less'; import styles from './index.less';
import BaseMenu, { getMenuMatches } from './BaseMenu'; import BaseMenu, { getMenuMatches } from './BaseMenu';
...@@ -37,6 +38,32 @@ const getIcon = icon => { ...@@ -37,6 +38,32 @@ const getIcon = icon => {
return 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 { export default class SiderMenu extends PureComponent {
static getDerivedStateFromProps(nextProps) { static getDerivedStateFromProps(nextProps) {
return { return {
...@@ -45,6 +72,8 @@ export default class SiderMenu extends PureComponent { ...@@ -45,6 +72,8 @@ export default class SiderMenu extends PureComponent {
} }
constructor(props) { constructor(props) {
super(props); super(props);
this.menus = props.menuData;
this.flatMenuKeys = getFlatMenuKeys(props.menuData);
this.state = { this.state = {
openKeys: getDefaultCollapsedSubMenus(props), openKeys: getDefaultCollapsedSubMenus(props),
}; };
...@@ -54,6 +83,15 @@ export default class SiderMenu extends PureComponent { ...@@ -54,6 +83,15 @@ export default class SiderMenu extends PureComponent {
* Convert pathname to openKeys * Convert pathname to openKeys
* /list/search/articles = > ['list','/list/search'] * /list/search/articles = > ['list','/list/search']
* @param props * @param props
*/
getDefaultCollapsedSubMenus(props) {
const {
location: { pathname },
} =
props || this.props;
return getMenuMatchKeys(this.flatMenuKeys, urlToList(pathname));
}
/**
* 判断是否是http链接.返回 Link 或 a * 判断是否是http链接.返回 Link 或 a
* Judge whether it is http link.return a or Link * Judge whether it is http link.return a or Link
* @memberof SiderMenu * @memberof SiderMenu
...@@ -120,6 +158,47 @@ export default class SiderMenu extends PureComponent { ...@@ -120,6 +158,47 @@ export default class SiderMenu extends PureComponent {
return <Menu.Item key={item.path}>{this.getMenuItemPath(item)}</Menu.Item>; return <Menu.Item key={item.path}>{this.getMenuItemPath(item)}</Menu.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 => { isMainMenu = key => {
return this.props.menuData.some(item => key && (item.key === key || item.path === key)); return this.props.menuData.some(item => key && (item.key === key || item.path === key));
}; };
......
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',
]);
});
});
...@@ -2,7 +2,7 @@ import puppeteer from 'puppeteer'; ...@@ -2,7 +2,7 @@ import puppeteer from 'puppeteer';
describe('Homepage', () => { describe('Homepage', () => {
it('it should have logo text', async () => { 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(); const page = await browser.newPage();
await page.goto('http://localhost:8000', { waitUntil: 'networkidle2' }); await page.goto('http://localhost:8000', { waitUntil: 'networkidle2' });
await page.waitForSelector('h1'); await page.waitForSelector('h1');
......
...@@ -5,7 +5,7 @@ describe('Login', () => { ...@@ -5,7 +5,7 @@ describe('Login', () => {
let page; let page;
beforeAll(async () => { beforeAll(async () => {
browser = await puppeteer.launch(); browser = await puppeteer.launch({ args: ['--no-sandbox'] });
}); });
beforeEach(async () => { beforeEach(async () => {
......
...@@ -5,6 +5,7 @@ import { connect } from 'dva'; ...@@ -5,6 +5,7 @@ import { connect } from 'dva';
import { Route, Redirect, Switch } from 'dva/router'; import { Route, Redirect, Switch } from 'dva/router';
import { ContainerQuery } from 'react-container-query'; import { ContainerQuery } from 'react-container-query';
import classNames from 'classnames'; import classNames from 'classnames';
import pathToRegexp from 'path-to-regexp';
import SiderMenu from '../components/SiderMenu'; import SiderMenu from '../components/SiderMenu';
import NotFound from '../routes/Exception/404'; import NotFound from '../routes/Exception/404';
import { getRoutes } from '../utils/utils'; import { getRoutes } from '../utils/utils';
...@@ -70,8 +71,15 @@ class BasicLayout extends React.PureComponent { ...@@ -70,8 +71,15 @@ class BasicLayout extends React.PureComponent {
const { routerData, location } = this.props; const { routerData, location } = this.props;
const { pathname } = location; const { pathname } = location;
let title = 'Ant Design Pro'; let title = 'Ant Design Pro';
if (routerData[pathname] && routerData[pathname].name) { let currRouterData = null;
title = `${routerData[pathname].name} - Ant Design Pro`; // 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; return title;
} }
......
...@@ -2,7 +2,6 @@ import React, { PureComponent } from 'react'; ...@@ -2,7 +2,6 @@ import React, { PureComponent } from 'react';
import { Spin } from 'antd'; import { Spin } from 'antd';
import { connect } from 'dva'; import { connect } from 'dva';
import { enquireScreen, unenquireScreen } from 'enquire-js'; import { enquireScreen, unenquireScreen } from 'enquire-js';
import BasicLayout from './BasicLayout'; import BasicLayout from './BasicLayout';
import { getMenuData } from '../common/menu'; import { getMenuData } from '../common/menu';
/** /**
...@@ -35,7 +34,6 @@ class LoadingPage extends PureComponent { ...@@ -35,7 +34,6 @@ class LoadingPage extends PureComponent {
loading: true, loading: true,
isMobile: false, isMobile: false,
}; };
componentDidMount() { componentDidMount() {
this.enquireHandler = enquireScreen(mobile => { this.enquireHandler = enquireScreen(mobile => {
this.setState({ this.setState({
...@@ -45,8 +43,8 @@ class LoadingPage extends PureComponent { ...@@ -45,8 +43,8 @@ class LoadingPage extends PureComponent {
this.props.dispatch({ this.props.dispatch({
type: 'user/fetchCurrent', type: 'user/fetchCurrent',
}); });
this.initSetting();
this.hideLoading(); this.hideLoading();
this.initSetting();
} }
componentWillUnmount() { componentWillUnmount() {
unenquireScreen(this.enquireHandler); unenquireScreen(this.enquireHandler);
......
...@@ -11,19 +11,21 @@ const defaultSetting = { ...@@ -11,19 +11,21 @@ const defaultSetting = {
}; };
export default { export default {
namespace: 'setting', namespace: 'setting',
state: defaultSetting, state: defaultSetting,
reducers: { reducers: {
getSetting(state) { getSetting(state) {
const setting = { ...state }; const setting = {};
const urlParams = new URL(window.location.href); const urlParams = new URL(window.location.href);
Object.keys(state).forEach(key => { Object.keys(state).forEach(key => {
if (urlParams.searchParams.has(key)) { if (urlParams.searchParams.has(key)) {
const value = urlParams.searchParams.get(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 }) { changeSetting(state, { payload }) {
const urlParams = new URL(window.location.href); const urlParams = new URL(window.location.href);
......
...@@ -44,6 +44,12 @@ for (let i = 0; i < 7; i += 1) { ...@@ -44,6 +44,12 @@ for (let i = 0; i < 7; i += 1) {
}); });
} }
const Yuan = ({ children }) => (
<span
dangerouslySetInnerHTML={{ __html: yuan(children) }}
/> /* eslint-disable-line react/no-danger */
);
@connect(({ chart, loading }) => ({ @connect(({ chart, loading }) => ({
chart, chart,
loading: loading.effects['chart/fetch'], loading: loading.effects['chart/fetch'],
...@@ -132,7 +138,9 @@ export default class Analysis extends Component { ...@@ -132,7 +138,9 @@ export default class Analysis extends Component {
const salesPieData = const salesPieData =
salesType === 'all' salesType === 'all'
? salesTypeData ? salesTypeData
: salesType === 'online' ? salesTypeDataOnline : salesTypeDataOffline; : salesType === 'online'
? salesTypeDataOnline
: salesTypeDataOffline;
const menu = ( const menu = (
<Menu> <Menu>
...@@ -254,7 +262,7 @@ export default class Analysis extends Component { ...@@ -254,7 +262,7 @@ export default class Analysis extends Component {
<Icon type="info-circle-o" /> <Icon type="info-circle-o" />
</Tooltip> </Tooltip>
} }
total={() => <span dangerouslySetInnerHTML={{ __html: yuan(126560) }} />} total={() => <Yuan>126560</Yuan>}
footer={<Field label="日均销售额" value={`¥${numeral(12423).format('0,0')}`} />} footer={<Field label="日均销售额" value={`¥${numeral(12423).format('0,0')}`} />}
contentHeight={46} contentHeight={46}
> >
...@@ -453,15 +461,9 @@ export default class Analysis extends Component { ...@@ -453,15 +461,9 @@ export default class Analysis extends Component {
<Pie <Pie
hasLegend hasLegend
subTitle="销售额" subTitle="销售额"
total={() => ( total={() => <Yuan>{salesPieData.reduce((pre, now) => now.y + pre, 0)}</Yuan>}
<span
dangerouslySetInnerHTML={{
__html: yuan(salesPieData.reduce((pre, now) => now.y + pre, 0)),
}}
/>
)}
data={salesPieData} data={salesPieData}
valueFormat={val => <span dangerouslySetInnerHTML={{ __html: yuan(val) }} />} valueFormat={value => <Yuan>{value}</Yuan>}
height={248} height={248}
lineWidth={4} lineWidth={4}
/> />
......
...@@ -14,28 +14,34 @@ class Step3 extends React.PureComponent { ...@@ -14,28 +14,34 @@ class Step3 extends React.PureComponent {
const information = ( const information = (
<div className={styles.information}> <div className={styles.information}>
<Row> <Row>
<Col span={8} className={styles.label}> <Col xs={24} sm={8} className={styles.label}>
付款账户 付款账户
</Col> </Col>
<Col span={16}>{data.payAccount}</Col> <Col xs={24} sm={16}>
{data.payAccount}
</Col>
</Row> </Row>
<Row> <Row>
<Col span={8} className={styles.label}> <Col xs={24} sm={8} className={styles.label}>
收款账户 收款账户
</Col> </Col>
<Col span={16}>{data.receiverAccount}</Col> <Col xs={24} sm={16}>
{data.receiverAccount}
</Col>
</Row> </Row>
<Row> <Row>
<Col span={8} className={styles.label}> <Col xs={24} sm={8} className={styles.label}>
收款人姓名 收款人姓名
</Col> </Col>
<Col span={16}>{data.receiverName}</Col> <Col xs={24} sm={16}>
{data.receiverName}
</Col>
</Row> </Row>
<Row> <Row>
<Col span={8} className={styles.label}> <Col xs={24} sm={8} className={styles.label}>
转账金额 转账金额
</Col> </Col>
<Col span={16}> <Col xs={24} sm={16}>
<span className={styles.money}>{data.amount}</span> <span className={styles.money}>{data.amount}</span>
</Col> </Col>
</Row> </Row>
......
...@@ -24,10 +24,11 @@ export default class StepForm extends PureComponent { ...@@ -24,10 +24,11 @@ export default class StepForm extends PureComponent {
} }
} }
render() { render() {
const { match, routerData } = this.props; const { match, routerData, location } = this.props;
return ( return (
<PageHeaderLayout <PageHeaderLayout
title="分步表单" title="分步表单"
tabActiveKey={location.pathname}
content="将一个冗长或用户不熟悉的表单任务分成多个步骤,指导用户完成。" content="将一个冗长或用户不熟悉的表单任务分成多个步骤,指导用户完成。"
> >
<Card bordered={false}> <Card bordered={false}>
......
...@@ -60,6 +60,9 @@ ...@@ -60,6 +60,9 @@
color: @heading-color; color: @heading-color;
text-align: right; text-align: right;
padding-right: 8px; padding-right: 8px;
@media screen and (max-width: @screen-sm) {
text-align: left;
}
} }
} }
......
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import { Button, Row, Col, Icon, Steps, Card } from 'antd'; import { Button, Row, Col, Icon, Steps, Card } from 'antd';
import Result from '../../components/Result'; import Result from 'components/Result';
import PageHeaderLayout from '../../layouts/PageHeaderLayout'; import PageHeaderLayout from '../../layouts/PageHeaderLayout';
const { Step } = Steps; const { Step } = Steps;
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
.main { .main {
width: 368px; width: 368px;
margin: 0 auto; margin: 0 auto;
@media screen and (max-width: @screen-sm) {
width: 95%;
}
.icon { .icon {
font-size: 24px; font-size: 24px;
......
...@@ -30,8 +30,9 @@ startServer.stdout.on('data', data => { ...@@ -30,8 +30,9 @@ startServer.stdout.on('data', data => {
const testCmd = spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['test'], { const testCmd = spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['test'], {
stdio: 'inherit', stdio: 'inherit',
}); });
testCmd.on('exit', () => { testCmd.on('exit', code => {
startServer.kill(); startServer.kill();
process.exit(code);
}); });
} }
}); });
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