Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v4] Strict ts #3723

Merged
merged 14 commits into from
Mar 14, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,7 @@ module.exports = {
},
settings: {
polyfills: ['fetch', 'promises', 'url'],
// support import modules from TypeScript files in JavaScript files
'import/resolver': { node: { extensions: ['.js', '.ts', '.tsx'] } },
},
};
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"singleQuote": true,
"trailingComma": "es5",
"trailingComma": "all",
"printWidth": 100,
"overrides": [
{
Expand Down
7 changes: 3 additions & 4 deletions config/config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// https://umijs.org/config/
import os from 'os';
// import os from 'os';
import slash from 'slash2';
import { IPlugin } from 'umi-types';
import { IPlugin, IConfig } from 'umi-types';
import defaultSettings from './defaultSettings';
import webpackPlugin from './plugin.config';

Expand Down Expand Up @@ -144,6 +144,5 @@ export default {
manifest: {
basePath: '/',
},

chainWebpack: webpackPlugin,
};
} as IConfig;
20 changes: 15 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
"dev:no-mock": "cross-env MOCK=none umi dev",
"build": "umi build",
"analyze": "cross-env ANALYZE=1 umi build",
"lint:js": "eslint --ext .js src tests",
"lint:ts": "tslint -p . -c tslint.yml",
"lint:style": "stylelint 'src/**/*.less' --syntax less",
"lint:prettier": "check-prettier lint",
"lint": "eslint --ext .js src tests && npm run lint:style && npm run lint:prettier",
"lint:fix": "eslint --fix --ext .js src tests && stylelint --fix 'src/**/*.less' --syntax less",
"lint": "npm run lint:js && npm run lint:ts && npm run lint:style && npm run lint:prettier",
"lint:fix": "eslint --fix --ext .js src tests && tslint --fix -p . -c tslint.yml && stylelint --fix 'src/**/*.less' --syntax less",
"lint-staged": "lint-staged",
"lint-staged:js": "eslint --ext .js",
"lint-staged:ts": "tslint",
"test": "umi test",
"test:component": "umi test ./src/components",
"test:all": "node ./tests/run-tests.js",
Expand Down Expand Up @@ -48,12 +51,16 @@
"react-document-title": "^2.0.3",
"react-media": "^1.8.0",
"react-media-hook2": "^1.0.2",
"umi-request": "^1.0.0",
"umi-types": "^0.2.0"
"umi-request": "^1.0.0"
},
"devDependencies": {
"@types/classnames": "^2.2.7",
"@types/enzyme": "^3.9.0",
"@types/jest": "^24.0.11",
"@types/lodash": "^4.14.122",
"@types/memoize-one": "^4.1.0",
"@types/react": "^16.8.1",
"@types/react-document-title": "^2.0.3",
"@types/react-dom": "^16.0.11",
"antd-pro-merge-less": "^1.0.0",
"antd-theme-webpack-plugin": "^1.2.0",
Expand Down Expand Up @@ -90,11 +97,13 @@
"stylelint-order": "^2.0.0",
"tslint": "^5.12.1",
"tslint-config-prettier": "^1.17.0",
"tslint-eslint-rules": "^5.4.0",
"tslint-react": "^3.6.0",
"umi": "^2.4.4",
"umi-plugin-ga": "^1.1.3",
"umi-plugin-pro-block": "^1.2.0",
"umi-plugin-react": "^1.3.4"
"umi-plugin-react": "^1.3.4",
"umi-types": "^0.2.0"
},
"optionalDependencies": {
"puppeteer": "^1.12.1"
Expand All @@ -105,6 +114,7 @@
"git add"
],
"**/*.{js,jsx}": "npm run lint-staged:js",
"**/*.{ts,tsx}": "npm run lint-staged:ts",
"**/*.less": "stylelint --syntax less"
},
"engines": {
Expand Down
4 changes: 2 additions & 2 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function ergodicRoutes(routes, authKey, authority) {

export function patchRoutes(routes) {
Object.keys(authRoutes).map(authKey =>
ergodicRoutes(routes, authKey, authRoutes[authKey].authority)
ergodicRoutes(routes, authKey, authRoutes[authKey].authority),
);
(window as any).g_routes = routes;
}
Expand All @@ -39,6 +39,6 @@ export function render(oldRender) {
},
() => {
oldRender();
}
},
);
}
53 changes: 23 additions & 30 deletions src/components/GlobalHeader/RightContent.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { ConnectProps } from '@/models/connect';
import { NoticeItem } from '@/models/global';
import { CurrentUser } from '@/models/user';
import React, { Component } from 'react';
import { FormattedMessage, formatMessage } from 'umi-plugin-locale';
import { Spin, Tag, Menu, Icon, Avatar, Tooltip, message } from 'antd';
Expand All @@ -10,38 +13,28 @@ import HeaderDropdown from '../HeaderDropdown';
import SelectLang from '../SelectLang';
import styles from './index.less';

