From 1abac6a331218a29f19b2096513ab78628328dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=B0=8F=E8=81=AA?= Date: Mon, 11 Mar 2019 20:29:44 +0800 Subject: [PATCH] [v4] transform typescript (#3702) * merge v3 to v4 * src/components/IconFont * src/components/PageLoading * src/components/SelectLang * src/components/SettingDrawer * remove e2e and test * src/components/TopNavHeader * src/components/GlobalHeader * src/components/HeaderDropdown * src/components/HeaderSearch * src/components/TopNavHeader * fix error * mock * move defaultSettings * global.txs * src/locales * remove lint mock * fix ci test error * change PureComponent to Component, interface IDefaultSettings * Don't prefix interface with I Close: #3706 * strictNullChecks set true --- config/{config.js => config.ts} | 9 +- .../defaultSettings.ts | 22 ++- config/{plugin.config.js => plugin.config.ts} | 0 e2e/baseLayout.e2e.js | 36 ---- e2e/home.e2e.js | 15 -- e2e/topMenu.e2e.js | 18 -- e2e/userLayout.e2e.js | 34 ---- mock/{notices.js => notices.ts} | 0 mock/{route.js => route.ts} | 0 mock/{user.js => user.ts} | 0 package.json | 13 +- src/{app.js => app.ts} | 2 +- .../{RightContent.js => RightContent.tsx} | 40 +++- .../GlobalHeader/{index.js => index.tsx} | 22 ++- src/components/HeaderDropdown/index.d.ts | 2 - src/components/HeaderDropdown/index.js | 13 -- src/components/HeaderDropdown/index.tsx | 22 +++ src/components/HeaderSearch/index.d.ts | 15 -- .../HeaderSearch/{index.js => index.tsx} | 36 ++-- .../IconFont/{index.js => index.tsx} | 4 +- .../PageLoading/{index.js => index.tsx} | 3 +- src/components/SelectLang/index.js | 49 ----- src/components/SelectLang/index.tsx | 51 ++++++ .../{BlockCheckbox.js => BlockCheckbox.tsx} | 7 +- .../{ThemeColor.js => ThemeColor.tsx} | 19 +- .../SettingDrawer/{index.js => index.tsx} | 21 ++- .../SiderMenu/{BaseMenu.js => BaseMenu.tsx} | 46 ++++- src/components/SiderMenu/SiderMenu.test.js | 39 ---- .../SiderMenu/{SiderMenu.js => SiderMenu.tsx} | 54 ++++-- .../{SiderMenuUtils.js => SiderMenuUtils.ts} | 1 + .../SiderMenu/{index.js => index.tsx} | 17 +- .../TopNavHeader/{index.js => index.tsx} | 42 ++++- src/components/_utils/pathTools.test.js | 17 -- .../_utils/{pathTools.js => pathTools.ts} | 0 src/{global.js => global.tsx} | 8 +- src/layouts/BasicLayout.js | 173 ------------------ src/layouts/BasicLayout.tsx | 153 ++++++++++++++++ src/layouts/BlankLayout.js | 3 - src/layouts/BlankLayout.tsx | 9 + src/layouts/{Footer.js => Footer.tsx} | 2 +- src/layouts/{Header.js => Header.tsx} | 42 +++-- .../{MenuContext.js => MenuContext.tsx} | 2 +- src/layouts/{UserLayout.js => UserLayout.tsx} | 26 ++- src/locales/{en-US.js => en-US.ts} | 0 .../en-US/{component.js => component.ts} | 0 .../{globalHeader.js => globalHeader.ts} | 0 src/locales/en-US/{menu.js => menu.ts} | 0 src/locales/en-US/{pwa.js => pwa.ts} | 0 .../{settingDrawer.js => settingDrawer.ts} | 0 .../en-US/{settings.js => settings.ts} | 0 src/locales/{pt-BR.js => pt-BR.ts} | 0 .../pt-BR/{component.js => component.ts} | 0 .../{globalHeader.js => globalHeader.ts} | 0 src/locales/pt-BR/{menu.js => menu.ts} | 0 src/locales/pt-BR/{pwa.js => pwa.ts} | 0 .../{settingDrawer.js => settingDrawer.ts} | 0 .../pt-BR/{settings.js => settings.ts} | 0 src/locales/{zh-CN.js => zh-CN.ts} | 0 .../zh-CN/{component.js => component.ts} | 0 .../{globalHeader.js => globalHeader.ts} | 0 src/locales/zh-CN/{menu.js => menu.ts} | 0 src/locales/zh-CN/{pwa.js => pwa.ts} | 0 .../{settingDrawer.js => settingDrawer.ts} | 0 .../zh-CN/{settings.js => settings.ts} | 0 src/locales/{zh-TW.js => zh-TW.ts} | 0 .../zh-TW/{component.js => component.ts} | 0 .../{globalHeader.js => globalHeader.ts} | 0 src/locales/zh-TW/{menu.js => menu.ts} | 0 src/locales/zh-TW/{pwa.js => pwa.ts} | 0 .../{settingDrawer.js => settingDrawer.ts} | 0 .../zh-TW/{settings.js => settings.ts} | 0 src/models/{global.js => global.ts} | 31 +++- src/models/{menu.js => menu.ts} | 55 ++++-- src/models/{setting.js => setting.ts} | 28 ++- src/models/{user.js => user.ts} | 34 +++- src/pages/Authorized.js | 44 ----- src/pages/Authorized.tsx | 45 +++++ src/pages/{Welcome.js => Welcome.tsx} | 0 src/services/{user.js => user.ts} | 6 +- src/typings.d.ts | 12 ++ src/utils/{Authorized.js => Authorized.ts} | 0 .../{authority.test.js => authority.test.ts} | 1 + src/utils/{authority.js => authority.ts} | 4 +- .../{getPageTitle.js => getPageTitle.ts} | 21 ++- src/utils/{request.js => request.ts} | 0 src/utils/utils.test.js | 38 ---- src/utils/{utils.js => utils.ts} | 0 tsconfig.json | 5 +- tslint.json | 4 +- 89 files changed, 772 insertions(+), 643 deletions(-) rename config/{config.js => config.ts} (95%) rename src/defaultSettings.js => config/defaultSettings.ts (60%) rename config/{plugin.config.js => plugin.config.ts} (100%) delete mode 100644 e2e/baseLayout.e2e.js delete mode 100644 e2e/home.e2e.js delete mode 100644 e2e/topMenu.e2e.js delete mode 100644 e2e/userLayout.e2e.js rename mock/{notices.js => notices.ts} (100%) rename mock/{route.js => route.ts} (100%) rename mock/{user.js => user.ts} (100%) rename src/{app.js => app.ts} (96%) rename src/components/GlobalHeader/{RightContent.js => RightContent.tsx} (83%) rename src/components/GlobalHeader/{index.js => index.tsx} (67%) delete mode 100644 src/components/HeaderDropdown/index.d.ts delete mode 100644 src/components/HeaderDropdown/index.js create mode 100644 src/components/HeaderDropdown/index.tsx delete mode 100644 src/components/HeaderSearch/index.d.ts rename src/components/HeaderSearch/{index.js => index.tsx} (83%) rename src/components/IconFont/{index.js => index.tsx} (59%) rename src/components/PageLoading/{index.js => index.tsx} (79%) delete mode 100644 src/components/SelectLang/index.js create mode 100644 src/components/SelectLang/index.tsx rename src/components/SettingDrawer/{BlockCheckbox.js => BlockCheckbox.tsx} (77%) rename src/components/SettingDrawer/{ThemeColor.js => ThemeColor.tsx} (76%) rename src/components/SettingDrawer/{index.js => index.tsx} (92%) rename src/components/SiderMenu/{BaseMenu.js => BaseMenu.tsx} (80%) delete mode 100644 src/components/SiderMenu/SiderMenu.test.js rename src/components/SiderMenu/{SiderMenu.js => SiderMenu.tsx} (72%) rename src/components/SiderMenu/{SiderMenuUtils.js => SiderMenuUtils.ts} (99%) rename src/components/SiderMenu/{index.js => index.tsx} (65%) rename src/components/TopNavHeader/{index.js => index.tsx} (56%) delete mode 100644 src/components/_utils/pathTools.test.js rename src/components/_utils/{pathTools.js => pathTools.ts} (100%) rename src/{global.js => global.tsx} (90%) delete mode 100644 src/layouts/BasicLayout.js create mode 100644 src/layouts/BasicLayout.tsx delete mode 100644 src/layouts/BlankLayout.js create mode 100644 src/layouts/BlankLayout.tsx rename src/layouts/{Footer.js => Footer.tsx} (96%) rename src/layouts/{Header.js => Header.tsx} (86%) rename src/layouts/{MenuContext.js => MenuContext.tsx} (54%) rename src/layouts/{UserLayout.js => UserLayout.tsx} (89%) rename src/locales/{en-US.js => en-US.ts} (100%) rename src/locales/en-US/{component.js => component.ts} (100%) rename src/locales/en-US/{globalHeader.js => globalHeader.ts} (100%) rename src/locales/en-US/{menu.js => menu.ts} (100%) rename src/locales/en-US/{pwa.js => pwa.ts} (100%) rename src/locales/en-US/{settingDrawer.js => settingDrawer.ts} (100%) rename src/locales/en-US/{settings.js => settings.ts} (100%) rename src/locales/{pt-BR.js => pt-BR.ts} (100%) rename src/locales/pt-BR/{component.js => component.ts} (100%) rename src/locales/pt-BR/{globalHeader.js => globalHeader.ts} (100%) rename src/locales/pt-BR/{menu.js => menu.ts} (100%) rename src/locales/pt-BR/{pwa.js => pwa.ts} (100%) rename src/locales/pt-BR/{settingDrawer.js => settingDrawer.ts} (100%) rename src/locales/pt-BR/{settings.js => settings.ts} (100%) rename src/locales/{zh-CN.js => zh-CN.ts} (100%) rename src/locales/zh-CN/{component.js => component.ts} (100%) rename src/locales/zh-CN/{globalHeader.js => globalHeader.ts} (100%) rename src/locales/zh-CN/{menu.js => menu.ts} (100%) rename src/locales/zh-CN/{pwa.js => pwa.ts} (100%) rename src/locales/zh-CN/{settingDrawer.js => settingDrawer.ts} (100%) rename src/locales/zh-CN/{settings.js => settings.ts} (100%) rename src/locales/{zh-TW.js => zh-TW.ts} (100%) rename src/locales/zh-TW/{component.js => component.ts} (100%) rename src/locales/zh-TW/{globalHeader.js => globalHeader.ts} (100%) rename src/locales/zh-TW/{menu.js => menu.ts} (100%) rename src/locales/zh-TW/{pwa.js => pwa.ts} (100%) rename src/locales/zh-TW/{settingDrawer.js => settingDrawer.ts} (100%) rename src/locales/zh-TW/{settings.js => settings.ts} (100%) rename src/models/{global.js => global.ts} (76%) rename src/models/{menu.js => menu.ts} (68%) rename src/models/{setting.js => setting.ts} (83%) rename src/models/{user.js => user.ts} (61%) delete mode 100644 src/pages/Authorized.js create mode 100644 src/pages/Authorized.tsx rename src/pages/{Welcome.js => Welcome.tsx} (100%) rename src/services/{user.js => user.ts} (50%) create mode 100644 src/typings.d.ts rename src/utils/{Authorized.js => Authorized.ts} (100%) rename src/utils/{authority.test.js => authority.test.ts} (97%) rename src/utils/{authority.js => authority.ts} (86%) rename src/utils/{getPageTitle.js => getPageTitle.ts} (58%) rename src/utils/{request.js => request.ts} (100%) delete mode 100644 src/utils/utils.test.js rename src/utils/{utils.js => utils.ts} (100%) diff --git a/config/config.js b/config/config.ts similarity index 95% rename from config/config.js rename to config/config.ts index a86d1efd..ea5ba918 100644 --- a/config/config.js +++ b/config/config.ts @@ -1,13 +1,14 @@ // https://umijs.org/config/ import os from 'os'; -import webpackPlugin from './plugin.config'; -import defaultSettings from '../src/defaultSettings'; import slash from 'slash2'; +import { IPlugin } from 'umi-types'; +import defaultSettings from './defaultSettings'; +import webpackPlugin from './plugin.config'; const { pwa, primaryColor } = defaultSettings; -const { NODE_ENV, APP_TYPE, TEST } = process.env; +const { APP_TYPE, TEST } = process.env; -const plugins = [ +const plugins: IPlugin[] = [ [ 'umi-plugin-react', { diff --git a/src/defaultSettings.js b/config/defaultSettings.ts similarity index 60% rename from src/defaultSettings.js rename to config/defaultSettings.ts index 4ba7eb39..9aa47e02 100644 --- a/src/defaultSettings.js +++ b/config/defaultSettings.ts @@ -1,4 +1,21 @@ -module.exports = { +export declare type SiderTheme = 'light' | 'dark'; + +export interface DefaultSettings { + navTheme: string | SiderTheme; + primaryColor: string; + layout: string; + contentWidth: string; + fixedHeader: boolean; + autoHideHeader: boolean; + fixSiderbar: boolean; + menu: { disableLocal: boolean }; + title: string; + pwa: boolean; + iconfontUrl: string; + colorWeak: boolean; +} + +export default { navTheme: 'dark', // theme for nav menu primaryColor: '#1890FF', // primary color of ant design layout: 'sidemenu', // nav menu position: sidemenu or topmenu @@ -6,6 +23,7 @@ module.exports = { fixedHeader: false, // sticky header autoHideHeader: false, // auto hide header fixSiderbar: false, // sticky siderbar + colorWeak: false, menu: { disableLocal: false, }, @@ -15,4 +33,4 @@ module.exports = { // eg://at.alicdn.com/t/font_1039637_btcrd5co4w.js // 注意:如果需要图标多色,Iconfont图标项目里要进行批量去色处理 iconfontUrl: '', -}; +} as DefaultSettings; diff --git a/config/plugin.config.js b/config/plugin.config.ts similarity index 100% rename from config/plugin.config.js rename to config/plugin.config.ts diff --git a/e2e/baseLayout.e2e.js b/e2e/baseLayout.e2e.js deleted file mode 100644 index 456861f9..00000000 --- a/e2e/baseLayout.e2e.js +++ /dev/null @@ -1,36 +0,0 @@ -import config from '../config/config'; - -const RouterConfig = config.routes; - -const BASE_URL = `http://localhost:${process.env.PORT || 8000}`; - -function formatter(data) { - return data - .reduce((pre, item) => { - pre.push(item.path); - return pre; - }, []) - .filter(item => item); -} - -describe('Homepage', async () => { - const testPage = path => async () => { - await page.goto(`${BASE_URL}${path}`); - await page.waitForSelector('footer', { - timeout: 2000, - }); - const haveFooter = await page.evaluate( - () => document.getElementsByTagName('footer').length > 0 - ); - expect(haveFooter).toBeTruthy(); - }; - - beforeAll(async () => { - jest.setTimeout(1000000); - await page.setCacheEnabled(false); - }); - const routers = formatter(RouterConfig[1].routes); - routers.forEach(route => { - it(`test pages ${route}`, testPage(route)); - }); -}); diff --git a/e2e/home.e2e.js b/e2e/home.e2e.js deleted file mode 100644 index 0531d5f4..00000000 --- a/e2e/home.e2e.js +++ /dev/null @@ -1,15 +0,0 @@ -const BASE_URL = `http://localhost:${process.env.PORT || 8000}`; - -describe('Homepage', () => { - beforeAll(async () => { - jest.setTimeout(1000000); - }); - it('it should have logo text', async () => { - await page.goto(BASE_URL); - await page.waitForSelector('h1', { - timeout: 5000, - }); - const text = await page.evaluate(() => document.getElementsByTagName('h1')[0].innerText); - expect(text).toContain('Ant Design Pro'); - }); -}); diff --git a/e2e/topMenu.e2e.js b/e2e/topMenu.e2e.js deleted file mode 100644 index 51ff9f35..00000000 --- a/e2e/topMenu.e2e.js +++ /dev/null @@ -1,18 +0,0 @@ -const BASE_URL = `http://localhost:${process.env.PORT || 8000}`; - -describe('Homepage', () => { - beforeAll(async () => { - jest.setTimeout(1000000); - }); - it('topmenu should have footer', async () => { - const params = '/form/basic-form?navTheme=light&layout=topmenu'; - await page.goto(`${BASE_URL}${params}`); - await page.waitForSelector('footer', { - timeout: 2000, - }); - const haveFooter = await page.evaluate( - () => document.getElementsByTagName('footer').length > 0 - ); - expect(haveFooter).toBeTruthy(); - }); -}); diff --git a/e2e/userLayout.e2e.js b/e2e/userLayout.e2e.js deleted file mode 100644 index 14b60416..00000000 --- a/e2e/userLayout.e2e.js +++ /dev/null @@ -1,34 +0,0 @@ -import config from '../config/config'; - -const RouterConfig = config.routes; - -const BASE_URL = `http://localhost:${process.env.PORT || 8000}`; - -function formatter(data) { - return data - .reduce((pre, item) => { - pre.push(item.path); - return pre; - }, []) - .filter(item => item); -} - -describe('Homepage', () => { - const testPage = path => async () => { - await page.goto(`${BASE_URL}${path}`); - await page.waitForSelector('footer', { - timeout: 2000, - }); - const haveFooter = await page.evaluate( - () => document.getElementsByTagName('footer').length > 0 - ); - expect(haveFooter).toBeTruthy(); - }; - - beforeAll(async () => { - jest.setTimeout(1000000); - }); - formatter(RouterConfig[0].routes).forEach(route => { - it(`test pages ${route}`, testPage(route)); - }); -}); diff --git a/mock/notices.js b/mock/notices.ts similarity index 100% rename from mock/notices.js rename to mock/notices.ts diff --git a/mock/route.js b/mock/route.ts similarity index 100% rename from mock/route.js rename to mock/route.ts diff --git a/mock/user.js b/mock/user.ts similarity index 100% rename from mock/user.js rename to mock/user.ts diff --git a/package.json b/package.json index 551ef36f..82256900 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,8 @@ "analyze": "cross-env ANALYZE=1 umi build", "lint:style": "stylelint 'src/**/*.less' --syntax less", "lint:prettier": "check-prettier lint", - "lint": "eslint --ext .js src mock tests && npm run lint:style && npm run lint:prettier", - "lint:fix": "eslint --fix --ext .js src mock tests && stylelint --fix 'src/**/*.less' --syntax less", + "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-staged": "lint-staged", "lint-staged:js": "eslint --ext .js", "test": "umi test", @@ -47,9 +47,12 @@ "react-copy-to-clipboard": "^5.0.1", "react-document-title": "^2.0.3", "react-media": "^1.8.0", - "umi-request": "^1.0.0" + "react-media-hook2": "^1.0.2", + "umi-request": "^1.0.0", + "umi-types": "^0.2.0" }, "devDependencies": { + "@types/jest": "^24.0.11", "@types/react": "^16.8.1", "@types/react-dom": "^16.0.11", "antd-pro-merge-less": "^1.0.0", @@ -90,8 +93,8 @@ "tslint-react": "^3.6.0", "umi": "^2.4.4", "umi-plugin-ga": "^1.1.3", - "umi-plugin-react": "^1.3.4", - "umi-plugin-pro-block": "^1.2.0" + "umi-plugin-pro-block": "^1.2.0", + "umi-plugin-react": "^1.3.4" }, "optionalDependencies": { "puppeteer": "^1.12.1" diff --git a/src/app.js b/src/app.ts similarity index 96% rename from src/app.js rename to src/app.ts index 0f35ff9a..22236327 100644 --- a/src/app.js +++ b/src/app.ts @@ -26,7 +26,7 @@ export function patchRoutes(routes) { Object.keys(authRoutes).map(authKey => ergodicRoutes(routes, authKey, authRoutes[authKey].authority) ); - window.g_routes = routes; + (window as any).g_routes = routes; } export function render(oldRender) { diff --git a/src/components/GlobalHeader/RightContent.js b/src/components/GlobalHeader/RightContent.tsx similarity index 83% rename from src/components/GlobalHeader/RightContent.js rename to src/components/GlobalHeader/RightContent.tsx index dc63084c..0d768987 100644 --- a/src/components/GlobalHeader/RightContent.js +++ b/src/components/GlobalHeader/RightContent.tsx @@ -1,6 +1,7 @@ -import React, { PureComponent } from 'react'; -import { FormattedMessage, formatMessage } from 'umi/locale'; +import React, { Component } from 'react'; +import { FormattedMessage, formatMessage } from 'umi-plugin-locale'; import { Spin, Tag, Menu, Icon, Avatar, Tooltip, message } from 'antd'; +import { ClickParam } from 'antd/es/menu'; import moment from 'moment'; import groupBy from 'lodash/groupBy'; import { NoticeIcon } from 'ant-design-pro'; @@ -9,7 +10,29 @@ import HeaderDropdown from '../HeaderDropdown'; import SelectLang from '../SelectLang'; import styles from './index.less'; -export default class GlobalHeaderRight extends PureComponent { +export declare 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; + }; + fetchingNotices?: boolean; + onNoticeVisibleChange?: (visible: boolean) => void; + onMenuClick?: (param: ClickParam) => void; + onNoticeClear?: (tabName: string) => void; + theme?: SiderTheme; +} +export default class GlobalHeaderRight extends Component { getNoticeData() { const { notices = [] } = this.props; if (notices.length === 0) { @@ -41,7 +64,7 @@ export default class GlobalHeaderRight extends PureComponent { return groupBy(newNotices, 'type'); } - getUnreadData = noticeData => { + getUnreadData: (noticeData: object) => any = noticeData => { const unreadMsg = {}; Object.entries(noticeData).forEach(([key, value]) => { if (!unreadMsg[key]) { @@ -126,25 +149,26 @@ export default class GlobalHeaderRight extends PureComponent { + { console.log(item, tabProps); // eslint-disable-line - this.changeReadState(item, tabProps); + this.changeReadState(item); }} loading={fetchingNotices} locale={{ emptyText: formatMessage({ id: 'component.noticeIcon.empty' }), clear: formatMessage({ id: 'component.noticeIcon.clear' }), - viewMore: formatMessage({ id: 'component.noticeIcon.view-more' }), + viewMore: formatMessage({ id: 'component.noticeIcon.view-more' }), // todo:node_modules/ant-design-pro/lib/NoticeIcon/index.d.ts 21 [key: string]: string; 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')} + onViewMore={() => message.info('Click on view more')} // todo:onViewMore?: (tabProps: INoticeIconProps) => void; clearClose > void; + isMobile?: boolean; + logo?: string; + onNoticeClear?: (type: string) => void; + onMenuClick?: ({ key: string }) => void; + onNoticeVisibleChange?: (b: boolean) => void; +} + +export default class GlobalHeader extends Component { componentWillUnmount() { this.triggerResizeEvent.cancel(); } - /* eslint-disable*/ - @Debounce(600) - triggerResizeEvent() { + triggerResizeEvent = debounce(() => { // eslint-disable-line const event = document.createEvent('HTMLEvents'); event.initEvent('resize', true, false); window.dispatchEvent(event); - } + }); toggle = () => { const { collapsed, onCollapse } = this.props; onCollapse(!collapsed); diff --git a/src/components/HeaderDropdown/index.d.ts b/src/components/HeaderDropdown/index.d.ts deleted file mode 100644 index e9dac7e5..00000000 --- a/src/components/HeaderDropdown/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import * as React from 'react'; -export default class HeaderDropdown extends React.Component {} diff --git a/src/components/HeaderDropdown/index.js b/src/components/HeaderDropdown/index.js deleted file mode 100644 index a19c471a..00000000 --- a/src/components/HeaderDropdown/index.js +++ /dev/null @@ -1,13 +0,0 @@ -import React, { PureComponent } from 'react'; -import { Dropdown } from 'antd'; -import classNames from 'classnames'; -import styles from './index.less'; - -export default class HeaderDropdown extends PureComponent { - render() { - const { overlayClassName, ...props } = this.props; - return ( - - ); - } -} diff --git a/src/components/HeaderDropdown/index.tsx b/src/components/HeaderDropdown/index.tsx new file mode 100644 index 00000000..b311061b --- /dev/null +++ b/src/components/HeaderDropdown/index.tsx @@ -0,0 +1,22 @@ +import React, { Component } from 'react'; +import { Dropdown } from 'antd'; +import classNames from 'classnames'; +import styles from './index.less'; + +declare type OverlayFunc = () => React.ReactNode; + +interface HeaderDropdownProps { + overlayClassName?: string; + overlay: React.ReactNode | OverlayFunc; + placement?: 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topCenter' | 'topRight' | 'bottomCenter'; +} + +export default class HeaderDropdown extends Component { + render() { + const { overlayClassName, ...props } = this.props; + + return ( + + ); + } +} diff --git a/src/components/HeaderSearch/index.d.ts b/src/components/HeaderSearch/index.d.ts deleted file mode 100644 index d78fde47..00000000 --- a/src/components/HeaderSearch/index.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from 'react'; -export interface IHeaderSearchProps { - placeholder?: string; - dataSource?: string[]; - defaultOpen?: boolean; - open?: boolean; - onSearch?: (value: string) => void; - onChange?: (value: string) => void; - onVisibleChange?: (visible: boolean) => void; - onPressEnter?: (value: string) => void; - style?: React.CSSProperties; - className?: string; -} - -export default class HeaderSearch extends React.Component {} diff --git a/src/components/HeaderSearch/index.js b/src/components/HeaderSearch/index.tsx similarity index 83% rename from src/components/HeaderSearch/index.js rename to src/components/HeaderSearch/index.tsx index 04f8b38e..34de1db7 100644 --- a/src/components/HeaderSearch/index.js +++ b/src/components/HeaderSearch/index.tsx @@ -1,24 +1,30 @@ -import React, { PureComponent } from 'react'; -import PropTypes from 'prop-types'; +import React, { Component } from 'react'; import { Input, Icon, AutoComplete } from 'antd'; +import InputProps from 'antd/es/input'; + import classNames from 'classnames'; import Debounce from 'lodash-decorators/debounce'; import Bind from 'lodash-decorators/bind'; import styles from './index.less'; -export default class HeaderSearch extends PureComponent { - static propTypes = { - className: PropTypes.string, - placeholder: PropTypes.string, - onSearch: PropTypes.func, - onChange: PropTypes.func, - onPressEnter: PropTypes.func, - defaultActiveFirstOption: PropTypes.bool, - dataSource: PropTypes.array, - defaultOpen: PropTypes.bool, - onVisibleChange: PropTypes.func, - }; +interface HeaderSearchProps { + onPressEnter: (value: string) => void; + onSearch: (value: string) => void; + onChange: (value: string) => void; + onVisibleChange: (b: boolean) => void; + className: string; + placeholder: string; + defaultActiveFirstOption: boolean; + dataSource: any[]; + defaultOpen: boolean; + open?: boolean; +} +interface HeaderSearchState { + value: string; + searchMode: boolean; +} +export default class HeaderSearch extends Component { static defaultProps = { defaultActiveFirstOption: false, onPressEnter: () => {}, @@ -40,6 +46,8 @@ export default class HeaderSearch extends PureComponent { return null; } + timeout: NodeJS.Timeout; + input: InputProps; constructor(props) { super(props); this.state = { diff --git a/src/components/IconFont/index.js b/src/components/IconFont/index.tsx similarity index 59% rename from src/components/IconFont/index.js rename to src/components/IconFont/index.tsx index 0b99dec3..c438b44a 100644 --- a/src/components/IconFont/index.js +++ b/src/components/IconFont/index.tsx @@ -1,6 +1,8 @@ import { Icon } from 'antd'; -import { iconfontUrl as scriptUrl } from '../../defaultSettings'; +import defaultSettings from '../../../config/defaultSettings'; +const { iconfontUrl } = defaultSettings; +const scriptUrl = iconfontUrl; // 使用: // import IconFont from '@/components/IconFont'; // diff --git a/src/components/PageLoading/index.js b/src/components/PageLoading/index.tsx similarity index 79% rename from src/components/PageLoading/index.js rename to src/components/PageLoading/index.tsx index 77c0f165..24160279 100644 --- a/src/components/PageLoading/index.js +++ b/src/components/PageLoading/index.tsx @@ -3,8 +3,9 @@ import { Spin } from 'antd'; // loading components from code split // https://umijs.org/plugin/umi-plugin-react.html#dynamicimport -export default () => ( +const PageLoding: React.SFC = () => (
); +export default PageLoding; diff --git a/src/components/SelectLang/index.js b/src/components/SelectLang/index.js deleted file mode 100644 index f6abe2f2..00000000 --- a/src/components/SelectLang/index.js +++ /dev/null @@ -1,49 +0,0 @@ -import React, { PureComponent } from 'react'; -import { formatMessage, setLocale, getLocale } from 'umi/locale'; -import { Menu, Icon } from 'antd'; -import classNames from 'classnames'; -import HeaderDropdown from '../HeaderDropdown'; -import styles from './index.less'; - -export default class SelectLang extends PureComponent { - changeLang = ({ key }) => { - setLocale(key); - }; - - render() { - const { className } = this.props; - const selectedLang = getLocale(); - const locales = ['zh-CN', 'zh-TW', 'en-US', 'pt-BR']; - const languageLabels = { - 'zh-CN': '简体中文', - 'zh-TW': '繁体中文', - 'en-US': 'English', - 'pt-BR': 'Português', - }; - const languageIcons = { - 'zh-CN': '🇨🇳', - 'zh-TW': '🇭🇰', - 'en-US': '🇬🇧', - 'pt-BR': '🇧🇷', - }; - const langMenu = ( - - {locales.map(locale => ( - - - {languageIcons[locale]} - {' '} - {languageLabels[locale]} - - ))} - - ); - return ( - - - - - - ); - } -} diff --git a/src/components/SelectLang/index.tsx b/src/components/SelectLang/index.tsx new file mode 100644 index 00000000..b145e39b --- /dev/null +++ b/src/components/SelectLang/index.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import { formatMessage, setLocale, getLocale } from 'umi-plugin-locale'; +import { Menu, Icon } from 'antd'; +import classNames from 'classnames'; +import HeaderDropdown from '../HeaderDropdown'; +import styles from './index.less'; + +interface SelectLangProps { + className?: string; +} +const SelectLang: React.SFC = props => { + const { className } = props; + const selectedLang = getLocale(); + const changeLang = ({ key }) => { + setLocale(key); + }; + const locales = ['zh-CN', 'zh-TW', 'en-US', 'pt-BR']; + const languageLabels = { + 'zh-CN': '简体中文', + 'zh-TW': '繁体中文', + 'en-US': 'English', + 'pt-BR': 'Português', + }; + const languageIcons = { + 'zh-CN': '🇨🇳', + 'zh-TW': '🇭🇰', + 'en-US': '🇬🇧', + 'pt-BR': '🇧🇷', + }; + const langMenu = ( + + {locales.map(locale => ( + + + {languageIcons[locale]} + {' '} + {languageLabels[locale]} + + ))} + + ); + return ( + + + + + + ); +}; + +export default SelectLang; diff --git a/src/components/SettingDrawer/BlockCheckbox.js b/src/components/SettingDrawer/BlockCheckbox.tsx similarity index 77% rename from src/components/SettingDrawer/BlockCheckbox.js rename to src/components/SettingDrawer/BlockCheckbox.tsx index 49af42c7..84800f89 100644 --- a/src/components/SettingDrawer/BlockCheckbox.js +++ b/src/components/SettingDrawer/BlockCheckbox.tsx @@ -2,7 +2,12 @@ import React from 'react'; import { Tooltip, Icon } from 'antd'; import style from './index.less'; -const BlockChecbox = ({ value, onChange, list }) => ( +interface BlockChecboxProps { + value: string; + onChange: (key: string) => void; + list: any[]; +} +const BlockChecbox: React.SFC = ({ value, onChange, list }) => (
{list.map(item => ( diff --git a/src/components/SettingDrawer/ThemeColor.js b/src/components/SettingDrawer/ThemeColor.tsx similarity index 76% rename from src/components/SettingDrawer/ThemeColor.js rename to src/components/SettingDrawer/ThemeColor.tsx index e5d66d4b..ac6cd2bb 100644 --- a/src/components/SettingDrawer/ThemeColor.js +++ b/src/components/SettingDrawer/ThemeColor.tsx @@ -1,9 +1,15 @@ import React from 'react'; import { Tooltip, Icon } from 'antd'; -import { formatMessage } from 'umi/locale'; +import { formatMessage } from 'umi-plugin-locale'; import styles from './ThemeColor.less'; -const Tag = ({ color, check, ...rest }) => ( +interface TagProps { + color: string; + check: boolean; + className?: string; + onClick?: () => void; +} +const Tag: React.SFC = ({ color, check, ...rest }) => (
(
); -const ThemeColor = ({ colors, title, value, onChange }) => { +interface ThemeColorProps { + colors?: any[]; + title?: string; + value: string; + onChange: (color: string) => void; +} + +const ThemeColor: React.SFC = ({ colors, title, value, onChange }) => { let colorList = colors; if (!colors) { colorList = [ diff --git a/src/components/SettingDrawer/index.js b/src/components/SettingDrawer/index.tsx similarity index 92% rename from src/components/SettingDrawer/index.js rename to src/components/SettingDrawer/index.tsx index cdb28aa3..d4932d96 100644 --- a/src/components/SettingDrawer/index.js +++ b/src/components/SettingDrawer/index.tsx @@ -1,16 +1,21 @@ -import React, { PureComponent } from 'react'; +import React, { Component } from 'react'; import { Select, message, Drawer, List, Switch, Divider, Icon, Button, Alert, Tooltip } from 'antd'; -import { formatMessage } from 'umi/locale'; +import { formatMessage } from 'umi-plugin-locale'; import { CopyToClipboard } from 'react-copy-to-clipboard'; import { connect } from 'dva'; import omit from 'omit.js'; import styles from './index.less'; import ThemeColor from './ThemeColor'; import BlockCheckbox from './BlockCheckbox'; +import { DefaultSettings } from '../../../config/defaultSettings'; const { Option } = Select; +interface BodyProps { + title: string; + style?: React.CSSProperties; +} -const Body = ({ children, title, style }) => ( +const Body: React.SFC = ({ children, title, style }) => (
(
); +interface SettingDrawerProps { + setting?: DefaultSettings; + dispatch?: (args: any) => void; +} +interface SettingDrawerState {} + @connect(({ setting }) => ({ setting })) -class SettingDrawer extends PureComponent { +class SettingDrawer extends Component { state = { collapse: false, }; @@ -120,7 +131,7 @@ class SettingDrawer extends PureComponent { return ( - {item.title} + {item.title} ); diff --git a/src/components/SiderMenu/BaseMenu.js b/src/components/SiderMenu/BaseMenu.tsx similarity index 80% rename from src/components/SiderMenu/BaseMenu.js rename to src/components/SiderMenu/BaseMenu.tsx index 9ab66ec3..991f03cf 100644 --- a/src/components/SiderMenu/BaseMenu.js +++ b/src/components/SiderMenu/BaseMenu.tsx @@ -1,12 +1,13 @@ -import React, { PureComponent } from 'react'; +import IconFont from '@/components/IconFont'; +import { isUrl } from '@/utils/utils'; +import { Icon, Menu } from 'antd'; import classNames from 'classnames'; -import { Menu, Icon } from 'antd'; +import * as H from 'history'; +import React, { Component } from 'react'; import Link from 'umi/link'; import { urlToList } from '../_utils/pathTools'; -import { getMenuMatches } from './SiderMenuUtils'; -import { isUrl } from '@/utils/utils'; import styles from './index.less'; -import IconFont from '@/components/IconFont'; +import { getMenuMatches } from './SiderMenuUtils'; const { SubMenu } = Menu; @@ -28,12 +29,39 @@ const getIcon = icon => { return icon; }; -export default class BaseMenu extends PureComponent { +export declare type CollapseType = 'clickTrigger' | 'responsive'; +export declare type SiderTheme = 'light' | 'dark'; +export declare type MenuMode = + | 'vertical' + | 'vertical-left' + | 'vertical-right' + | 'horizontal' + | 'inline'; + +interface BaseMenuProps { + flatMenuKeys?: any[]; + location?: H.Location; + onCollapse?: (collapsed: boolean, type?: CollapseType) => void; + isMobile?: boolean; + openKeys?: any; + theme?: SiderTheme; + mode?: MenuMode; + className?: string; + collapsed?: boolean; + handleOpenChange?: (openKeys: any[]) => void; + menuData?: any[]; + style?: React.CSSProperties; + onOpenChange?: (openKeys: string[]) => void; +} + +interface BaseMenuState {} + +export default class BaseMenu extends Component { /** * 获得菜单子节点 * @memberof SiderMenu */ - getNavMenuItems = menusData => { + getNavMenuItems: (menusData: any[]) => any[] = menusData => { if (!menusData) { return []; } @@ -131,6 +159,9 @@ export default class BaseMenu extends PureComponent { location: { pathname }, className, collapsed, + handleOpenChange, + style, + menuData, } = this.props; // if pathname can't match, use the nearest parent's key let selectedKeys = this.getSelectedMenuKeys(pathname); @@ -143,7 +174,6 @@ export default class BaseMenu extends PureComponent { openKeys: openKeys.length === 0 ? [...selectedKeys] : openKeys, }; } - const { handleOpenChange, style, menuData } = this.props; const cls = classNames(className, { 'top-nav-menu': mode === 'horizontal', }); diff --git a/src/components/SiderMenu/SiderMenu.test.js b/src/components/SiderMenu/SiderMenu.test.js deleted file mode 100644 index 3d280da0..00000000 --- a/src/components/SiderMenu/SiderMenu.test.js +++ /dev/null @@ -1,39 +0,0 @@ -import { getFlatMenuKeys } from './SiderMenuUtils'; - -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', - ]); - }); -}); diff --git a/src/components/SiderMenu/SiderMenu.js b/src/components/SiderMenu/SiderMenu.tsx similarity index 72% rename from src/components/SiderMenu/SiderMenu.js rename to src/components/SiderMenu/SiderMenu.tsx index da9520fa..8a55f897 100644 --- a/src/components/SiderMenu/SiderMenu.js +++ b/src/components/SiderMenu/SiderMenu.tsx @@ -1,29 +1,39 @@ -import React, { PureComponent, Suspense } from 'react'; import { Layout } from 'antd'; import classNames from 'classnames'; +import * as H from 'history'; +import React, { Component, Suspense } from 'react'; import Link from 'umi/link'; -import styles from './index.less'; +import defaultSettings from '../../../config/defaultSettings'; import PageLoading from '../PageLoading'; +import styles from './index.less'; import { getDefaultCollapsedSubMenus } from './SiderMenuUtils'; -import { title } from '../../defaultSettings'; const BaseMenu = React.lazy(() => import('./BaseMenu')); const { Sider } = Layout; +const { title } = defaultSettings; +let firstMount: boolean = true; -let firstMount = true; +export declare type CollapseType = 'clickTrigger' | 'responsive'; +export declare type SiderTheme = 'light' | 'dark'; -export default class SiderMenu extends PureComponent { - constructor(props) { - super(props); - this.state = { - openKeys: getDefaultCollapsedSubMenus(props), - }; - } +interface SiderMenuProps { + menuData: any[]; + location?: H.Location; + flatMenuKeys?: any[]; + logo?: string; + collapsed: boolean; + onCollapse: (collapsed: boolean, type?: CollapseType) => void; + fixSiderbar?: boolean; + theme?: SiderTheme; + isMobile: boolean; +} - componentDidMount() { - firstMount = false; - } +interface SiderMenuState { + openKeys: any; + flatMenuKeysLen?: number; +} +export default class SiderMenu extends Component { static getDerivedStateFromProps(props, state) { const { pathname, flatMenuKeysLen } = state; if (props.location.pathname !== pathname || props.flatMenuKeys.length !== flatMenuKeysLen) { @@ -35,8 +45,18 @@ export default class SiderMenu extends PureComponent { } return null; } + constructor(props: SiderMenuProps) { + super(props); + this.state = { + openKeys: getDefaultCollapsedSubMenus(props), + }; + } + + componentDidMount() { + firstMount = false; + } - isMainMenu = key => { + isMainMenu: (key: string) => boolean = key => { const { menuData } = this.props; return menuData.some(item => { if (key) { @@ -46,7 +66,7 @@ export default class SiderMenu extends PureComponent { }); }; - handleOpenChange = openKeys => { + handleOpenChange: (openKeys: any[]) => void = openKeys => { const moreThanOne = openKeys.filter(openKey => this.isMainMenu(openKey)).length > 1; this.setState({ openKeys: moreThanOne ? [openKeys.pop()] : [...openKeys], @@ -65,7 +85,7 @@ export default class SiderMenu extends PureComponent { return ( { diff --git a/src/components/SiderMenu/SiderMenuUtils.js b/src/components/SiderMenu/SiderMenuUtils.ts similarity index 99% rename from src/components/SiderMenu/SiderMenuUtils.js rename to src/components/SiderMenu/SiderMenuUtils.ts index 6e04ec13..0c398b88 100644 --- a/src/components/SiderMenu/SiderMenuUtils.js +++ b/src/components/SiderMenu/SiderMenuUtils.ts @@ -24,6 +24,7 @@ export const getMenuMatches = (flatMenuKeys, path) => } return false; }); + /** * 获得菜单子节点 * @memberof SiderMenu diff --git a/src/components/SiderMenu/index.js b/src/components/SiderMenu/index.tsx similarity index 65% rename from src/components/SiderMenu/index.js rename to src/components/SiderMenu/index.tsx index 0be27331..9716eb74 100644 --- a/src/components/SiderMenu/index.js +++ b/src/components/SiderMenu/index.tsx @@ -3,7 +3,18 @@ import { Drawer } from 'antd'; import SiderMenu from './SiderMenu'; import { getFlatMenuKeys } from './SiderMenuUtils'; -const SiderMenuWrapper = React.memo(props => { +export declare type SiderTheme = 'light' | 'dark'; + +interface SiderMenuProps { + isMobile: boolean; + menuData: any[]; + collapsed: boolean; + logo?: string; + theme?: SiderTheme; + onCollapse: (payload: boolean) => void; +} + +const SiderMenuWrapper: React.SFC = props => { const { isMobile, menuData, collapsed, onCollapse } = props; const flatMenuKeys = getFlatMenuKeys(menuData); return isMobile ? ( @@ -21,6 +32,6 @@ const SiderMenuWrapper = React.memo(props => { ) : ( ); -}); +}; -export default SiderMenuWrapper; +export default React.memo(SiderMenuWrapper); diff --git a/src/components/TopNavHeader/index.js b/src/components/TopNavHeader/index.tsx similarity index 56% rename from src/components/TopNavHeader/index.js rename to src/components/TopNavHeader/index.tsx index 2d0e0656..a1b610b3 100644 --- a/src/components/TopNavHeader/index.js +++ b/src/components/TopNavHeader/index.tsx @@ -1,16 +1,52 @@ -import React, { PureComponent } from 'react'; +import React, { Component } from 'react'; import Link from 'umi/link'; import RightContent from '../GlobalHeader/RightContent'; import BaseMenu from '../SiderMenu/BaseMenu'; import { getFlatMenuKeys } from '../SiderMenu/SiderMenuUtils'; import styles from './index.less'; -import { title } from '../../defaultSettings'; +import defaultSettings from '../../../config/defaultSettings'; -export default class TopNavHeader extends PureComponent { +export declare type CollapseType = 'clickTrigger' | 'responsive'; +export declare type SiderTheme = 'light' | 'dark'; +export declare type MenuMode = + | 'vertical' + | 'vertical-left' + | 'vertical-right' + | 'horizontal' + | 'inline'; + +const { title } = defaultSettings; +interface TopNavHeaderProps { + theme: SiderTheme; + contentWidth?: string; + menuData?: any[]; + logo?: string; + mode?: MenuMode; + flatMenuKeys?: any[]; + onCollapse?: (collapsed: boolean, type?: CollapseType) => void; + isMobile?: boolean; + openKeys?: any; + className?: string; + collapsed?: boolean; + handleOpenChange?: (openKeys: any[]) => void; + style?: React.CSSProperties; + onOpenChange?: (openKeys: string[]) => void; + onNoticeClear?: (type: string) => void; + onMenuClick?: ({ key: string }) => void; + onNoticeVisibleChange?: (b: boolean) => void; +} + +interface TopNavHeaderState { + maxWidth: undefined | number; +} + +export default class TopNavHeader extends Component { state = { maxWidth: undefined, }; + maim: HTMLDivElement; + static getDerivedStateFromProps(props) { return { maxWidth: (props.contentWidth === 'Fixed' ? 1200 : window.innerWidth) - 280 - 165 - 40, diff --git a/src/components/_utils/pathTools.test.js b/src/components/_utils/pathTools.test.js deleted file mode 100644 index a9b93155..00000000 --- a/src/components/_utils/pathTools.test.js +++ /dev/null @@ -1,17 +0,0 @@ -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', - ]); - }); -}); diff --git a/src/components/_utils/pathTools.js b/src/components/_utils/pathTools.ts similarity index 100% rename from src/components/_utils/pathTools.js rename to src/components/_utils/pathTools.ts diff --git a/src/global.js b/src/global.tsx similarity index 90% rename from src/global.js rename to src/global.tsx index bebe4829..65e9b0db 100644 --- a/src/global.js +++ b/src/global.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { notification, Button, message } from 'antd'; -import { formatMessage } from 'umi/locale'; -import defaultSettings from './defaultSettings'; +import { formatMessage } from 'umi-plugin-locale'; +import defaultSettings from '../config/defaultSettings'; -window.React = React; +(window as any).React = React; const { pwa } = defaultSettings; // if pwa is true @@ -14,7 +14,7 @@ if (pwa) { }); // Pop up a prompt on the page asking the user if they want to use the latest version - window.addEventListener('sw.updated', e => { + window.addEventListener('sw.updated', (e: CustomEvent) => { const reloadSW = async () => { // Check if there is sw whose state is waiting in ServiceWorkerRegistration // https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration diff --git a/src/layouts/BasicLayout.js b/src/layouts/BasicLayout.js deleted file mode 100644 index 06cc41fc..00000000 --- a/src/layouts/BasicLayout.js +++ /dev/null @@ -1,173 +0,0 @@ -import React, { Suspense } from 'react'; -import { Layout } from 'antd'; -import DocumentTitle from 'react-document-title'; -import { connect } from 'dva'; -import { ContainerQuery } from 'react-container-query'; -import classNames from 'classnames'; -import Media from 'react-media'; -import logo from '../assets/logo.svg'; -import Footer from './Footer'; -import Header from './Header'; -import Context from './MenuContext'; -import PageLoading from '@/components/PageLoading'; -import SiderMenu from '@/components/SiderMenu'; -import getPageTitle from '@/utils/getPageTitle'; -import styles from './BasicLayout.less'; - -// lazy load SettingDrawer -const SettingDrawer = React.lazy(() => import('@/components/SettingDrawer')); - -const { Content } = Layout; - -const query = { - 'screen-xs': { - maxWidth: 575, - }, - 'screen-sm': { - minWidth: 576, - maxWidth: 767, - }, - 'screen-md': { - minWidth: 768, - maxWidth: 991, - }, - 'screen-lg': { - minWidth: 992, - maxWidth: 1199, - }, - 'screen-xl': { - minWidth: 1200, - maxWidth: 1599, - }, - 'screen-xxl': { - minWidth: 1600, - }, -}; - -class BasicLayout extends React.Component { - componentDidMount() { - const { - dispatch, - route: { routes, authority }, - } = this.props; - dispatch({ - type: 'user/fetchCurrent', - }); - dispatch({ - type: 'setting/getSetting', - }); - dispatch({ - type: 'menu/getMenuData', - payload: { routes, authority }, - }); - } - - getContext() { - const { location, breadcrumbNameMap } = this.props; - return { - location, - breadcrumbNameMap, - }; - } - - getLayoutStyle = () => { - const { fixSiderbar, isMobile, collapsed, layout } = this.props; - if (fixSiderbar && layout !== 'topmenu' && !isMobile) { - return { - paddingLeft: collapsed ? '80px' : '256px', - }; - } - return null; - }; - - handleMenuCollapse = collapsed => { - const { dispatch } = this.props; - dispatch({ - type: 'global/changeLayoutCollapsed', - payload: collapsed, - }); - }; - - renderSettingDrawer = () => { - // Do not render SettingDrawer in production - // unless it is deployed in preview.pro.ant.design as demo - if (process.env.NODE_ENV === 'production' && APP_TYPE !== 'site') { - return null; - } - return ; - }; - - render() { - const { - navTheme, - layout: PropsLayout, - children, - location: { pathname }, - isMobile, - menuData, - breadcrumbNameMap, - fixedHeader, - } = this.props; - - const isTop = PropsLayout === 'topmenu'; - const contentStyle = !fixedHeader ? { paddingTop: 0 } : {}; - const layout = ( - - {isTop && !isMobile ? null : ( - - )} - -
- - {children} - -