diff --git a/mock/route.js b/mock/route.js index 89d892e..fb0456b 100644 --- a/mock/route.js +++ b/mock/route.js @@ -90,7 +90,7 @@ const database = [ name: 'Editor' }, icon: 'edit', - route: '/UIElement/editor', + route: '/editor', }, { id: '5', diff --git a/package.json b/package.json index 6e00baf..fcab4c5 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "stylelint": "^13.2.0", "stylelint-config-prettier": "^8.0.0", "stylelint-config-standard": "^20.0.0", + "typescript": "^3.8.3", "umi": "^3.0.0" }, "engines": { @@ -93,7 +94,7 @@ "format": "minimal", "extractBabelOptions": { "presets": [ - "umi/babel" + "@umijs/babel-preset-umi" ] } }, diff --git a/src/components/Layout/Bread.js b/src/components/Layout/Bread.js index 473a7a6..272e4f1 100644 --- a/src/components/Layout/Bread.js +++ b/src/components/Layout/Bread.js @@ -2,11 +2,13 @@ import React, { PureComponent, Fragment } from 'react' 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 { queryAncestors } from 'utils' import styles from './Bread.less' +@withI18n() @withRouter class Bread extends PureComponent { generateBreadcrumbs = paths => { diff --git a/src/components/Layout/Header.js b/src/components/Layout/Header.js index 35eb356..6bf0216 100644 --- a/src/components/Layout/Header.js +++ b/src/components/Layout/Header.js @@ -2,9 +2,9 @@ import React, { PureComponent, Fragment } from 'react' import PropTypes from 'prop-types' import { Menu, Layout, Avatar, Popover, Badge, List } from 'antd' import { Ellipsis } from 'ant-design-pro' -import { useIntl } from 'umi' import { Icon as LegacyIcon } from '@ant-design/compatible' import { BellOutlined, RightOutlined } from '@ant-design/icons' +import { Trans, withI18n } from '@lingui/react' import { setLocale } from 'utils' import moment from 'moment' import classnames from 'classnames' @@ -13,6 +13,7 @@ import styles from './Header.less' const { SubMenu } = Menu +@withI18n() class Header extends PureComponent { handleClickMenu = e => { e.key === 'SignOut' && this.props.onSignOut() @@ -28,16 +29,14 @@ class Header extends PureComponent { onCollapseChange, onAllNotificationsRead, } = this.props - const intl = useIntl() + const rightContent = [ - {intl.formatMessage({ - id: 'Hi,' - })} + Hi, {username} @@ -45,9 +44,7 @@ class Header extends PureComponent { } > - {intl.formatMessage({ - id: 'Sign out' - })} + Sign out , diff --git a/src/components/Layout/Sider.js b/src/components/Layout/Sider.js index 62b4854..4614abc 100644 --- a/src/components/Layout/Sider.js +++ b/src/components/Layout/Sider.js @@ -59,11 +59,7 @@ class Sider extends PureComponent {
- {intl.formatMessage( - { - id: 'Switch Theme', - defaultMessage: '你好,旅行者', - })} + Switch Theme { - // false means no refresh - setLocale(language, false) + const catalog = await import( + /* webpackMode: "lazy", webpackChunkName: "i18n-[index]" */ + `@lingui/loader!../locales/${language}/messages.json` + ) + + this.setState(state => ({ + catalogs: { + ...state.catalogs, + [language]: catalog, + }, + })) } render() { diff --git a/src/models/app.js b/src/models/app.js index 129d3d1..bd2a104 100644 --- a/src/models/app.js +++ b/src/models/app.js @@ -52,6 +52,7 @@ export default { dispatch({ type: 'query' }) }, setupHistory({ dispatch, history }) { + console.log(history) history.listen(location => { dispatch({ type: 'updateState', diff --git a/src/pages/404.js b/src/pages/404.tsx similarity index 100% rename from src/pages/404.js rename to src/pages/404.tsx diff --git a/src/pages/chart/Container.js b/src/pages/chart/Container.js deleted file mode 100644 index 5c19608..0000000 --- a/src/pages/chart/Container.js +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { ResponsiveContainer } from 'recharts' -import styles from './Container.less' - -const Container = ({ - children, - ratio = 5 / 2, - minHeight = 250, - maxHeight = 350, -}) => ( -
-
-
- {children} -
-
-) - -Container.propTypes = { - children: PropTypes.element.isRequired, - ratio: PropTypes.number, - minHeight: PropTypes.number, - maxHeight: PropTypes.number, -} - -export default Container diff --git a/src/pages/chart/Container.less b/src/pages/chart/Container.less deleted file mode 100644 index ab10db2..0000000 --- a/src/pages/chart/Container.less +++ /dev/null @@ -1,20 +0,0 @@ -.container { - width: 100%; - position: relative; - display: inline-block; - - :global { - .recharts-responsive-container { - width: e('calc(100% + 56px)') !important; - margin-left: -32px; - } - } -} - -.content { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; -} diff --git a/src/pages/UIElement/editor/index.js b/src/pages/editor/index.js similarity index 92% rename from src/pages/UIElement/editor/index.js rename to src/pages/editor/index.js index 0fffab1..f65bb6a 100644 --- a/src/pages/UIElement/editor/index.js +++ b/src/pages/editor/index.js @@ -1,11 +1,11 @@ -import React from 'react' -import { Editor } from 'components' +import { Component } from 'react' +import { Editor, Page } from 'components' import { convertToRaw } from 'draft-js' import { Row, Col, Card } from 'antd' import draftToHtml from 'draftjs-to-html' import draftToMarkdown from 'draftjs-to-markdown' -export default class EditorPage extends React.Component { +export default class EditorPage extends Component { constructor(props) { super(props) this.state = { @@ -26,17 +26,18 @@ export default class EditorPage extends React.Component { md: 24, style: { marginBottom: 32, - }, + } } const textareaStyle = { minHeight: 496, width: '100%', background: '#f7f7f7', borderColor: '#F1F1F1', - padding: '16px 8px', + padding: '16px 8px' } + return ( -
+ @@ -98,7 +99,7 @@ export default class EditorPage extends React.Component { -
+ ) } } diff --git a/src/pages/login/index.js b/src/pages/login/index.js index fbdd8a3..74c9c53 100644 --- a/src/pages/login/index.js +++ b/src/pages/login/index.js @@ -6,13 +6,14 @@ import { GlobalFooter } from 'ant-design-pro' import { Form } from '@ant-design/compatible' import '@ant-design/compatible/assets/index.css' import { GithubOutlined } from '@ant-design/icons' - +import { Trans, withI18n } from '@lingui/react' import { setLocale } from 'utils' import config from 'utils/config' import styles from './index.less' const FormItem = Form.Item +@withI18n() @connect(({ loading }) => ({ loading })) @Form.create() class Login extends PureComponent { @@ -94,15 +95,15 @@ class Login extends PureComponent { onClick={this.handleOk} loading={loading.effects.login} > - {Intl.formatMessage({id: 'Sign in'})} + Sign in

- {Intl.formatMessage({id: 'Username'})} + Username :guest - {Intl.formatMessage({id: 'Password'})} + Password :guest

diff --git a/src/pages/post/components/List.js b/src/pages/post/components/List.js index 685683b..43bfeae 100644 --- a/src/pages/post/components/List.js +++ b/src/pages/post/components/List.js @@ -1,8 +1,10 @@ import React, { PureComponent } from 'react' import { Table, Avatar } from 'antd' +import { withI18n } from '@lingui/react' import { Ellipsis } from 'ant-design-pro' import styles from './List.less' +@withI18n() class List extends PureComponent { render() { const { i18n, ...tableProps } = this.props diff --git a/src/pages/post/index.js b/src/pages/post/index.js index 7d8e2f2..fd231cb 100644 --- a/src/pages/post/index.js +++ b/src/pages/post/index.js @@ -4,6 +4,7 @@ import { connect } from 'dva' import { Tabs } from 'antd' import { history } from 'umi' import { stringify } from 'qs' +import { withI18n } from '@lingui/react' import { Page } from 'components' import List from './components/List' diff --git a/src/pages/request/index.js b/src/pages/request/index.js index 3d8e9b6..6024b20 100644 --- a/src/pages/request/index.js +++ b/src/pages/request/index.js @@ -6,6 +6,7 @@ import classnames from 'classnames' import { Form } from '@ant-design/compatible' import '@ant-design/compatible/assets/index.css' import { CloseOutlined } from '@ant-design/icons' +import { Trans } from '@lingui/react' import api from '@/services/api' import { Page } from 'components' diff --git a/src/pages/user/components/Filter.js b/src/pages/user/components/Filter.js index 0a5b87c..021863a 100644 --- a/src/pages/user/components/Filter.js +++ b/src/pages/user/components/Filter.js @@ -7,6 +7,7 @@ import { FilterItem } from 'components' import { Form } from '@ant-design/compatible' import '@ant-design/compatible/assets/index.css' +import { Trans, withI18n } from '@lingui/react' import { Button, Row, Col, DatePicker, Input, Cascader } from 'antd' import city from 'utils/city' @@ -26,6 +27,7 @@ const TwoColProps = { xl: 96, } +@withI18n() @Form.create() class Filter extends Component { handleFields = fields => { diff --git a/src/pages/user/components/List.js b/src/pages/user/components/List.js index 5a32b8e..ff73f0f 100644 --- a/src/pages/user/components/List.js +++ b/src/pages/user/components/List.js @@ -2,23 +2,22 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' import { Table, Modal, Avatar } from 'antd' import { DropOption } from 'components' -import { Link, useIntl } from 'umi' +import { Trans, withI18n } from '@lingui/react' +import { Link } from 'umi' import styles from './List.less' const { confirm } = Modal +@withI18n() class List extends PureComponent { handleMenuClick = (record, e) => { - const { onDeleteItem, onEditItem } = this.props + const { onDeleteItem, onEditItem, i18n } = this.props if (e.key === '1') { onEditItem(record) } else if (e.key === '2') { confirm({ - title: intl.formatMessage( - { - id: 'Are you sure delete this record?', - }), + title: i18n.t`Are you sure delete this record?`, onOk() { onDeleteItem(record.id) }, @@ -27,11 +26,11 @@ class List extends PureComponent { } render() { - const { onDeleteItem, onEditItem, ...tableProps } = this.props - const intl = useIntl() + const { onDeleteItem, onEditItem, i18n, ...tableProps } = this.props + const columns = [ { - title: intl.formatMessage({id: 'Avatar'}), + title: Avatar, dataIndex: 'avatar', key: 'avatar', width: 72, @@ -39,49 +38,49 @@ class List extends PureComponent { render: text => , }, { - title: intl.formatMessage({id: 'Name'}), + title: Name, dataIndex: 'name', key: 'name', render: (text, record) => {text}, }, { - title: intl.formatMessage({id: 'NickName'}), + title: NickName, dataIndex: 'nickName', key: 'nickName', }, { - title: intl.formatMessage({id: 'Age'}), + title: Age, dataIndex: 'age', key: 'age', }, { - title: intl.formatMessage({id: 'Gender'}), + title: Gender, dataIndex: 'isMale', key: 'isMale', render: text => {text ? 'Male' : 'Female'}, }, { - title: intl.formatMessage({id: 'Phone'}), + title: Phone, dataIndex: 'phone', key: 'phone', }, { - title: intl.formatMessage({id: 'Email'}), + title: Email, dataIndex: 'email', key: 'email', }, { - title: intl.formatMessage({id: 'Address'}), + title: Address, dataIndex: 'address', key: 'address', }, { - title: intl.formatMessage({id: 'CreateTime'}), + title: CreateTime, dataIndex: 'createTime', key: 'createTime', }, { - title: intl.formatMessage({id: 'Operation'}), + title: Operation, key: 'operation', fixed: 'right', render: (text, record) => { @@ -89,14 +88,8 @@ class List extends PureComponent { this.handleMenuClick(record, e)} menuOptions={[ - { key: '1', name: intl.formatMessage( - { - id: 'Update', - }) }, - { key: '2', name: intl.formatMessage( - { - id: 'Delete', - }) }, + { key: '1', name: i18n.t`Update` }, + { key: '2', name: i18n.t`Delete` }, ]} /> ) @@ -109,7 +102,7 @@ class List extends PureComponent { {...tableProps} pagination={{ ...tableProps.pagination, - showTotal: total => intl.formatMessage({name: 'Total '},{id: 'Avatar'}, { name: 'Items'}), + showTotal: total => i18n.t`Total ${total} Items`, }} className={styles.table} bordered diff --git a/src/pages/user/components/Modal.js b/src/pages/user/components/Modal.js index 746cfc8..4c2348c 100644 --- a/src/pages/user/components/Modal.js +++ b/src/pages/user/components/Modal.js @@ -3,8 +3,7 @@ import PropTypes from 'prop-types' import { Input, InputNumber, Radio, Modal, Cascader } from 'antd' import { Form } from '@ant-design/compatible' import '@ant-design/compatible/assets/index.css' -import { useIntl } from 'umi'; - +import { Trans, withI18n } from '@lingui/react' import city from 'utils/city' const FormItem = Form.Item @@ -17,7 +16,7 @@ const formItemLayout = { span: 14, }, } - +@withI18n() @Form.create() class UserModal extends PureComponent { handleOk = () => { @@ -54,10 +53,7 @@ class UserModal extends PureComponent { ], })()} - + {getFieldDecorator('nickName', { initialValue: item.nickName, rules: [ @@ -79,18 +75,10 @@ class UserModal extends PureComponent { })( - {intl.formatMessage( - { - id: 'Male', - defaultMessage: '你好,旅行者', - })} + Male - {intl.formatMessage( - { - id: 'Female', - defaultMessage: '你好,旅行者', - })} + Female )} diff --git a/src/pages/user/index.js b/src/pages/user/index.js index 83b5911..e9602bc 100644 --- a/src/pages/user/index.js +++ b/src/pages/user/index.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types' import { history } from 'umi' import { connect } from 'dva' import { Row, Col, Button, Popconfirm } from 'antd' +import { withI18n } from '@lingui/react' import { Page } from 'components' import { stringify } from 'qs' import List from './components/List' diff --git a/src/utils/index.js b/src/utils/index.js index 7fceadf..dd7efc1 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,12 +1,17 @@ import { cloneDeep } from 'lodash' const { pathToRegexp } = require("path-to-regexp") import 'moment/locale/zh-cn' +import store from 'store' +import { i18n } from './config' export classnames from 'classnames' export config from './config' export request from './request' export { Color } from './theme' +export const languages = i18n ? i18n.languages.map(item => item.key) : [] +export const defaultLanguage = i18n ? i18n.defaultLanguage : '' + /** * Query objects that specify keys and values in an array where all values are objects. * @param {array} array An array where all values are objects, like [{key:1},{key:2}]. @@ -55,6 +60,8 @@ export function arrayToTree( return result } + + /** * In an array object, traverse all parent IDs based on the value of an object. * @param {array} array The Array need to Converted. @@ -149,3 +156,19 @@ export function queryLayout(layouts, pathname) { return result } + + +export function getLocale() { + return store.get('locale') +} + +export function setLocale(language) { + if (getLocale() !== language) { + moment.locale(language === 'zh' ? 'zh-cn' : language) + store.set('locale', language) + history.push({ + pathname: `/${window.location.pathname}`, + search: window.location.search, + }) + } +} \ No newline at end of file