export declare type SiderTheme = 'light' | 'dark';
export type SiderTheme = 'light' | 'dark';

interface GlobalHeaderRightProps {
notices?: any[];
dispatch?: (args: any) => void;
// wait for https://github.com/umijs/umi/pull/2036
currentUser?: {
avatar?: string;
name?: string;
title?: string;
group?: string;
signature?: string;
geographic?: any;
tags?: any[];
unreadCount: number;
};
export interface GlobalHeaderRightProps extends ConnectProps {
notices?: NoticeItem[];
currentUser?: CurrentUser;
fetchingNotices?: boolean;
onNoticeVisibleChange?: (visible: boolean) => void;
onMenuClick?: (param: ClickParam) => void;
onNoticeClear?: (tabName: string) => void;
theme?: SiderTheme;
}

export default class GlobalHeaderRight extends Component<GlobalHeaderRightProps> {
getNoticeData() {
getNoticeData = (): { [key: string]: NoticeItem[] } => {
const { notices = [] } = this.props;
if (notices.length === 0) {
return {};
}
const newNotices = notices.map(notice => {
const newNotice = { ...notice };
if (newNotice.datetime) {
newNotice.datetime = moment(notice.datetime).fromNow();
newNotice.datetime = moment(notice.datetime as string).fromNow();
}
if (newNotice.id) {
newNotice.key = newNotice.id;
Expand All @@ -62,10 +55,10 @@ export default class GlobalHeaderRight extends Component<GlobalHeaderRightProps>
return newNotice;
});
return groupBy(newNotices, 'type');
}
};

getUnreadData: (noticeData: object) => any = noticeData => {
const unreadMsg = {};
getUnreadData = (noticeData: { [key: string]: NoticeItem[] }) => {
const unreadMsg: { [key: string]: number } = {};
Object.entries(noticeData).forEach(([key, value]) => {
if (!unreadMsg[key]) {
unreadMsg[key] = 0;
Expand All @@ -77,10 +70,10 @@ export default class GlobalHeaderRight extends Component<GlobalHeaderRightProps>
return unreadMsg;
};

changeReadState = clickedItem => {
changeReadState = (clickedItem: NoticeItem) => {
const { id } = clickedItem;
const { dispatch } = this.props;
dispatch({
dispatch!({
type: 'global/changeNoticeReadState',
payload: id,
});
Expand Down Expand Up @@ -133,10 +126,10 @@ export default class GlobalHeaderRight extends Component<GlobalHeaderRightProps>
formatMessage({ id: 'component.globalHeader.search.example3' }),
]}
onSearch={value => {
console.log('input', value); // eslint-disable-line
console.log('input', value); // tslint:disable-line no-console
}}
onPressEnter={value => {
console.log('enter', value); // eslint-disable-line
console.log('enter', value); // tslint:disable-line no-console
}}
/>
<Tooltip title={formatMessage({ id: 'component.globalHeader.help' })}>
Expand All @@ -152,23 +145,23 @@ export default class GlobalHeaderRight extends Component<GlobalHeaderRightProps>

<NoticeIcon
className={styles.action}
count={currentUser.unreadCount}
count={currentUser && currentUser.unreadCount}
onItemClick={(item, tabProps) => {
console.log(item, tabProps); // eslint-disable-line
this.changeReadState(item);
console.log(item, tabProps); // tslint:disable-line no-console
this.changeReadState(item as NoticeItem);
}}
loading={fetchingNotices}
locale={{
emptyText: formatMessage({ id: 'component.noticeIcon.empty' }),
clear: formatMessage({ id: 'component.noticeIcon.clear' }),
viewMore: formatMessage({ id: 'component.noticeIcon.view-more' }), // todo:node_modules/ant-design-pro/lib/NoticeIcon/index.d.ts 21 [key: string]: string;
viewMore: formatMessage({ id: 'component.noticeIcon.view-more' }),
notification: formatMessage({ id: 'component.globalHeader.notification' }),
message: formatMessage({ id: 'component.globalHeader.message' }),
event: formatMessage({ id: 'component.globalHeader.event' }),
}}
onClear={onNoticeClear}
onPopupVisibleChange={onNoticeVisibleChange}
onViewMore={() => message.info('Click on view more')} // todo:onViewMore?: (tabProps: INoticeIconProps) => void;
onViewMore={() => message.info('Click on view more')}
clearClose
>
<NoticeIcon.Tab
Expand Down Expand Up @@ -196,7 +189,7 @@ export default class GlobalHeaderRight extends Component<GlobalHeaderRightProps>
showViewMore
/>
</NoticeIcon>
{currentUser.name ? (
{currentUser && currentUser.name ? (
<HeaderDropdown overlay={menu}>
<span className={`${styles.action} ${styles.account}`}>
<Avatar
Expand Down
24 changes: 14 additions & 10 deletions src/components/GlobalHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,35 @@ import { Icon } from 'antd';
import Link from 'umi/link';
import debounce from 'lodash/debounce';
import styles from './index.less';
import RightContent from './RightContent';
import RightContent, { GlobalHeaderRightProps } from './RightContent';

interface GlobalHeaderProps {
type PartialGlobalHeaderRightProps = {
[K in
| 'onMenuClick'
| 'onNoticeClear'
| 'onNoticeVisibleChange'
| 'currentUser']?: GlobalHeaderRightProps[K]
};

export interface GlobalHeaderProps extends PartialGlobalHeaderRightProps {
collapsed?: boolean;
onCollapse?: (collapsed: boolean) => void;
isMobile?: boolean;
logo?: string;
onNoticeClear?: (type: string) => void;
onMenuClick?: ({ key: string }) => void;
onNoticeVisibleChange?: (b: boolean) => void;
}

export default class GlobalHeader extends Component<GlobalHeaderProps> {
componentWillUnmount() {
this.triggerResizeEvent.cancel();
}
triggerResizeEvent = debounce(() => {
// eslint-disable-line
const event = document.createEvent('HTMLEvents');
event.initEvent('resize', true, false);
window.dispatchEvent(event);
});
componentWillUnmount() {
this.triggerResizeEvent.cancel();
}
toggle = () => {
const { collapsed, onCollapse } = this.props;
onCollapse(!collapsed);
if (onCollapse) onCollapse(!collapsed);
this.triggerResizeEvent();
};
render() {
Expand Down
1 change: 1 addition & 0 deletions src/components/SettingDrawer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ class SettingDrawer extends Component<SettingDrawerProps, SettingDrawerState> {
<List.Item
actions={[
<Switch
key="Switch"
size="small"
checked={!!colorWeak}
onChange={checked => this.changeSetting('colorWeak', checked)}
Expand Down
2 changes: 1 addition & 1 deletion src/components/SiderMenu/SiderMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ export default class SiderMenu extends Component<SiderMenuProps, SiderMenuState>
});
return (
<Sider
collapsible
trigger={null}
collapsible={true}
collapsed={collapsed}
breakpoint="lg"
onCollapse={collapse => {
Expand Down
15 changes: 8 additions & 7 deletions src/components/TopNavHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ClickParam } from 'antd/es/menu';
import React, { Component } from 'react';
import Link from 'umi/link';
import RightContent from '../GlobalHeader/RightContent';
Expand Down Expand Up @@ -32,7 +33,7 @@ interface TopNavHeaderProps {
style?: React.CSSProperties;
onOpenChange?: (openKeys: string[]) => void;
onNoticeClear?: (type: string) => void;
onMenuClick?: ({ key: string }) => void;
onMenuClick?: (param: ClickParam) => void;
onNoticeVisibleChange?: (b: boolean) => void;
}

Expand All @@ -41,18 +42,18 @@ interface TopNavHeaderState {
}

export default class TopNavHeader extends Component<TopNavHeaderProps, TopNavHeaderState> {
state = {
maxWidth: undefined,
};

maim: HTMLDivElement;

static getDerivedStateFromProps(props) {
return {
maxWidth: (props.contentWidth === 'Fixed' ? 1200 : window.innerWidth) - 280 - 165 - 40,
};
}

state = {
maxWidth: undefined,
};

maim: HTMLDivElement;

render() {
const { theme, contentWidth, menuData, logo } = this.props;
const { maxWidth } = this.state;
Expand Down
18 changes: 18 additions & 0 deletions src/components/_utils/pathTools.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'jest';
import { urlToList } from './pathTools';

describe('test urlToList', () => {
it('A path', () => {
expect(urlToList('/userinfo')).toEqual(['/userinfo']);
});
it('Secondary path', () => {
expect(urlToList('/userinfo/2144')).toEqual(['/userinfo', '/userinfo/2144']);
});
it('Three paths', () => {
expect(urlToList('/userinfo/2144/addr')).toEqual([
'/userinfo',
'/userinfo/2144',
'/userinfo/2144/addr',
]);
});
});
2 changes: 1 addition & 1 deletion src/components/_utils/pathTools.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// /userinfo/2144/id => ['/userinfo','/useinfo/2144,'/userindo/2144/id']
// eslint-disable-next-line import/prefer-default-export
export function urlToList(url) {
export function urlToList(url: string) {
const urllist = url.split('/').filter(i => i);
return urllist.map((urlItem, index) => `/${urllist.slice(0, index + 1).join('/')}`);
}
2 changes: 1 addition & 1 deletion src/layouts/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class HeaderView extends Component<HeaderViewProps, HeaderViewState> {
message.success(
`${formatMessage({ id: 'component.noticeIcon.cleared' })} ${formatMessage({
id: `component.globalHeader.${type}`,
})}`
})}`,
);
const { dispatch } = this.props;
dispatch({
Expand Down
Loading