diff --git a/.travis.yml b/.travis.yml index 4789d27f..66de02f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,24 +4,15 @@ node_js: script: - npm run build before_install: + - yarn global add now +after_script: - | - if [ "$TRAVIS_BRANCH" = "develop" ]; then - for prefixed_envvar in ${!DEV_*}; do - eval export ${prefixed_envvar#DEV_}="${!prefixed_envvar}" - done - elif [ "$TRAVIS_BRANCH" = "master" ]; then - for prefixed_envvar in ${!PROD_*}; do - eval export ${prefixed_envvar#PROD_}="${!prefixed_envvar}" - done + if [[ $TRAVIS_BRANCH == 'master' ]]; then + echo $PROD_SITE_NOW_CONFIG >> dist/vercel.json && echo $PROD_DOC_NOW_CONFIG >> docs/vercel.json; else - for prefixed_envvar in ${!TEST_*}; do - eval export ${prefixed_envvar#TEST_}="${!prefixed_envvar}" - done + echo $DEV_SITE_NOW_CONFIG >> dist/vercel.json && echo $DEV_DOC_NOW_CONFIG >> docs/vercel.json; fi - - openssl aes-256-cbc -K $encrypted_18b2305b78c9_key -iv $encrypted_18b2305b78c9_iv -in config/id_rsa.enc -out ~/.ssh/id_rsa -d - - chmod 600 ~/.ssh/id_rsa - - echo -e "Host $HOST\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config - - yarn global add now -after_script: - - scp -o stricthostkeychecking=no -r ./dist root@$HOST:$BUILD_DIR - - cd ./docs && now -A $DOC_NOW_CONFIG -t $NOW_TOKEN && now alias -A $DOC_NOW_CONFIG -t $NOW_TOKEN + - cd ./dist + - now -A vercel.json -t $NOW_TOKEN --prod -c + - cd ../docs + - now -A vercel.json -t $NOW_TOKEN --prod -c diff --git a/.umirc.js b/.umirc.js index 21a9aa37..b270ac23 100644 --- a/.umirc.js +++ b/.umirc.js @@ -3,46 +3,26 @@ import { resolve } from 'path' const fs = require('fs') const path = require('path') const lessToJs = require('less-vars-to-js') +const isDevelopment = process.env.NODE_ENV === 'development' +// how to speed compile: https://umijs.org/guide/boost-compile-speed export default { // IMPORTANT! change next line to yours or delete. And hide in dev - // publicPath: 'https://cdn.antd-admin.zuiidea.com/', - hash: true, - ignoreMomentLocale: true, - targets: { ie: 9 }, - dva: { immer: true }, - antd: {}, - dynamicImport: { - loading: 'components/Loader/Loader', - }, - // not support in umi@3 - // pwa: { - // manifestOptions: { - // srcPath: 'manifest.json', - // }, - // }, - // Theme for antd - // https://ant.design/docs/react/customize-theme - theme: lessToJs( - fs.readFileSync(path.join(__dirname, './src/themes/default.less'), 'utf8') - ), - // Webpack Configuration - proxy: { - '/api/v1/weather': { - target: 'https://api.seniverse.com/', - changeOrigin: true, - pathRewrite: { '^/api/v1/weather': '/v3/weather' }, - }, - }, + publicPath: isDevelopment ? '/' : 'https://cdn.antd-admin.zuiidea.com/', alias: { api: resolve(__dirname, './src/services/'), components: resolve(__dirname, './src/components'), config: resolve(__dirname, './src/utils/config'), - models: resolve(__dirname, './src/models'), - services: resolve(__dirname, './src/services'), themes: resolve(__dirname, './src/themes'), utils: resolve(__dirname, './src/utils'), }, + antd: {}, + // a lower cost way to genereate sourcemap, default is cheap-module-source-map, could save 60% time in dev hotload + devtool: 'eval', + dva: { immer: true }, + dynamicImport: { + loading: 'components/Loader/Loader', + }, extraBabelPresets: ['@lingui/babel-preset-react'], extraBabelPlugins: [ [ @@ -54,18 +34,38 @@ export default { }, 'lodash', ], + [ + 'import', + { + libraryName: '@ant-design/icons', + libraryDirectory: 'es/icons', + camel2DashComponentName: false, + }, + 'ant-design-icons', + ], ], - chainWebpack: function(config, { webpack }) { - config.module - .rule('js-in-node_modules') - .exclude.add(/node_modules/) - .end() - - config.module - .rule('ts-in-node_modules') - .exclude.add(/node_modules/) - .end() - + hash: true, + ignoreMomentLocale: true, + // umi3 comple node_modules by default, could be disable + nodeModulesTransform: { + type: 'none', + exclude: [], + }, + // Webpack Configuration + proxy: { + '/api/v1/weather': { + target: 'https://api.seniverse.com/', + changeOrigin: true, + pathRewrite: { '^/api/v1/weather': '/v3/weather' }, + }, + }, + targets: { ie: 9 }, + // Theme for antd + // https://ant.design/docs/react/customize-theme + theme: lessToJs( + fs.readFileSync(path.join(__dirname, './src/themes/default.less'), 'utf8') + ), + chainWebpack: function (config, { webpack }) { config.merge({ optimization: { minimize: true, @@ -83,27 +83,37 @@ export default { antd: { name: 'antd', priority: 20, - test: /[\\/]node_modules[\\/](antd|@ant-design\/icons|@ant-design\/compatible)[\\/]/, + test: /[\\/]node_modules[\\/](antd|@ant-design\/icons)[\\/]/, + }, + 'echarts-gl': { + name: 'echarts-gl', + priority: 30, + test: /[\\/]node_modules[\\/]echarts-gl[\\/]/, + }, + zrender: { + name: 'zrender', + priority: 30, + test: /[\\/]node_modules[\\/]zrender[\\/]/, }, echarts: { name: 'echarts', priority: 20, - test: /[\\/]node_modules[\\/]echarts|echarts-for-react|echarts-gl|echarts-liquidfill[\\/]/, + test: /[\\/]node_modules[\\/](echarts|echarts-for-react|echarts-liquidfill)[\\/]/, }, highcharts: { name: 'highcharts', priority: 20, - test: /[\\/]node_modules[\\/](highcharts-exporting|highcharts-more|react-highcharts)[\\/]/, + test: /[\\/]node_modules[\\/]highcharts[\\/]/, }, recharts: { name: 'recharts', priority: 20, - test: /[\\/]node_modules[\\/](recharts)[\\/]/, + test: /[\\/]node_modules[\\/]recharts[\\/]/, }, draftjs: { name: 'draftjs', - priority: 20, - test: /[\\/]node_modules[\\/](draftjs-to-html|draftjs-to-markdown)[\\/]/, + priority: 30, + test: /[\\/]node_modules[\\/](draft-js|react-draft-wysiwyg|draftjs-to-html|draftjs-to-markdown)[\\/]/, }, async: { chunks: 'async', diff --git a/config/id_rsa.enc b/config/id_rsa.enc deleted file mode 100644 index 47993a75..00000000 Binary files a/config/id_rsa.enc and /dev/null differ diff --git a/docs/now.dev.json b/docs/now.dev.json deleted file mode 100644 index 20e8c746..00000000 --- a/docs/now.dev.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": 2, - "name": "antd-admin-devdoc", - "alias": ["devdoc-antd-admin.now.sh", "devdoc.antd-admin.zuiidea.com"], - "public": true -} diff --git a/docs/now.json b/docs/now.json deleted file mode 100644 index a6da56f8..00000000 --- a/docs/now.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": 2, - "name": "antd-admin-doc", - "alias": ["doc-antd-admin.now.sh", "doc.antd-admin.zuiidea.com"], - "public": true -} diff --git a/mock/dashboard.js b/mock/dashboard.js index 3b263ea6..8758594d 100644 --- a/mock/dashboard.js +++ b/mock/dashboard.js @@ -105,7 +105,7 @@ const Dashboard = Mock.mock({ content: "I'm selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can't handle me at my worst, then you sure as hell don't deserve me at my best.", avatar: - 'http://img.hb.aicdn.com/bc442cf0cc6f7940dcc567e465048d1a8d634493198c4-sPx5BR_fw236', + '//cdn.antd-admin.zuiidea.com/bc442cf0cc6f7940dcc567e465048d1a8d634493198c4-sPx5BR_fw236', }, numbers: [ { diff --git a/package.json b/package.json index d1c580dd..006dd0f5 100644 --- a/package.json +++ b/package.json @@ -4,13 +4,13 @@ "license": "MIT", "description": "An admin dashboard application demo built upon Ant Design and UmiJS", "dependencies": { - "@ant-design/compatible": "^1.0.0", - "@ant-design/icons": "^4.0.0", + "@ant-design/icons": "^4.2.2", "@lingui/react": "^2.8.0", "antd": "^4.0.0", "axios": "^0.19.0", "classnames": "^2.2.6", "d3-shape": "^1.3.0", + "draft-js": "^0.11.7", "draftjs-to-html": "^0.9.0", "draftjs-to-markdown": "^0.6.0", "dva-model-extend": "^0.1.2", @@ -31,7 +31,7 @@ "react-adsense": "^0.1.0", "react-countup": "^4.2.0", "react-draft-wysiwyg": "^1.13.0", - "react-helmet": "^5.2.0", + "react-helmet": "^6.0.0", "react-highcharts": "^16.1.0", "react-perfect-scrollbar": "^1.5.0", "recharts": "^2.0.0-beta.3", @@ -45,25 +45,25 @@ "babel-eslint": "^10.0.1", "babel-plugin-dev-expression": "^0.2.1", "babel-plugin-module-resolver": "^4.0.0", - "cross-env": "^6.0.0", - "eslint": "^6.8.0", + "cross-env": "^7.0.0", + "eslint": "^7.0.0", "eslint-config-react-app": "^5.0.0", - "eslint-plugin-flowtype": "^4.6.0", + "eslint-plugin-flowtype": "^5.1.0", "eslint-plugin-import": "^2.18.0", "eslint-plugin-jsx-a11y": "^6.2.1", "eslint-plugin-react": "^7.14.0", - "eslint-plugin-react-hooks": "^2.5.0", + "eslint-plugin-react-hooks": "^4.0.0", "husky": "^4.2.0", "less-vars-to-js": "^1.3.0", "lint-staged": "^10.0.0", "mockjs": "^1.1.0", "module": "^1.2.5", - "prettier": "^1.19.0", + "prettier": "^2.0.0", "stylelint": "^13.2.0", "stylelint-config-prettier": "^8.0.0", "stylelint-config-standard": "^20.0.0", "typescript": "^3.8.3", - "umi": "^3.0.0" + "umi": "^3.2.0" }, "engines": { "node": ">= 10.0.0" diff --git a/src/components/Layout/Bread.js b/src/components/Layout/Bread.js index a3a121a9..fcfb200b 100644 --- a/src/components/Layout/Bread.js +++ b/src/components/Layout/Bread.js @@ -3,20 +3,20 @@ import PropTypes from 'prop-types' import { Breadcrumb } from 'antd' import { Link, withRouter } from 'umi' import { withI18n } from '@lingui/react' -import { Icon as LegacyIcon } from '@ant-design/compatible' -const { pathToRegexp } = require("path-to-regexp") +import iconMap from 'utils/iconMap' +const { pathToRegexp } = require('path-to-regexp') import { queryAncestors } from 'utils' import styles from './Bread.less' @withI18n() @withRouter class Bread extends PureComponent { - generateBreadcrumbs = paths => { + generateBreadcrumbs = (paths) => { return paths.map((item, key) => { const content = item && ( {item.icon && ( - + {iconMap[item.icon]} )} {item.name} @@ -40,7 +40,7 @@ class Bread extends PureComponent { // Find a route that matches the pathname. const currentRoute = routeList.find( - _ => _.route && pathToRegexp(_.route).exec(location.pathname) + (_) => _.route && pathToRegexp(_.route).exec(location.pathname) ) // Find the breadcrumb navigation of the current route match and all its ancestors. diff --git a/src/components/Layout/Header.js b/src/components/Layout/Header.js index 49908818..48401877 100644 --- a/src/components/Layout/Header.js +++ b/src/components/Layout/Header.js @@ -2,8 +2,12 @@ import React, { PureComponent, Fragment } from 'react' import PropTypes from 'prop-types' import { Menu, Layout, Avatar, Popover, Badge, List } from 'antd' import { Ellipsis } from 'components' -import { Icon as LegacyIcon } from '@ant-design/compatible' -import { BellOutlined, RightOutlined } from '@ant-design/icons' +import { + BellOutlined, + RightOutlined, + MenuFoldOutlined, + MenuUnfoldOutlined, +} from '@ant-design/icons' import { Trans, withI18n } from '@lingui/react' import { setLocale } from 'utils' import moment from 'moment' @@ -144,14 +148,8 @@ class Header extends PureComponent { className={styles.button} onClick={onCollapseChange.bind(this, !collapsed)} > - + {collapsed ? : } -
{rightContent}
) diff --git a/src/components/Layout/Menu.js b/src/components/Layout/Menu.js index 3cd91cca..8438599a 100644 --- a/src/components/Layout/Menu.js +++ b/src/components/Layout/Menu.js @@ -1,13 +1,10 @@ import React, { PureComponent, Fragment } from 'react' import PropTypes from 'prop-types' -import { Icon as LegacyIcon } from '@ant-design/compatible' import { Menu } from 'antd' import { NavLink, withRouter } from 'umi' -const { pathToRegexp } = require("path-to-regexp") -import { - arrayToTree, - queryAncestors, -} from 'utils' +import { pathToRegexp } from 'path-to-regexp' +import { arrayToTree, queryAncestors } from 'utils' +import iconMap from 'utils/iconMap' import store from 'store' const { SubMenu } = Menu @@ -45,7 +42,7 @@ class SiderMenu extends PureComponent { key={item.id} title={ - {item.icon && } + {item.icon && iconMap[item.icon]} {item.name} } @@ -57,7 +54,7 @@ class SiderMenu extends PureComponent { return ( - {item.icon && } + {item.icon && iconMap[item.icon]} {item.name} diff --git a/src/pages/dashboard/components/browser.js b/src/pages/dashboard/components/browser.js index 4f52dbee..c17239fd 100644 --- a/src/pages/dashboard/components/browser.js +++ b/src/pages/dashboard/components/browser.js @@ -38,7 +38,7 @@ function Browser({ data }) { pagination={false} showHeader={false} columns={columns} - rowKey={(record, key) => key} + rowKey='name' dataSource={data} /> ) diff --git a/src/pages/dashboard/components/comments.js b/src/pages/dashboard/components/comments.js index ed3cdc20..64038606 100644 --- a/src/pages/dashboard/components/comments.js +++ b/src/pages/dashboard/components/comments.js @@ -54,7 +54,7 @@ function Comments({ data }) { pagination={false} showHeader={false} columns={columns} - rowKey={(record, key) => key} + rowKey='avatar' dataSource={data.filter((item, key) => key < 3)} /> diff --git a/src/pages/dashboard/components/numberCard.js b/src/pages/dashboard/components/numberCard.js index 267b1818..dbab616a 100644 --- a/src/pages/dashboard/components/numberCard.js +++ b/src/pages/dashboard/components/numberCard.js @@ -1,10 +1,11 @@ import React from 'react' import PropTypes from 'prop-types' -import { Icon as LegacyIcon } from '@ant-design/compatible' import { Card } from 'antd' import CountUp from 'react-countup' +import iconMap from 'utils/iconMap' import styles from './numberCard.less' + function NumberCard({ icon, color, title, number, countUp }) { return ( - + + {iconMap[icon]} +

{title || 'No Title'}

diff --git a/src/pages/dashboard/components/recentSales.js b/src/pages/dashboard/components/recentSales.js index 5b034a44..01907dc3 100644 --- a/src/pages/dashboard/components/recentSales.js +++ b/src/pages/dashboard/components/recentSales.js @@ -53,7 +53,7 @@ function RecentSales({ data }) { key} + rowKey='id' dataSource={data.filter((item, key) => key < 5)} /> diff --git a/src/pages/dashboard/model.js b/src/pages/dashboard/model.js index f448058b..19ae6a63 100644 --- a/src/pages/dashboard/model.js +++ b/src/pages/dashboard/model.js @@ -5,6 +5,7 @@ const { pathToRegexp } = require("path-to-regexp") import { model } from 'utils/model' const { queryDashboard, queryWeather } = api +const avatar = '//cdn.antd-admin.zuiidea.com/bc442cf0cc6f7940dcc567e465048d1a8d634493198c4-sPx5BR_fw236.jpeg' export default modelExtend(model, { namespace: 'dashboard', @@ -13,12 +14,11 @@ export default modelExtend(model, { city: '深圳', temperature: '30', name: '晴', - icon: '//s5.sencdn.com/web/icons/3d_50/2.png', + icon: '//cdn.antd-admin.zuiidea.com/sun.png', }, sales: [], quote: { - avatar: - 'http://img.hb.aicdn.com/bc442cf0cc6f7940dcc567e465048d1a8d634493198c4-sPx5BR_fw236', + avatar, }, numbers: [], recentSales: [], @@ -27,8 +27,7 @@ export default modelExtend(model, { browser: [], cpu: {}, user: { - avatar: - 'http://img.hb.aicdn.com/bc442cf0cc6f7940dcc567e465048d1a8d634493198c4-sPx5BR_fw236', + avatar, }, }, subscriptions: { @@ -62,7 +61,7 @@ export default modelExtend(model, { city: data.location.name, temperature: data.now.temperature, name: data.now.text, - icon: `//s5.sencdn.com/web/icons/3d_50/${data.now.code}.png`, + icon: `//cdn.antd-admin.zuiidea.com/web/icons/3d_50/${data.now.code}.png`, } yield put({ type: 'updateState', diff --git a/src/utils/iconMap.jsx b/src/utils/iconMap.jsx new file mode 100644 index 00000000..ceacadfd --- /dev/null +++ b/src/utils/iconMap.jsx @@ -0,0 +1,31 @@ +import { + PayCircleOutlined, + ShoppingCartOutlined, + MessageOutlined, + TeamOutlined, + UserOutlined, + DashboardOutlined, + ApiOutlined, + CameraOutlined, + EditOutlined, + CodeOutlined, + LineOutlined, + BarChartOutlined, + AreaChartOutlined, +} from '@ant-design/icons' + +export default { + 'pay-circle-o': , + 'shopping-cart': , + 'camera-o': , + 'line-chart': , + 'code-o': , + 'area-chart': , + 'bar-chart': , + message: , + team: , + dashboard: , + user: , + api: , + edit: , +}