diff --git a/AccountCenter/.gitignore b/AccountCenter/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/AccountCenter/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/AccountCenter/.umirc.js b/AccountCenter/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..6f5bf0564d9bd0bd2952b8c733821edae8d6c4f8 --- /dev/null +++ b/AccountCenter/.umirc.js @@ -0,0 +1,13 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { layout: 'ant-design-pro' }], + [ + 'umi-plugin-react', + { + dva: true, + locale: true, + antd: true, + }, + ], + ], +}; diff --git a/AccountCenter/README.md b/AccountCenter/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ddecd3225528d0712bd911d273df731ba6a87e26 --- /dev/null +++ b/AccountCenter/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/accountcenter + +AccountCenter + +## Usage + +```sh +umi block add ant-design-pro/AccountCenter +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/AccountCenter/package.json b/AccountCenter/package.json new file mode 100644 index 0000000000000000000000000000000000000000..d8cd626ee453fa1ec271aeea23ef596930a38e20 --- /dev/null +++ b/AccountCenter/package.json @@ -0,0 +1,25 @@ +{ + "name": "@umi-block/account-center", + "version": "0.0.1", + "description": "AccountCenter", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/accountcenter" + }, + "dependencies": { + "antd": "^3.10.9", + "dva": "^2.4.0", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/AccountCenter/snapshot.png b/AccountCenter/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..a5a4515c4af4dde29296e704f1f4804ffe686fca Binary files /dev/null and b/AccountCenter/snapshot.png differ diff --git a/src/pages/Account/Center/Center.less b/AccountCenter/src/Center.less similarity index 92% rename from src/pages/Account/Center/Center.less rename to AccountCenter/src/Center.less index 37d6a203e668df00d742f20c366721a18304600c..c6125f1e6f3ba76be4ae149cc0daed39ca62e10f 100644 --- a/src/pages/Account/Center/Center.less +++ b/AccountCenter/src/Center.less @@ -1,5 +1,4 @@ @import '~antd/lib/style/themes/default.less'; -@import '~@/utils/utils.less'; .avatarHolder { text-align: center; @@ -80,7 +79,10 @@ margin-bottom: 24px; color: @text-color; transition: color 0.3s; - .textOverflow(); + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + white-space: nowrap; &:hover { color: @primary-color; diff --git a/AccountCenter/src/_mock.js b/AccountCenter/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..3c9ef791dce51d8bed8dc2b6f2dcc56d7e8bc046 --- /dev/null +++ b/AccountCenter/src/_mock.js @@ -0,0 +1,138 @@ +const titles = [ + 'Alipay', + 'Angular', + 'Ant Design', + 'Ant Design Pro', + 'Bootstrap', + 'React', + 'Vue', + 'Webpack', +]; +const avatars = [ + 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png', // Alipay + 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png', // Angular + 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', // Ant Design + 'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', // Ant Design Pro + 'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png', // Bootstrap + 'https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png', // React + 'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png', // Vue + 'https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png', // Webpack +]; + +const getNotice = [ + { + id: 'xxx1', + title: titles[0], + logo: avatars[0], + description: '那是一种内在的东西,他们到达不了,也无法触及的', + updatedAt: new Date(), + member: '科学搬砖组', + href: '', + memberLink: '', + }, + { + id: 'xxx2', + title: titles[1], + logo: avatars[1], + description: '希望是一个好东西,也许是最好的,好东西是不会消亡的', + updatedAt: new Date('2017-07-24'), + member: '全组都是吴彦祖', + href: '', + memberLink: '', + }, + { + id: 'xxx3', + title: titles[2], + logo: avatars[2], + description: '城镇中有那么多的酒馆,她却偏偏走进了我的酒馆', + updatedAt: new Date(), + member: '中二少女团', + href: '', + memberLink: '', + }, + { + id: 'xxx4', + title: titles[3], + logo: avatars[3], + description: '那时候我只会想自己想要什么,从不想自己拥有什么', + updatedAt: new Date('2017-07-23'), + member: '程序员日常', + href: '', + memberLink: '', + }, + { + id: 'xxx5', + title: titles[4], + logo: avatars[4], + description: '凛冬将至', + updatedAt: new Date('2017-07-23'), + member: '高逼格设计天团', + href: '', + memberLink: '', + }, + { + id: 'xxx6', + title: titles[5], + logo: avatars[5], + description: '生命就像一盒巧克力,结果往往出人意料', + updatedAt: new Date('2017-07-23'), + member: '骗你来学计算机', + href: '', + memberLink: '', + }, +]; + +export default { + // 支持值为 Object 和 Array + 'GET /api/BLOCK_NAME/currentUser': { + name: 'Serati Ma', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png', + userid: '00000001', + email: 'antdesign@alipay.com', + signature: '海纳百川,有容乃大', + title: '交互专家', + group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED', + notice: getNotice, + tags: [ + { + key: '0', + label: '很有想法的', + }, + { + key: '1', + label: '专注设计', + }, + { + key: '2', + label: '辣~', + }, + { + key: '3', + label: '大长腿', + }, + { + key: '4', + label: '川妹子', + }, + { + key: '5', + label: '海纳百川', + }, + ], + notifyCount: 12, + unreadCount: 11, + country: 'China', + geographic: { + province: { + label: '浙江省', + key: '330000', + }, + city: { + label: '杭州市', + key: '330100', + }, + }, + address: '西湖区工专路 77 号', + phone: '0752-268888888', + }, +}; diff --git a/AccountCenter/src/index.js b/AccountCenter/src/index.js new file mode 100644 index 0000000000000000000000000000000000000000..a8dc908478b04b4442c5a2ed3a081c31e4d76771 --- /dev/null +++ b/AccountCenter/src/index.js @@ -0,0 +1,191 @@ +import React, { PureComponent } from 'react'; +import { connect } from 'dva'; +import Link from 'umi/link'; +import { Card, Row, Col, Icon, Avatar, Tag, Divider, Input } from 'antd'; +import styles from './Center.less'; + +const operationTabList = [ + { + key: 'articles', + tab: ( + + 文章 (8) + + ), + }, + { + key: 'applications', + tab: ( + + 应用 (8) + + ), + }, + { + key: 'projects', + tab: ( + + 项目 (8) + + ), + }, +]; + +@connect(({ loading, BLOCK_NAME_CAMEL_CASE }) => ({ + currentUser: BLOCK_NAME_CAMEL_CASE.currentUser, + currentUserLoading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchCurrent'], +})) +class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { + static getDerivedStateFromProps(props, state) { + const { match, location } = props; + const { tabKey } = state; + const urlTabKey = location.pathname.replace(`${match.path}/`, ''); + if (urlTabKey && urlTabKey !== '/' && tabKey !== urlTabKey) { + return { + tabKey: urlTabKey, + }; + } + return null; + } + + state = { + newTags: [], + inputVisible: false, + inputValue: '', + tabKey: 'articles', + }; + + componentDidMount() { + const { dispatch } = this.props; + dispatch({ + type: 'BLOCK_NAME_CAMEL_CASE/fetchCurrent', + }); + } + + onTabChange = key => { + // If you need to sync state to url + // const { match } = this.props; + // router.push(`${match.url}/${key}`); + this.setState({ + tabKey: key, + }); + }; + + showInput = () => { + this.setState({ inputVisible: true }, () => this.input.focus()); + }; + + saveInputRef = input => { + this.input = input; + }; + + handleInputChange = e => { + this.setState({ inputValue: e.target.value }); + }; + + handleInputConfirm = () => { + const { state } = this; + const { inputValue } = state; + let { newTags } = state; + if (inputValue && newTags.filter(tag => tag.label === inputValue).length === 0) { + newTags = [...newTags, { key: `new-${newTags.length}`, label: inputValue }]; + } + this.setState({ + newTags, + inputVisible: false, + inputValue: '', + }); + }; + + render() { + const { newTags, inputVisible, inputValue, tabKey } = this.state; + const { currentUser, currentUserLoading, children } = this.props; + const dataLoading = currentUserLoading || !(currentUser && Object.keys(currentUser).length); + return ( + + + + {!dataLoading ? ( + + + + {currentUser.name} + {currentUser.signature} + + + + + {currentUser.title} + + + + {currentUser.group} + + + + {currentUser.geographic.province.label} + {currentUser.geographic.city.label} + + + + + 标签 + {currentUser.tags.concat(newTags).map(item => ( + {item.label} + ))} + {inputVisible && ( + + )} + {!inputVisible && ( + + + + )} + + + + 团队 + + {currentUser.notice.map(item => ( + + + + {item.member} + + + ))} + + + + ) : null} + + + + + {children || tabKey} + + + + ); + } +} + +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/src/models/user.js b/AccountCenter/src/model.js similarity index 90% rename from src/models/user.js rename to AccountCenter/src/model.js index c84ebbcfc8ed31efef71df8e8fc7d350894a1722..f927b437690729e549debbb3c3bd24965a4d2db6 100644 --- a/src/models/user.js +++ b/AccountCenter/src/model.js @@ -1,7 +1,7 @@ -import { query as queryUsers, queryCurrent } from '@/services/user'; +import { query as queryUsers, queryCurrent } from './service'; export default { - namespace: 'user', + namespace: 'BLOCK_NAME_CAMEL_CASE', state: { list: [], diff --git a/AccountCenter/src/service.js b/AccountCenter/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..6fdf83df65bd2e0e359eb6f1bc9d8ee076cff540 --- /dev/null +++ b/AccountCenter/src/service.js @@ -0,0 +1,9 @@ +import request from 'umi-request'; + +export async function query() { + return request('/api/BLOCK_NAME/users'); +} + +export async function queryCurrent() { + return request('/api/BLOCK_NAME/currentUser'); +} diff --git a/AccountSettings/.gitignore b/AccountSettings/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/AccountSettings/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/AccountSettings/.umirc.js b/AccountSettings/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..70ab1e9b79813e2a091d036d763edc262cdf23bf --- /dev/null +++ b/AccountSettings/.umirc.js @@ -0,0 +1,18 @@ +export default { + plugins: [ + [ + 'umi-plugin-block-dev', + { + layout: 'ant-design-pro', + }, + ], + [ + 'umi-plugin-react', + { + dva: true, + locale: true, + antd: true, + }, + ], + ], +}; diff --git a/AccountSettings/README.md b/AccountSettings/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ff93fb84f9dd39bfc6030305f82e62296c339502 --- /dev/null +++ b/AccountSettings/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/accountsettings + +AccountSettings + +## Usage + +```sh +umi block add ant-design-pro/AccountSettings +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/AccountSettings/jsconfig.json b/AccountSettings/jsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..f87334d482029d82509ddb6c0dab5ab62236cd15 --- /dev/null +++ b/AccountSettings/jsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + } +} diff --git a/AccountSettings/package.json b/AccountSettings/package.json new file mode 100644 index 0000000000000000000000000000000000000000..8901d45c231094e654de3bd20d13725f03a245ea --- /dev/null +++ b/AccountSettings/package.json @@ -0,0 +1,25 @@ +{ + "name": "@umi-block/account-settings", + "version": "0.0.1", + "description": "AccountSettings", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/accountsettings" + }, + "dependencies": { + "antd": "^3.10.9", + "dva": "^2.4.0", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0", + "umi-plugin-react": "^1.3.0-beta.1" + }, + "license": "ISC" +} diff --git a/AccountSettings/snapshot.png b/AccountSettings/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..a4f5f1c375689badbf56331fb7e11dc39f4513ae Binary files /dev/null and b/AccountSettings/snapshot.png differ diff --git a/AccountSettings/src/_mock.js b/AccountSettings/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..6533a3386ea3930d739fe63e381562ef4397ae4c --- /dev/null +++ b/AccountSettings/src/_mock.js @@ -0,0 +1,66 @@ +import city from './geographic/city.json'; +import province from './geographic/province.json'; + +function getProvince(req, res) { + return res.json(province); +} + +function getCity(req, res) { + return res.json(city[req.params.province]); +} +// 代码中会兼容本地 service mock 以及部署站点的静态数据 +export default { + // 支持值为 Object 和 Array + 'GET /api/BLOCK_NAME/currentUser': { + name: 'Serati Ma', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png', + userid: '00000001', + email: 'antdesign@alipay.com', + signature: '海纳百川,有容乃大', + title: '交互专家', + group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED', + tags: [ + { + key: '0', + label: '很有想法的', + }, + { + key: '1', + label: '专注设计', + }, + { + key: '2', + label: '辣~', + }, + { + key: '3', + label: '大长腿', + }, + { + key: '4', + label: '川妹子', + }, + { + key: '5', + label: '海纳百川', + }, + ], + notifyCount: 12, + unreadCount: 11, + country: 'China', + geographic: { + province: { + label: '浙江省', + key: '330000', + }, + city: { + label: '杭州市', + key: '330100', + }, + }, + address: '西湖区工专路 77 号', + phone: '0752-268888888', + }, + 'GET /api/BLOCK_NAME/province': getProvince, + 'GET /api/BLOCK_NAME/city/:province': getCity, +}; diff --git a/src/pages/Account/Settings/BaseView.less b/AccountSettings/src/components/BaseView.less similarity index 100% rename from src/pages/Account/Settings/BaseView.less rename to AccountSettings/src/components/BaseView.less diff --git a/src/pages/Account/Settings/GeographicView.js b/AccountSettings/src/components/GeographicView.js similarity index 85% rename from src/pages/Account/Settings/GeographicView.js rename to AccountSettings/src/components/GeographicView.js index d33cb13871d39ef38ad986013339200c072b2d64..c5274b7c894d9edb52298219c35126a26357561c 100644 --- a/src/pages/Account/Settings/GeographicView.js +++ b/AccountSettings/src/components/GeographicView.js @@ -10,19 +10,19 @@ const nullSlectItem = { key: '', }; -@connect(({ geographic }) => { - const { province, isLoading, city } = geographic; +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => { + const { province, city } = BLOCK_NAME_CAMEL_CASE; return { province, city, - isLoading, + loading: loading.models.BLOCK_NAME_CAMEL_CASE, }; }) class GeographicView extends PureComponent { componentDidMount = () => { const { dispatch } = this.props; dispatch({ - type: 'geographic/fetchProvince', + type: 'BLOCK_NAME_CAMEL_CASE/fetchProvince', }); }; @@ -31,7 +31,7 @@ class GeographicView extends PureComponent { if (!props.value && !!value && !!value.province) { dispatch({ - type: 'geographic/fetchCity', + type: 'BLOCK_NAME_CAMEL_CASE/fetchCity', payload: value.province.key, }); } @@ -65,7 +65,7 @@ class GeographicView extends PureComponent { selectProvinceItem = item => { const { dispatch, onChange } = this.props; dispatch({ - type: 'geographic/fetchCity', + type: 'BLOCK_NAME_CAMEL_CASE/fetchCity', payload: item.key, }); onChange({ @@ -99,9 +99,9 @@ class GeographicView extends PureComponent { render() { const { province, city } = this.conversionObject(); - const { isLoading } = this.props; + const { loading } = this.props; return ( - + ( - + @@ -22,7 +21,7 @@ const AvatarView = ({ avatar }) => ( - + @@ -51,8 +50,8 @@ const validatorPhone = (rule, value, callback) => { callback(); }; -@connect(({ user }) => ({ - currentUser: user.currentUser, +@connect(({ BLOCK_NAME_CAMEL_CASE }) => ({ + currentUser: BLOCK_NAME_CAMEL_CASE.currentUser, })) @Form.create() class BaseView extends Component { @@ -90,47 +89,47 @@ class BaseView extends Component { - + {getFieldDecorator('email', { rules: [ { required: true, - message: formatMessage({ id: 'app.settings.basic.email-message' }, {}), + message: formatMessage({ id: 'BLOCK_NAME.basic.email-message' }, {}), }, ], })()} - + {getFieldDecorator('name', { rules: [ { required: true, - message: formatMessage({ id: 'app.settings.basic.nickname-message' }, {}), + message: formatMessage({ id: 'BLOCK_NAME.basic.nickname-message' }, {}), }, ], })()} - + {getFieldDecorator('profile', { rules: [ { required: true, - message: formatMessage({ id: 'app.settings.basic.profile-message' }, {}), + message: formatMessage({ id: 'BLOCK_NAME.basic.profile-message' }, {}), }, ], })( )} - + {getFieldDecorator('country', { rules: [ { required: true, - message: formatMessage({ id: 'app.settings.basic.country-message' }, {}), + message: formatMessage({ id: 'BLOCK_NAME.basic.country-message' }, {}), }, ], })( @@ -139,12 +138,12 @@ class BaseView extends Component { )} - + {getFieldDecorator('geographic', { rules: [ { required: true, - message: formatMessage({ id: 'app.settings.basic.geographic-message' }, {}), + message: formatMessage({ id: 'BLOCK_NAME.basic.geographic-message' }, {}), }, { validator: validatorGeographic, @@ -152,22 +151,22 @@ class BaseView extends Component { ], })()} - + {getFieldDecorator('address', { rules: [ { required: true, - message: formatMessage({ id: 'app.settings.basic.address-message' }, {}), + message: formatMessage({ id: 'BLOCK_NAME.basic.address-message' }, {}), }, ], })()} - + {getFieldDecorator('phone', { rules: [ { required: true, - message: formatMessage({ id: 'app.settings.basic.phone-message' }, {}), + message: formatMessage({ id: 'BLOCK_NAME.basic.phone-message' }, {}), }, { validator: validatorPhone }, ], @@ -175,7 +174,7 @@ class BaseView extends Component { diff --git a/src/pages/Account/Settings/BindingView.js b/AccountSettings/src/components/binding.js similarity index 59% rename from src/pages/Account/Settings/BindingView.js rename to AccountSettings/src/components/binding.js index 29a29890ca0d5ab339f872f1fe614ff9b0122ea4..c95eca62ab0a200b78bcf0cb3a043dfc808ebde5 100644 --- a/src/pages/Account/Settings/BindingView.js +++ b/AccountSettings/src/components/binding.js @@ -5,31 +5,31 @@ import { Icon, List } from 'antd'; class BindingView extends Component { getData = () => [ { - title: formatMessage({ id: 'app.settings.binding.taobao' }, {}), - description: formatMessage({ id: 'app.settings.binding.taobao-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.binding.taobao' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.binding.taobao-description' }, {}), actions: [ - + , ], avatar: , }, { - title: formatMessage({ id: 'app.settings.binding.alipay' }, {}), - description: formatMessage({ id: 'app.settings.binding.alipay-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.binding.alipay' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.binding.alipay-description' }, {}), actions: [ - + , ], avatar: , }, { - title: formatMessage({ id: 'app.settings.binding.dingding' }, {}), - description: formatMessage({ id: 'app.settings.binding.dingding-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.binding.dingding' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.binding.dingding-description' }, {}), actions: [ - + , ], avatar: , diff --git a/src/pages/Account/Settings/NotificationView.js b/AccountSettings/src/components/notification.js similarity index 55% rename from src/pages/Account/Settings/NotificationView.js rename to AccountSettings/src/components/notification.js index 96677bbd269501cb9e901ea0f30b58ed2e51d774..b61eac3e68bd65000fe3043c8c2c70bb79da2227 100644 --- a/src/pages/Account/Settings/NotificationView.js +++ b/AccountSettings/src/components/notification.js @@ -6,25 +6,25 @@ class NotificationView extends Component { getData = () => { const Action = ( ); return [ { - title: formatMessage({ id: 'app.settings.notification.password' }, {}), - description: formatMessage({ id: 'app.settings.notification.password-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.notification.password' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.notification.password-description' }, {}), actions: [Action], }, { - title: formatMessage({ id: 'app.settings.notification.messages' }, {}), - description: formatMessage({ id: 'app.settings.notification.messages-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.notification.messages' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.notification.messages-description' }, {}), actions: [Action], }, { - title: formatMessage({ id: 'app.settings.notification.todo' }, {}), - description: formatMessage({ id: 'app.settings.notification.todo-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.notification.todo' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.notification.todo-description' }, {}), actions: [Action], }, ]; diff --git a/src/pages/Account/Settings/SecurityView.js b/AccountSettings/src/components/security.js similarity index 50% rename from src/pages/Account/Settings/SecurityView.js rename to AccountSettings/src/components/security.js index 0706bd0b9b2988bb41bcc2a3fe9ab20f65f6bf16..96685c0fb911c20d2e73a644fd7aa3f82d1ebe3d 100644 --- a/src/pages/Account/Settings/SecurityView.js +++ b/AccountSettings/src/components/security.js @@ -6,17 +6,17 @@ import { List } from 'antd'; const passwordStrength = { strong: ( - + ), medium: ( - + ), weak: ( - + Weak ), @@ -25,58 +25,58 @@ const passwordStrength = { class SecurityView extends Component { getData = () => [ { - title: formatMessage({ id: 'app.settings.security.password' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.security.password' }, {}), description: ( - {formatMessage({ id: 'app.settings.security.password-description' })}: + {formatMessage({ id: 'BLOCK_NAME.security.password-description' })}: {passwordStrength.strong} ), actions: [ - + , ], }, { - title: formatMessage({ id: 'app.settings.security.phone' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.security.phone' }, {}), description: `${formatMessage( - { id: 'app.settings.security.phone-description' }, + { id: 'BLOCK_NAME.security.phone-description' }, {} )}:138****8293`, actions: [ - + , ], }, { - title: formatMessage({ id: 'app.settings.security.question' }, {}), - description: formatMessage({ id: 'app.settings.security.question-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.security.question' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.security.question-description' }, {}), actions: [ - + , ], }, { - title: formatMessage({ id: 'app.settings.security.email' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.security.email' }, {}), description: `${formatMessage( - { id: 'app.settings.security.email-description' }, + { id: 'BLOCK_NAME.security.email-description' }, {} )}:ant***sign.com`, actions: [ - + , ], }, { - title: formatMessage({ id: 'app.settings.security.mfa' }, {}), - description: formatMessage({ id: 'app.settings.security.mfa-description' }, {}), + title: formatMessage({ id: 'BLOCK_NAME.security.mfa' }, {}), + description: formatMessage({ id: 'BLOCK_NAME.security.mfa-description' }, {}), actions: [ - + , ], }, diff --git a/mock/geographic/city.json b/AccountSettings/src/geographic/city.json similarity index 100% rename from mock/geographic/city.json rename to AccountSettings/src/geographic/city.json diff --git a/mock/geographic/province.json b/AccountSettings/src/geographic/province.json similarity index 100% rename from mock/geographic/province.json rename to AccountSettings/src/geographic/province.json diff --git a/AccountSettings/src/index.js b/AccountSettings/src/index.js new file mode 100644 index 0000000000000000000000000000000000000000..32985cfec461b82e1e85c134a9a03ece7d4e75b3 --- /dev/null +++ b/AccountSettings/src/index.js @@ -0,0 +1,137 @@ +import React, { Component } from 'react'; +import { connect } from 'dva'; +import { FormattedMessage } from 'umi/locale'; +import { Menu } from 'antd'; +import styles from './style.less'; +import BaseView from './components/base'; +import SecurityView from './components/security'; +import BindingView from './components/binding'; +import NotificationView from './components/notification'; + +const { Item } = Menu; + +@connect(({ BLOCK_NAME_CAMEL_CASE }) => ({ + currentUser: BLOCK_NAME_CAMEL_CASE.currentUser, +})) +class PAGE_NAME_UPPER_CAMEL_CASE extends Component { + constructor(props) { + super(props); + const menuMap = { + base: , + security: ( + + ), + binding: ( + + ), + notification: ( + + ), + }; + this.state = { + mode: 'inline', + menuMap, + selectKey: 'base', + }; + } + + componentDidMount() { + const { dispatch } = this.props; + dispatch({ + type: 'BLOCK_NAME_CAMEL_CASE/fetchCurrent', + }); + window.addEventListener('resize', this.resize); + this.resize(); + } + + componentWillUnmount() { + window.removeEventListener('resize', this.resize); + } + + getmenu = () => { + const { menuMap } = this.state; + return Object.keys(menuMap).map(item => {menuMap[item]}); + }; + + getRightTitle = () => { + const { selectKey, menuMap } = this.state; + return menuMap[selectKey]; + }; + + selectKey = ({ key }) => { + this.setState({ + selectKey: key, + }); + }; + + resize = () => { + if (!this.main) { + return; + } + requestAnimationFrame(() => { + if (!this.main) { + return; + } + let mode = 'inline'; + const { offsetWidth } = this.main; + if (this.main.offsetWidth < 641 && offsetWidth > 400) { + mode = 'horizontal'; + } + if (window.innerWidth < 768 && offsetWidth > 400) { + mode = 'horizontal'; + } + this.setState({ + mode, + }); + }); + }; + + renderChildren = () => { + const { selectKey } = this.state; + switch (selectKey) { + case 'base': + return ; + case 'security': + return ; + case 'binding': + return ; + case 'notification': + return ; + default: + break; + } + + return null; + }; + + render() { + const { currentUser } = this.props; + if (!currentUser.userid) { + return ''; + } + const { mode, selectKey } = this.state; + return ( + { + this.main = ref; + }} + > + + + {this.getmenu()} + + + + {this.getRightTitle()} + {this.renderChildren()} + + + ); + } +} + +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/AccountSettings/src/locales/en-US.js b/AccountSettings/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..aab0f68db624474e8f1e43686648c6391af1fd9d --- /dev/null +++ b/AccountSettings/src/locales/en-US.js @@ -0,0 +1,60 @@ +export default { + 'BLOCK_NAME.menuMap.basic': 'Basic Settings', + 'BLOCK_NAME.menuMap.security': 'Security Settings', + 'BLOCK_NAME.menuMap.binding': 'Account Binding', + 'BLOCK_NAME.menuMap.notification': 'New Message Notification', + 'BLOCK_NAME.basic.avatar': 'Avatar', + 'BLOCK_NAME.basic.change-avatar': 'Change avatar', + 'BLOCK_NAME.basic.email': 'Email', + 'BLOCK_NAME.basic.email-message': 'Please input your email!', + 'BLOCK_NAME.basic.nickname': 'Nickname', + 'BLOCK_NAME.basic.nickname-message': 'Please input your Nickname!', + 'BLOCK_NAME.basic.profile': 'Personal profile', + 'BLOCK_NAME.basic.profile-message': 'Please input your personal profile!', + 'BLOCK_NAME.basic.profile-placeholder': 'Brief introduction to yourself', + 'BLOCK_NAME.basic.country': 'Country/Region', + 'BLOCK_NAME.basic.country-message': 'Please input your country!', + 'BLOCK_NAME.basic.geographic': 'Province or city', + 'BLOCK_NAME.basic.geographic-message': 'Please input your geographic info!', + 'BLOCK_NAME.basic.address': 'Street Address', + 'BLOCK_NAME.basic.address-message': 'Please input your address!', + 'BLOCK_NAME.basic.phone': 'Phone Number', + 'BLOCK_NAME.basic.phone-message': 'Please input your phone!', + 'BLOCK_NAME.basic.update': 'Update Information', + 'BLOCK_NAME.security.strong': 'Strong', + 'BLOCK_NAME.security.medium': 'Medium', + 'BLOCK_NAME.security.weak': 'Weak', + 'BLOCK_NAME.security.password': 'Account Password', + 'BLOCK_NAME.security.password-description': 'Current password strength:', + 'BLOCK_NAME.security.phone': 'Security Phone', + 'BLOCK_NAME.security.phone-description': 'Bound phone:', + 'BLOCK_NAME.security.question': 'Security Question', + 'BLOCK_NAME.security.question-description': + 'The security question is not set, and the security policy can effectively protect the account security', + 'BLOCK_NAME.security.email': 'Backup Email', + 'BLOCK_NAME.security.email-description': 'Bound Email:', + 'BLOCK_NAME.security.mfa': 'MFA Device', + 'BLOCK_NAME.security.mfa-description': + 'Unbound MFA device, after binding, can be confirmed twice', + 'BLOCK_NAME.security.modify': 'Modify', + 'BLOCK_NAME.security.set': 'Set', + 'BLOCK_NAME.security.bind': 'Bind', + 'BLOCK_NAME.binding.taobao': 'Binding Taobao', + 'BLOCK_NAME.binding.taobao-description': 'Currently unbound Taobao account', + 'BLOCK_NAME.binding.alipay': 'Binding Alipay', + 'BLOCK_NAME.binding.alipay-description': 'Currently unbound Alipay account', + 'BLOCK_NAME.binding.dingding': 'Binding DingTalk', + 'BLOCK_NAME.binding.dingding-description': 'Currently unbound DingTalk account', + 'BLOCK_NAME.binding.bind': 'Bind', + 'BLOCK_NAME.notification.password': 'Account Password', + 'BLOCK_NAME.notification.password-description': + 'Messages from other users will be notified in the form of a station letter', + 'BLOCK_NAME.notification.messages': 'System Messages', + 'BLOCK_NAME.notification.messages-description': + 'System messages will be notified in the form of a station letter', + 'BLOCK_NAME.notification.todo': 'To-do Notification', + 'BLOCK_NAME.notification.todo-description': + 'The to-do list will be notified in the form of a letter from the station', + 'BLOCK_NAME.settings.open': 'Open', + 'BLOCK_NAME.settings.close': 'Close', +}; diff --git a/AccountSettings/src/locales/zh-CN.js b/AccountSettings/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..29c5674b831184c5967a1c2982f9a8773c71678c --- /dev/null +++ b/AccountSettings/src/locales/zh-CN.js @@ -0,0 +1,55 @@ +export default { + 'BLOCK_NAME.menuMap.basic': '基本设置', + 'BLOCK_NAME.menuMap.security': '安全设置', + 'BLOCK_NAME.menuMap.binding': '账号绑定', + 'BLOCK_NAME.menuMap.notification': '新消息通知', + 'BLOCK_NAME.basic.avatar': '头像', + 'BLOCK_NAME.basic.change-avatar': '更换头像', + 'BLOCK_NAME.basic.email': '邮箱', + 'BLOCK_NAME.basic.email-message': '请输入您的邮箱!', + 'BLOCK_NAME.basic.nickname': '昵称', + 'BLOCK_NAME.basic.nickname-message': '请输入您的昵称!', + 'BLOCK_NAME.basic.profile': '个人简介', + 'BLOCK_NAME.basic.profile-message': '请输入个人简介!', + 'BLOCK_NAME.basic.profile-placeholder': '个人简介', + 'BLOCK_NAME.basic.country': '国家/地区', + 'BLOCK_NAME.basic.country-message': '请输入您的国家或地区!', + 'BLOCK_NAME.basic.geographic': '所在省市', + 'BLOCK_NAME.basic.geographic-message': '请输入您的所在省市!', + 'BLOCK_NAME.basic.address': '街道地址', + 'BLOCK_NAME.basic.address-message': '请输入您的街道地址!', + 'BLOCK_NAME.basic.phone': '联系电话', + 'BLOCK_NAME.basic.phone-message': '请输入您的联系电话!', + 'BLOCK_NAME.basic.update': '更新基本信息', + 'BLOCK_NAME.security.strong': '强', + 'BLOCK_NAME.security.medium': '中', + 'BLOCK_NAME.security.weak': '弱', + 'BLOCK_NAME.security.password': '账户密码', + 'BLOCK_NAME.security.password-description': '当前密码强度:', + 'BLOCK_NAME.security.phone': '密保手机', + 'BLOCK_NAME.security.phone-description': '已绑定手机:', + 'BLOCK_NAME.security.question': '密保问题', + 'BLOCK_NAME.security.question-description': '未设置密保问题,密保问题可有效保护账户安全', + 'BLOCK_NAME.security.email': '备用邮箱', + 'BLOCK_NAME.security.email-description': '已绑定邮箱:', + 'BLOCK_NAME.security.mfa': 'MFA 设备', + 'BLOCK_NAME.security.mfa-description': '未绑定 MFA 设备,绑定后,可以进行二次确认', + 'BLOCK_NAME.security.modify': '修改', + 'BLOCK_NAME.security.set': '设置', + 'BLOCK_NAME.security.bind': '绑定', + 'BLOCK_NAME.binding.taobao': '绑定淘宝', + 'BLOCK_NAME.binding.taobao-description': '当前未绑定淘宝账号', + 'BLOCK_NAME.binding.alipay': '绑定支付宝', + 'BLOCK_NAME.binding.alipay-description': '当前未绑定支付宝账号', + 'BLOCK_NAME.binding.dingding': '绑定钉钉', + 'BLOCK_NAME.binding.dingding-description': '当前未绑定钉钉账号', + 'BLOCK_NAME.binding.bind': '绑定', + 'BLOCK_NAME.notification.password': '账户密码', + 'BLOCK_NAME.notification.password-description': '其他用户的消息将以站内信的形式通知', + 'BLOCK_NAME.notification.messages': '系统消息', + 'BLOCK_NAME.notification.messages-description': '系统消息将以站内信的形式通知', + 'BLOCK_NAME.notification.todo': '待办任务', + 'BLOCK_NAME.notification.todo-description': '待办任务将以站内信的形式通知', + 'BLOCK_NAME.settings.open': '开', + 'BLOCK_NAME.settings.close': '关', +}; diff --git a/AccountSettings/src/locales/zh-TW.js b/AccountSettings/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..a65cf7e96dad48d3cce631bd4e199eab9ec13d2e --- /dev/null +++ b/AccountSettings/src/locales/zh-TW.js @@ -0,0 +1,55 @@ +export default { + 'BLOCK_NAME.menuMap.basic': '基本設置', + 'BLOCK_NAME.menuMap.security': '安全設置', + 'BLOCK_NAME.menuMap.binding': '賬號綁定', + 'BLOCK_NAME.menuMap.notification': '新消息通知', + 'BLOCK_NAME.basic.avatar': '頭像', + 'BLOCK_NAME.basic.change-avatar': '更換頭像', + 'BLOCK_NAME.basic.email': '郵箱', + 'BLOCK_NAME.basic.email-message': '請輸入您的郵箱!', + 'BLOCK_NAME.basic.nickname': '昵稱', + 'BLOCK_NAME.basic.nickname-message': '請輸入您的昵稱!', + 'BLOCK_NAME.basic.profile': '個人簡介', + 'BLOCK_NAME.basic.profile-message': '請輸入個人簡介!', + 'BLOCK_NAME.basic.profile-placeholder': '個人簡介', + 'BLOCK_NAME.basic.country': '國家/地區', + 'BLOCK_NAME.basic.country-message': '請輸入您的國家或地區!', + 'BLOCK_NAME.basic.geographic': '所在省市', + 'BLOCK_NAME.basic.geographic-message': '請輸入您的所在省市!', + 'BLOCK_NAME.basic.address': '街道地址', + 'BLOCK_NAME.basic.address-message': '請輸入您的街道地址!', + 'BLOCK_NAME.basic.phone': '聯系電話', + 'BLOCK_NAME.basic.phone-message': '請輸入您的聯系電話!', + 'BLOCK_NAME.basic.update': '更新基本信息', + 'BLOCK_NAME.security.strong': '強', + 'BLOCK_NAME.security.medium': '中', + 'BLOCK_NAME.security.weak': '弱', + 'BLOCK_NAME.security.password': '賬戶密碼', + 'BLOCK_NAME.security.password-description': '當前密碼強度:', + 'BLOCK_NAME.security.phone': '密保手機', + 'BLOCK_NAME.security.phone-description': '已綁定手機:', + 'BLOCK_NAME.security.question': '密保問題', + 'BLOCK_NAME.security.question-description': '未設置密保問題,密保問題可有效保護賬戶安全', + 'BLOCK_NAME.security.email': '備用郵箱', + 'BLOCK_NAME.security.email-description': '已綁定郵箱:', + 'BLOCK_NAME.security.mfa': 'MFA 設備', + 'BLOCK_NAME.security.mfa-description': '未綁定 MFA 設備,綁定後,可以進行二次確認', + 'BLOCK_NAME.security.modify': '修改', + 'BLOCK_NAME.security.set': '設置', + 'BLOCK_NAME.security.bind': '綁定', + 'BLOCK_NAME.binding.taobao': '綁定淘寶', + 'BLOCK_NAME.binding.taobao-description': '當前未綁定淘寶賬號', + 'BLOCK_NAME.binding.alipay': '綁定支付寶', + 'BLOCK_NAME.binding.alipay-description': '當前未綁定支付寶賬號', + 'BLOCK_NAME.binding.dingding': '綁定釘釘', + 'BLOCK_NAME.binding.dingding-description': '當前未綁定釘釘賬號', + 'BLOCK_NAME.binding.bind': '綁定', + 'BLOCK_NAME.notification.password': '賬戶密碼', + 'BLOCK_NAME.notification.password-description': '其他用戶的消息將以站內信的形式通知', + 'BLOCK_NAME.notification.messages': '系統消息', + 'BLOCK_NAME.notification.messages-description': '系統消息將以站內信的形式通知', + 'BLOCK_NAME.notification.todo': '待辦任務', + 'BLOCK_NAME.notification.todo-description': '待辦任務將以站內信的形式通知', + 'BLOCK_NAME.settings.open': '開', + 'BLOCK_NAME.settings.close': '關', +}; diff --git a/src/pages/Account/Settings/models/geographic.js b/AccountSettings/src/model.js similarity index 50% rename from src/pages/Account/Settings/models/geographic.js rename to AccountSettings/src/model.js index a501920c7159e773285f23311e52366c563235f8..99fc23a30a72cb3660cace5a027eca3548640012 100644 --- a/src/pages/Account/Settings/models/geographic.js +++ b/AccountSettings/src/model.js @@ -1,15 +1,30 @@ -import { queryProvince, queryCity } from '@/services/geographic'; +import { query as queryUsers, queryCurrent, queryProvince, queryCity } from './service'; export default { - namespace: 'geographic', + namespace: 'BLOCK_NAME_CAMEL_CASE', state: { + list: [], + currentUser: {}, province: [], city: [], - isLoading: false, }, effects: { + *fetch(_, { call, put }) { + const response = yield call(queryUsers); + yield put({ + type: 'save', + payload: response, + }); + }, + *fetchCurrent(_, { call, put }) { + const response = yield call(queryCurrent); + yield put({ + type: 'saveCurrentUser', + payload: response, + }); + }, *fetchProvince(_, { call, put }) { yield put({ type: 'changeLoading', @@ -20,29 +35,39 @@ export default { type: 'setProvince', payload: response, }); - yield put({ - type: 'changeLoading', - payload: false, - }); }, *fetchCity({ payload }, { call, put }) { - yield put({ - type: 'changeLoading', - payload: true, - }); const response = yield call(queryCity, payload); yield put({ type: 'setCity', payload: response, }); - yield put({ - type: 'changeLoading', - payload: false, - }); }, }, reducers: { + save(state, action) { + return { + ...state, + list: action.payload, + }; + }, + saveCurrentUser(state, action) { + return { + ...state, + currentUser: action.payload || {}, + }; + }, + changeNotifyCount(state, action) { + return { + ...state, + currentUser: { + ...state.currentUser, + notifyCount: action.payload.totalCount, + unreadCount: action.payload.unreadCount, + }, + }; + }, setProvince(state, action) { return { ...state, diff --git a/AccountSettings/src/service.js b/AccountSettings/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..104bb1e95faf1c80935bdcf42af0807c2e3304e0 --- /dev/null +++ b/AccountSettings/src/service.js @@ -0,0 +1,17 @@ +import request from 'umi-request'; + +export async function queryCurrent() { + return request('/api/BLOCK_NAME/currentUser'); +} + +export async function queryProvince() { + return request('/api/BLOCK_NAME/province'); +} + +export async function queryCity(province) { + return request(`/api/BLOCK_NAME/city/${province}`); +} + +export async function query() { + return request('/api/BLOCK_NAME/users'); +} diff --git a/src/pages/Account/Settings/Info.less b/AccountSettings/src/style.less similarity index 100% rename from src/pages/Account/Settings/Info.less rename to AccountSettings/src/style.less diff --git a/AdvancedForm/.gitignore b/AdvancedForm/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/AdvancedForm/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/AdvancedForm/.umirc.js b/AdvancedForm/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/AdvancedForm/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/AdvancedForm/README.md b/AdvancedForm/README.md new file mode 100644 index 0000000000000000000000000000000000000000..cc9bfcbe5ab7d1712f074c3a8c5d750c3278a589 --- /dev/null +++ b/AdvancedForm/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/advancedform + +AdvancedForm + +## Usage + +```sh +umi block add ant-design-pro/advancedform +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/AdvancedForm/package.json b/AdvancedForm/package.json new file mode 100644 index 0000000000000000000000000000000000000000..a26dc013f98971eeab36d1c4ac42957c4385ea0b --- /dev/null +++ b/AdvancedForm/package.json @@ -0,0 +1,27 @@ +{ + "name": "@umi-block/advanced-form", + "version": "0.0.1", + "description": "AdvancedForm", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/advancedform" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "dva": "^2.4.0", + "lodash": "^4.17.10", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/AdvancedForm/snapshot.png b/AdvancedForm/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..c6c31d206674a32f789305620dd9334a2dbdd935 Binary files /dev/null and b/AdvancedForm/snapshot.png differ diff --git a/AdvancedForm/src/_mock.js b/AdvancedForm/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..8e7996deae35737ca576735528af9f6eaa281b98 --- /dev/null +++ b/AdvancedForm/src/_mock.js @@ -0,0 +1,5 @@ +export default { + 'POST /api/BLOCK_NAME/forms': (req, res) => { + res.send({ message: 'Ok' }); + }, +}; diff --git a/AdvancedForm/src/components/PageHeaderWrapper/index.js b/AdvancedForm/src/components/PageHeaderWrapper/index.js new file mode 100644 index 0000000000000000000000000000000000000000..c11873f2c8c24d44391261910d5adb52ab916d1a --- /dev/null +++ b/AdvancedForm/src/components/PageHeaderWrapper/index.js @@ -0,0 +1,25 @@ +import React from 'react'; +import { FormattedMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { PageHeader } from 'ant-design-pro'; +import styles from './index.less'; + +const PageHeaderWrapper = ({ children, wrapperClassName, ...restProps }) => ( + + } + key="pageheader" + {...restProps} + linkElement={Link} + itemRender={item => { + if (item.locale) { + return ; + } + return item.title; + }} + /> + {children ? {children} : null} + +); + +export default PageHeaderWrapper; diff --git a/src/components/PageHeaderWrapper/index.less b/AdvancedForm/src/components/PageHeaderWrapper/index.less similarity index 100% rename from src/components/PageHeaderWrapper/index.less rename to AdvancedForm/src/components/PageHeaderWrapper/index.less diff --git a/src/pages/Forms/TableForm.js b/AdvancedForm/src/components/TableForm.js similarity index 98% rename from src/pages/Forms/TableForm.js rename to AdvancedForm/src/components/TableForm.js index ae2723e7ba4eea80351d5a3d772fba89404e2c5c..66f941dcfaa7dd029d3cb2b5597c0771214af5c0 100644 --- a/src/pages/Forms/TableForm.js +++ b/AdvancedForm/src/components/TableForm.js @@ -1,7 +1,7 @@ import React, { PureComponent, Fragment } from 'react'; import { Table, Button, Input, message, Popconfirm, Divider } from 'antd'; -import isEqual from 'lodash/isEqual'; -import styles from './style.less'; +import { isEqual } from 'lodash'; +import styles from '../style.less'; class TableForm extends PureComponent { index = 0; diff --git a/src/pages/Forms/AdvancedForm.js b/AdvancedForm/src/index.js similarity index 96% rename from src/pages/Forms/AdvancedForm.js rename to AdvancedForm/src/index.js index fbd39689351b897e42538e7590a21aa6c112c8c7..e2045c2699f32ca3d69ffb032587aec34595dfcf 100644 --- a/src/pages/Forms/AdvancedForm.js +++ b/AdvancedForm/src/index.js @@ -13,9 +13,9 @@ import { Popover, } from 'antd'; import { connect } from 'dva'; -import FooterToolbar from '@/components/FooterToolbar'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; -import TableForm from './TableForm'; +import { FooterToolbar } from 'ant-design-pro'; +import PageHeaderWrapper from './components/PageHeaderWrapper'; +import TableForm from './components/TableForm'; import styles from './style.less'; const { Option } = Select; @@ -58,10 +58,10 @@ const tableData = [ ]; @connect(({ loading }) => ({ - submitting: loading.effects['form/submitAdvancedForm'], + submitting: loading.effects['BLOCK_NAME_CAMEL_CASE/submitAdvancedForm'], })) @Form.create() -class AdvancedForm extends PureComponent { +class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { state = { width: '100%', }; @@ -139,7 +139,7 @@ class AdvancedForm extends PureComponent { if (!error) { // submit the values dispatch({ - type: 'form/submitAdvancedForm', + type: 'BLOCK_NAME_CAMEL_CASE/submitAdvancedForm', payload: values, }); } @@ -320,4 +320,4 @@ class AdvancedForm extends PureComponent { } } -export default AdvancedForm; +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/AdvancedForm/src/locales/en-US.js b/AdvancedForm/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..3356dda0f90eaa80e52b8bc4bd9002f62d9d4bc8 --- /dev/null +++ b/AdvancedForm/src/locales/en-US.js @@ -0,0 +1,61 @@ +export default { + 'BLOCK_NAME.basic.title': 'Basic form', + 'BLOCK_NAME.basic.description': + 'Form pages are used to collect or verify information to users, and basic forms are common in scenarios where there are fewer data items.', + + 'BLOCK_NAME.email.required': 'Please enter your email!', + 'BLOCK_NAME.email.wrong-format': 'The email address is in the wrong format!', + 'BLOCK_NAME.userName.required': 'Please enter your userName!', + 'BLOCK_NAME.password.required': 'Please enter your password!', + 'BLOCK_NAME.password.twice': 'The passwords entered twice do not match!', + 'BLOCK_NAME.strength.msg': + "Please enter at least 6 characters and don't use passwords that are easy to guess.", + 'BLOCK_NAME.strength.strong': 'Strength: strong', + 'BLOCK_NAME.strength.medium': 'Strength: medium', + 'BLOCK_NAME.strength.short': 'Strength: too short', + 'BLOCK_NAME.confirm-password.required': 'Please confirm your password!', + 'BLOCK_NAME.phone-number.required': 'Please enter your phone number!', + 'BLOCK_NAME.phone-number.wrong-format': 'Malformed phone number!', + 'BLOCK_NAME.verification-code.required': 'Please enter the verification code!', + 'BLOCK_NAME.title.required': 'Please enter a title', + 'BLOCK_NAME.date.required': 'Please select the start and end date', + 'BLOCK_NAME.goal.required': 'Please enter a description of the goal', + 'BLOCK_NAME.standard.required': 'Please enter a metric', + + 'BLOCK_NAME.form.get-captcha': 'Get Captcha', + 'BLOCK_NAME.captcha.second': 'sec', + 'BLOCK_NAME.form.optional': ' (optional) ', + 'BLOCK_NAME.form.submit': 'Submit', + 'BLOCK_NAME.form.save': 'Save', + 'BLOCK_NAME.email.placeholder': 'Email', + 'BLOCK_NAME.password.placeholder': 'Password', + 'BLOCK_NAME.confirm-password.placeholder': 'Confirm password', + 'BLOCK_NAME.phone-number.placeholder': 'Phone number', + 'BLOCK_NAME.verification-code.placeholder': 'Verification code', + 'BLOCK_NAME.title.label': 'Title', + 'BLOCK_NAME.title.placeholder': 'Give the target a name', + 'BLOCK_NAME.date.label': 'Start and end date', + 'BLOCK_NAME.placeholder.start': 'Start date', + 'BLOCK_NAME.placeholder.end': 'End date', + 'BLOCK_NAME.goal.label': 'Goal description', + 'BLOCK_NAME.goal.placeholder': 'Please enter your work goals', + 'BLOCK_NAME.standard.label': 'Metrics', + 'BLOCK_NAME.standard.placeholder': 'Please enter a metric', + 'BLOCK_NAME.client.label': 'Client', + 'BLOCK_NAME.label.tooltip': 'Target service object', + 'BLOCK_NAME.client.placeholder': + 'Please describe your customer service, internal customers directly @ Name / job number', + 'BLOCK_NAME.invites.label': 'Inviting critics', + 'BLOCK_NAME.invites.placeholder': 'Please direct @ Name / job number, you can invite up to 5 people', + 'BLOCK_NAME.weight.label': 'Weight', + 'BLOCK_NAME.weight.placeholder': 'Please enter weight', + 'BLOCK_NAME.public.label': 'Target disclosure', + 'BLOCK_NAME.label.help': 'Customers and invitees are shared by default', + 'BLOCK_NAME.radio.public': 'Public', + 'BLOCK_NAME.radio.partially-public': 'Partially public', + 'BLOCK_NAME.radio.private': 'Private', + 'BLOCK_NAME.publicUsers.placeholder': 'Open to', + 'BLOCK_NAME.option.A': 'Colleague A', + 'BLOCK_NAME.option.B': 'Colleague B', + 'BLOCK_NAME.option.C': 'Colleague C', +}; diff --git a/AdvancedForm/src/locales/pt-BR.js b/AdvancedForm/src/locales/pt-BR.js new file mode 100644 index 0000000000000000000000000000000000000000..1cc9013111adbea37ac80892f11b28d487566f72 --- /dev/null +++ b/AdvancedForm/src/locales/pt-BR.js @@ -0,0 +1,57 @@ +export default { + 'BLOCK_NAME.basic.title': 'Basic form', + 'BLOCK_NAME.basic.description': + 'Form pages are used to collect or verify information to users, and basic forms are common in scenarios where there are fewer data items.', + + 'BLOCK_NAME.email.required': 'Por favor insira seu email!', + 'BLOCK_NAME.email.wrong-format': 'O email está errado!', + 'BLOCK_NAME.userName.required': 'Por favor insira nome de usuário!', + 'BLOCK_NAME.password.required': 'Por favor insira sua senha!', + 'BLOCK_NAME.password.twice': 'As senhas não estão iguais!', + 'BLOCK_NAME.strength.msg': + 'Por favor insira pelo menos 6 caracteres e não use senhas fáceis de adivinhar.', + 'BLOCK_NAME.strength.strong': 'Força: forte', + 'BLOCK_NAME.strength.medium': 'Força: média', + 'BLOCK_NAME.strength.short': 'Força: curta', + 'BLOCK_NAME.confirm-password.required': 'Por favor confirme sua senha!', + 'BLOCK_NAME.phone-number.required': 'Por favor insira seu telefone!', + 'BLOCK_NAME.phone-number.wrong-format': 'Formato de telefone errado!', + 'BLOCK_NAME.verification-code.required': 'Por favor insira seu código de verificação!', + + 'BLOCK_NAME.form.get-captcha': 'Get Captcha', + 'BLOCK_NAME.captcha.second': 'sec', + 'BLOCK_NAME.email.placeholder': 'Email', + 'BLOCK_NAME.password.placeholder': 'Senha', + 'BLOCK_NAME.confirm-password.placeholder': 'Confirme a senha', + 'BLOCK_NAME.phone-number.placeholder': 'Telefone', + 'BLOCK_NAME.verification-code.placeholder': 'Código de verificação', + 'BLOCK_NAME.form.optional': ' (optional) ', + 'BLOCK_NAME.form.submit': 'Submit', + 'BLOCK_NAME.form.save': 'Save', + 'BLOCK_NAME.title.label': 'Title', + 'BLOCK_NAME.title.placeholder': 'Give the target a name', + 'BLOCK_NAME.date.label': 'Start and end date', + 'BLOCK_NAME.placeholder.start': 'Start date', + 'BLOCK_NAME.placeholder.end': 'End date', + 'BLOCK_NAME.goal.label': 'Goal description', + 'BLOCK_NAME.goal.placeholder': 'Please enter your work goals', + 'BLOCK_NAME.standard.label': 'Metrics', + 'BLOCK_NAME.standard.placeholder': 'Please enter a metric', + 'BLOCK_NAME.client.label': 'Client', + 'BLOCK_NAME.label.tooltip': 'Target service object', + 'BLOCK_NAME.client.placeholder': + 'Please describe your customer service, internal customers directly @ Name / job number', + 'BLOCK_NAME.invites.label': 'Inviting critics', + 'BLOCK_NAME.invites.placeholder': 'Please direct @ Name / job number, you can invite up to 5 people', + 'BLOCK_NAME.weight.label': 'Weight', + 'BLOCK_NAME.weight.placeholder': 'Please enter weight', + 'BLOCK_NAME.public.label': 'Target disclosure', + 'BLOCK_NAME.label.help': 'Customers and invitees are shared by default', + 'BLOCK_NAME.radio.public': 'Public', + 'BLOCK_NAME.radio.partially-public': 'Partially public', + 'BLOCK_NAME.radio.private': 'Private', + 'BLOCK_NAME.publicUsers.placeholder': 'Open to', + 'BLOCK_NAME.option.A': 'Colleague A', + 'BLOCK_NAME.option.B': 'Colleague B', + 'BLOCK_NAME.option.C': 'Colleague C', +}; diff --git a/AdvancedForm/src/locales/zh-CN.js b/AdvancedForm/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..d9a4b1deb9b5d6f5aa748d6a7aa85ee087cbd416 --- /dev/null +++ b/AdvancedForm/src/locales/zh-CN.js @@ -0,0 +1,59 @@ +export default { + 'BLOCK_NAME.basic.title': '基础表单', + 'BLOCK_NAME.basic.description': + '表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。', + + 'BLOCK_NAME.email.required': '请输入邮箱地址!', + 'BLOCK_NAME.email.wrong-format': '邮箱地址格式错误!', + 'BLOCK_NAME.userName.required': '请输入用户名!', + 'BLOCK_NAME.password.required': '请输入密码!', + 'BLOCK_NAME.password.twice': '两次输入的密码不匹配!', + 'BLOCK_NAME.strength.msg': '请至少输入 6 个字符。请不要使用容易被猜到的密码。', + 'BLOCK_NAME.strength.strong': '强度:强', + 'BLOCK_NAME.strength.medium': '强度:中', + 'BLOCK_NAME.strength.short': '强度:太短', + 'BLOCK_NAME.confirm-password.required': '请确认密码!', + 'BLOCK_NAME.phone-number.required': '请输入手机号!', + 'BLOCK_NAME.phone-number.wrong-format': '手机号格式错误!', + 'BLOCK_NAME.verification-code.required': '请输入验证码!', + 'BLOCK_NAME.title.required': '请输入标题', + 'BLOCK_NAME.date.required': '请选择起止日期', + 'BLOCK_NAME.goal.required': '请输入目标描述', + 'BLOCK_NAME.standard.required': '请输入衡量标准', + + 'BLOCK_NAME.form.get-captcha': '获取验证码', + 'BLOCK_NAME.captcha.second': '秒', + 'BLOCK_NAME.form.optional': '(选填)', + 'BLOCK_NAME.form.submit': '提交', + 'BLOCK_NAME.form.save': '保存', + 'BLOCK_NAME.email.placeholder': '邮箱', + 'BLOCK_NAME.password.placeholder': '至少6位密码,区分大小写', + 'BLOCK_NAME.confirm-password.placeholder': '确认密码', + 'BLOCK_NAME.phone-number.placeholder': '手机号', + 'BLOCK_NAME.verification-code.placeholder': '验证码', + 'BLOCK_NAME.title.label': '标题', + 'BLOCK_NAME.title.placeholder': '给目标起个名字', + 'BLOCK_NAME.date.label': '起止日期', + 'BLOCK_NAME.placeholder.start': '开始日期', + 'BLOCK_NAME.placeholder.end': '结束日期', + 'BLOCK_NAME.goal.label': '目标描述', + 'BLOCK_NAME.goal.placeholder': '请输入你的阶段性工作目标', + 'BLOCK_NAME.standard.label': '衡量标准', + 'BLOCK_NAME.standard.placeholder': '请输入衡量标准', + 'BLOCK_NAME.client.label': '客户', + 'BLOCK_NAME.label.tooltip': '目标的服务对象', + 'BLOCK_NAME.client.placeholder': '请描述你服务的客户,内部客户直接 @姓名/工号', + 'BLOCK_NAME.invites.label': '邀评人', + 'BLOCK_NAME.invites.placeholder': '请直接 @姓名/工号,最多可邀请 5 人', + 'BLOCK_NAME.weight.label': '权重', + 'BLOCK_NAME.weight.placeholder': '请输入', + 'BLOCK_NAME.public.label': '目标公开', + 'BLOCK_NAME.label.help': '客户、邀评人默认被分享', + 'BLOCK_NAME.radio.public': '公开', + 'BLOCK_NAME.radio.partially-public': '部分公开', + 'BLOCK_NAME.radio.private': '不公开', + 'BLOCK_NAME.publicUsers.placeholder': '公开给', + 'BLOCK_NAME.option.A': '同事甲', + 'BLOCK_NAME.option.B': '同事乙', + 'BLOCK_NAME.option.C': '同事丙', +}; diff --git a/AdvancedForm/src/locales/zh-TW.js b/AdvancedForm/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..d42f8520ecb62730bdca8f6aa83ec32982c05932 --- /dev/null +++ b/AdvancedForm/src/locales/zh-TW.js @@ -0,0 +1,59 @@ +export default { + 'BLOCK_NAME.basic.title': '基礎表單', + 'BLOCK_NAME.basic.description': + '表單頁用於向用戶收集或驗證信息,基礎表單常見於數據項較少的表單場景。', + + 'BLOCK_NAME.email.required': '請輸入郵箱地址!', + 'BLOCK_NAME.email.wrong-format': '郵箱地址格式錯誤!', + 'BLOCK_NAME.userName.required': '請輸入賬戶!', + 'BLOCK_NAME.password.required': '請輸入密碼!', + 'BLOCK_NAME.password.twice': '兩次輸入的密碼不匹配!', + 'BLOCK_NAME.strength.msg': '請至少輸入 6 個字符。請不要使用容易被猜到的密碼。', + 'BLOCK_NAME.strength.strong': '強度:強', + 'BLOCK_NAME.strength.medium': '強度:中', + 'BLOCK_NAME.strength.short': '強度:太短', + 'BLOCK_NAME.confirm-password.required': '請確認密碼!', + 'BLOCK_NAME.phone-number.required': '請輸入手機號!', + 'BLOCK_NAME.phone-number.wrong-format': '手機號格式錯誤!', + 'BLOCK_NAME.verification-code.required': '請輸入驗證碼!', + 'BLOCK_NAME.title.required': '請輸入標題', + 'BLOCK_NAME.date.required': '請選擇起止日期', + 'BLOCK_NAME.goal.required': '請輸入目標描述', + 'BLOCK_NAME.standard.required': '請輸入衡量標淮', + + 'BLOCK_NAME.form.get-captcha': '獲取驗證碼', + 'BLOCK_NAME.captcha.second': '秒', + 'BLOCK_NAME.form.optional': '(選填)', + 'BLOCK_NAME.form.submit': '提交', + 'BLOCK_NAME.form.save': '保存', + 'BLOCK_NAME.email.placeholder': '郵箱', + 'BLOCK_NAME.password.placeholder': '至少6位密碼,區分大小寫', + 'BLOCK_NAME.confirm-password.placeholder': '確認密碼', + 'BLOCK_NAME.phone-number.placeholder': '手機號', + 'BLOCK_NAME.verification-code.placeholder': '驗證碼', + 'BLOCK_NAME.title.label': '標題', + 'BLOCK_NAME.title.placeholder': '給目標起個名字', + 'BLOCK_NAME.date.label': '起止日期', + 'BLOCK_NAME.placeholder.start': '開始日期', + 'BLOCK_NAME.placeholder.end': '結束日期', + 'BLOCK_NAME.goal.label': '目標描述', + 'BLOCK_NAME.goal.placeholder': '請輸入妳的階段性工作目標', + 'BLOCK_NAME.standard.label': '衡量標淮', + 'BLOCK_NAME.standard.placeholder': '請輸入衡量標淮', + 'BLOCK_NAME.client.label': '客戶', + 'BLOCK_NAME.label.tooltip': '目標的服務對象', + 'BLOCK_NAME.client.placeholder': '請描述妳服務的客戶,內部客戶直接 @姓名/工號', + 'BLOCK_NAME.invites.label': '邀評人', + 'BLOCK_NAME.invites.placeholder': '請直接 @姓名/工號,最多可邀請 5 人', + 'BLOCK_NAME.weight.label': '權重', + 'BLOCK_NAME.weight.placeholder': '請輸入', + 'BLOCK_NAME.public.label': '目標公開', + 'BLOCK_NAME.label.help': '客戶、邀評人默認被分享', + 'BLOCK_NAME.radio.public': '公開', + 'BLOCK_NAME.radio.partially-public': '部分公開', + 'BLOCK_NAME.radio.private': '不公開', + 'BLOCK_NAME.publicUsers.placeholder': '公開給', + 'BLOCK_NAME.option.A': '同事甲', + 'BLOCK_NAME.option.B': '同事乙', + 'BLOCK_NAME.option.C': '同事丙', +}; diff --git a/AdvancedForm/src/model.js b/AdvancedForm/src/model.js new file mode 100644 index 0000000000000000000000000000000000000000..d07e01930a93912389fa3f9fd35d121276b3207c --- /dev/null +++ b/AdvancedForm/src/model.js @@ -0,0 +1,15 @@ +import { message } from 'antd'; +import { fakeSubmitForm } from './service'; + +export default { + namespace: 'BLOCK_NAME_CAMEL_CASE', + + state: {}, + + effects: { + *submitAdvancedForm({ payload }, { call }) { + yield call(fakeSubmitForm, payload); + message.success('提交成功'); + }, + }, +}; diff --git a/AdvancedForm/src/service.js b/AdvancedForm/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..77e522c8ca3527da73e4fc1e879705931c277028 --- /dev/null +++ b/AdvancedForm/src/service.js @@ -0,0 +1,8 @@ +import request from 'umi-request'; + +export async function fakeSubmitForm(params) { + return request('/api/BLOCK_NAME/forms', { + method: 'POST', + data: params, + }); +} diff --git a/src/pages/Forms/style.less b/AdvancedForm/src/style.less similarity index 100% rename from src/pages/Forms/style.less rename to AdvancedForm/src/style.less diff --git a/AdvancedProfile/.gitignore b/AdvancedProfile/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/AdvancedProfile/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/AdvancedProfile/.umirc.js b/AdvancedProfile/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/AdvancedProfile/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/AdvancedProfile/README.md b/AdvancedProfile/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9fde77c0432168fd9de1b9174a67ba7732518bd0 --- /dev/null +++ b/AdvancedProfile/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/advancedprofile + +AdvancedProfile + +## Usage + +```sh +umi block add ant-design-pro/advancedprofile +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/AdvancedProfile/package.json b/AdvancedProfile/package.json new file mode 100644 index 0000000000000000000000000000000000000000..65437eb63f4ea64badf6ee14032824c4ab7bc3b6 --- /dev/null +++ b/AdvancedProfile/package.json @@ -0,0 +1,28 @@ +{ + "name": "@umi-block/advanced-profile", + "version": "0.0.1", + "description": "AdvancedProfile", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/advancedprofile" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "classnames": "^2.2.6", + "dva": "^2.4.0", + "lodash-decorators": "^6.0.0", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/AdvancedProfile/snapshot.png b/AdvancedProfile/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..09173fd37a0ddcab8ee8a5429ee0d0d89e364798 Binary files /dev/null and b/AdvancedProfile/snapshot.png differ diff --git a/AdvancedProfile/src/_mock.js b/AdvancedProfile/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..6a34f734f7da4a3879ba6acde2a98e96248f33dc --- /dev/null +++ b/AdvancedProfile/src/_mock.js @@ -0,0 +1,74 @@ +const advancedOperation1 = [ + { + key: 'op1', + type: '订购关系生效', + name: '曲丽丽', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '-', + }, + { + key: 'op2', + type: '财务复审', + name: '付小小', + status: 'reject', + updatedAt: '2017-10-03 19:23:12', + memo: '不通过原因', + }, + { + key: 'op3', + type: '部门初审', + name: '周毛毛', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '-', + }, + { + key: 'op4', + type: '提交订单', + name: '林东东', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '很棒', + }, + { + key: 'op5', + type: '创建订单', + name: '汗牙牙', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '-', + }, +]; + +const advancedOperation2 = [ + { + key: 'op1', + type: '订购关系生效', + name: '曲丽丽', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '-', + }, +]; + +const advancedOperation3 = [ + { + key: 'op1', + type: '创建订单', + name: '汗牙牙', + status: 'agree', + updatedAt: '2017-10-03 19:23:12', + memo: '-', + }, +]; + +const getProfileAdvancedData = { + advancedOperation1, + advancedOperation2, + advancedOperation3, +}; + +export default { + 'GET /api/BLOCK_NAME/advanced': getProfileAdvancedData, +}; diff --git a/AdvancedProfile/src/components/PageHeaderWrapper/index.js b/AdvancedProfile/src/components/PageHeaderWrapper/index.js new file mode 100644 index 0000000000000000000000000000000000000000..165ae2524640af9bfb6a72e918852e8e60480fc7 --- /dev/null +++ b/AdvancedProfile/src/components/PageHeaderWrapper/index.js @@ -0,0 +1,26 @@ +import React from 'react'; +import { FormattedMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { PageHeader } from 'ant-design-pro'; +import styles from './index.less'; + +const PageHeaderWrapper = ({ children, contentWidth, wrapperClassName, top, ...restProps }) => ( + + } + key="pageheader" + {...restProps} + linkElement={Link} + itemRender={item => { + if (item.locale) { + return ; + } + return item.title; + }} + /> + {children ? {children} : null} + +); + +export default PageHeaderWrapper; diff --git a/AdvancedProfile/src/components/PageHeaderWrapper/index.less b/AdvancedProfile/src/components/PageHeaderWrapper/index.less new file mode 100644 index 0000000000000000000000000000000000000000..39a449657a98b039c29e6654fd117267cbb5283a --- /dev/null +++ b/AdvancedProfile/src/components/PageHeaderWrapper/index.less @@ -0,0 +1,11 @@ +@import '~antd/lib/style/themes/default.less'; + +.content { + margin: 24px 24px 0; +} + +@media screen and (max-width: @screen-sm) { + .content { + margin: 24px 0 0; + } +} diff --git a/src/pages/Profile/AdvancedProfile.js b/AdvancedProfile/src/index.js similarity index 94% rename from src/pages/Profile/AdvancedProfile.js rename to AdvancedProfile/src/index.js index 0006f993af920de30a7921cbbd2d2a9af74e66c7..341c0aa39b74b5b99e6b52a64cfd74749cb6d961 100644 --- a/src/pages/Profile/AdvancedProfile.js +++ b/AdvancedProfile/src/index.js @@ -18,9 +18,9 @@ import { Divider, } from 'antd'; import classNames from 'classnames'; -import DescriptionList from '@/components/DescriptionList'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; -import styles from './AdvancedProfile.less'; +import { DescriptionList } from 'ant-design-pro'; +import PageHeaderWrapper from './components/PageHeaderWrapper'; +import styles from './style.less'; const { Step } = Steps; const { Description } = DescriptionList; @@ -180,11 +180,11 @@ const columns = [ }, ]; -@connect(({ profile, loading }) => ({ - profile, - loading: loading.effects['profile/fetchAdvanced'], +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ + BLOCK_NAME_CAMEL_CASE, + loading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchAdvanced'], })) -class AdvancedProfile extends Component { +class PAGE_NAME_UPPER_CAMEL_CASE extends Component { state = { operationkey: 'tab1', stepDirection: 'horizontal', @@ -193,7 +193,7 @@ class AdvancedProfile extends Component { componentDidMount() { const { dispatch } = this.props; dispatch({ - type: 'profile/fetchAdvanced', + type: 'BLOCK_NAME_CAMEL_CASE/fetchAdvanced', }); this.setStepDirection(); @@ -227,8 +227,8 @@ class AdvancedProfile extends Component { render() { const { stepDirection, operationkey } = this.state; - const { profile, loading } = this.props; - const { advancedOperation1, advancedOperation2, advancedOperation3 } = profile; + const { BLOCK_NAME_CAMEL_CASE, loading } = this.props; + const { advancedOperation1, advancedOperation2, advancedOperation3 } = BLOCK_NAME_CAMEL_CASE; const contentList = { tab1: ( ( } + title={} action={ } + title={} > @@ -33,18 +34,18 @@ const IntroduceRow = memo(({ loading, visitData }) => ( total={() => 126560} footer={ } + label={} value={`¥${numeral(12423).format('0,0')}`} /> } contentHeight={46} > - + 12% - + 11% @@ -54,10 +55,10 @@ const IntroduceRow = memo(({ loading, visitData }) => ( } + title={} action={ } + title={} > @@ -65,7 +66,7 @@ const IntroduceRow = memo(({ loading, visitData }) => ( total={numeral(8846).format('0,0')} footer={ } + label={} value={numeral(1234).format('0,0')} /> } @@ -78,10 +79,10 @@ const IntroduceRow = memo(({ loading, visitData }) => ( } + title={} action={ } + title={} > @@ -91,7 +92,7 @@ const IntroduceRow = memo(({ loading, visitData }) => ( } @@ -109,13 +110,13 @@ const IntroduceRow = memo(({ loading, visitData }) => ( bordered={false} title={ } action={ } + title={} > @@ -124,11 +125,11 @@ const IntroduceRow = memo(({ loading, visitData }) => ( footer={ - + 12% - + 11% diff --git a/src/pages/Dashboard/OfflineData.js b/Analysis/src/components/OfflineData.js similarity index 80% rename from src/pages/Dashboard/OfflineData.js rename to Analysis/src/components/OfflineData.js index f7d06ef07b8f10f93a86320b3b17d081816a462f..274c1e0d4157c373ee8e0e01f32078e1c6dc720d 100755 --- a/src/pages/Dashboard/OfflineData.js +++ b/Analysis/src/components/OfflineData.js @@ -1,9 +1,10 @@ import React, { memo } from 'react'; import { Card, Tabs, Row, Col } from 'antd'; import { formatMessage, FormattedMessage } from 'umi/locale'; -import styles from './Analysis.less'; -import { TimelineChart, Pie } from '@/components/Charts'; -import NumberInfo from '@/components/NumberInfo'; +import { Charts, NumberInfo } from 'ant-design-pro'; +import styles from '../style.less'; + +const { TimelineChart, Pie } = Charts; const CustomTab = ({ data, currentTabKey: currentKey }) => ( @@ -11,7 +12,7 @@ const CustomTab = ({ data, currentTabKey: currentKey }) => ( + } gap={2} total={`${data.cvr * 100}%`} @@ -50,8 +51,8 @@ const OfflineData = memo( height={400} data={offlineChartData} titleMap={{ - y1: formatMessage({ id: 'app.analysis.traffic' }), - y2: formatMessage({ id: 'app.analysis.payments' }), + y1: formatMessage({ id: 'BLOCK_NAME.analysis.traffic' }), + y2: formatMessage({ id: 'BLOCK_NAME.analysis.payments' }), }} /> diff --git a/src/components/PageLoading/index.js b/Analysis/src/components/PageLoading/index.js similarity index 100% rename from src/components/PageLoading/index.js rename to Analysis/src/components/PageLoading/index.js diff --git a/Analysis/src/components/ProportionSales.js b/Analysis/src/components/ProportionSales.js new file mode 100755 index 0000000000000000000000000000000000000000..51d44be2070a1fa9c332dd90fd12766b5df15747 --- /dev/null +++ b/Analysis/src/components/ProportionSales.js @@ -0,0 +1,65 @@ +import React, { memo } from 'react'; +import { Card, Radio } from 'antd'; +import { Charts } from 'ant-design-pro'; +import { FormattedMessage } from 'umi/locale'; +import styles from '../style.less'; +import Yuan from '../utils/Yuan'; + +const { Pie } = Charts; + +const ProportionSales = memo( + ({ dropdownGroup, salesType, loading, salesPieData, handleChangeSalesType }) => ( + + } + bodyStyle={{ padding: 24 }} + extra={ + + {dropdownGroup} + + + + + + + + + + + + + + + } + style={{ marginTop: 24 }} + > + + + + + } + total={() => {salesPieData.reduce((pre, now) => now.y + pre, 0)}} + data={salesPieData} + valueFormat={value => {value}} + height={248} + lineWidth={4} + /> + + + ) +); + +export default ProportionSales; diff --git a/src/pages/Dashboard/SalesCard.js b/Analysis/src/components/SalesCard.js similarity index 82% rename from src/pages/Dashboard/SalesCard.js rename to Analysis/src/components/SalesCard.js index 3ab577757067c329a79028cbec08deb3dfc61787..893314eb075fb6511ad8233e366d94054bbaa592 100755 --- a/src/pages/Dashboard/SalesCard.js +++ b/Analysis/src/components/SalesCard.js @@ -2,8 +2,10 @@ import React, { memo } from 'react'; import { Row, Col, Card, Tabs, DatePicker } from 'antd'; import { FormattedMessage, formatMessage } from 'umi/locale'; import numeral from 'numeral'; -import styles from './Analysis.less'; -import { Bar } from '@/components/Charts'; +import { Charts } from 'ant-design-pro'; +import styles from '../style.less'; + +const { Bar } = Charts; const { RangePicker } = DatePicker; const { TabPane } = Tabs; @@ -11,7 +13,7 @@ const { TabPane } = Tabs; const rankingListData = []; for (let i = 0; i < 7; i += 1) { rankingListData.push({ - title: formatMessage({ id: 'app.analysis.test' }, { no: i }), + title: formatMessage({ id: 'BLOCK_NAME.analysis.test' }, { no: i }), total: 323234, }); } @@ -25,16 +27,16 @@ const SalesCard = memo( selectDate('today')}> - + selectDate('week')}> - + selectDate('month')}> - + selectDate('year')}> - + } + tab={} key="sales" > @@ -58,7 +60,7 @@ const SalesCard = memo( height={295} title={ } @@ -70,7 +72,7 @@ const SalesCard = memo( @@ -96,7 +98,7 @@ const SalesCard = memo( } + tab={} key="views" > @@ -106,7 +108,7 @@ const SalesCard = memo( height={292} title={ } @@ -118,7 +120,7 @@ const SalesCard = memo( diff --git a/src/pages/Dashboard/TopSearch.js b/Analysis/src/components/TopSearch.js similarity index 69% rename from src/pages/Dashboard/TopSearch.js rename to Analysis/src/components/TopSearch.js index 4e75ea7d51ebba6a5d52e336c24d318f8e5d5a41..9946b2ad5763b7bcde5ddda74fa202e467660f20 100755 --- a/src/pages/Dashboard/TopSearch.js +++ b/Analysis/src/components/TopSearch.js @@ -1,35 +1,35 @@ import React, { memo } from 'react'; import { Row, Col, Table, Tooltip, Card, Icon } from 'antd'; import { FormattedMessage } from 'umi/locale'; -import Trend from '@/components/Trend'; +import { Trend, NumberInfo, Charts } from 'ant-design-pro'; import numeral from 'numeral'; -import styles from './Analysis.less'; -import NumberInfo from '@/components/NumberInfo'; -import { MiniArea } from '@/components/Charts'; +import styles from '../style.less'; + +const { MiniArea } = Charts; const columns = [ { - title: , + title: , dataIndex: 'index', key: 'index', }, { title: ( - + ), dataIndex: 'keyword', key: 'keyword', render: text => {text}, }, { - title: , + title: , dataIndex: 'count', key: 'count', sorter: (a, b) => a.count - b.count, className: styles.alignRight, }, { - title: , + title: , dataIndex: 'range', key: 'range', sorter: (a, b) => a.range - b.range, @@ -47,7 +47,7 @@ const TopSearch = memo(({ loading, visitData2, searchData, dropdownGroup }) => ( loading={loading} bordered={false} title={ - + } extra={dropdownGroup} style={{ marginTop: 24 }} @@ -57,9 +57,9 @@ const TopSearch = memo(({ loading, visitData2, searchData, dropdownGroup }) => ( - + } + title={} > @@ -77,11 +77,11 @@ const TopSearch = memo(({ loading, visitData2, searchData, dropdownGroup }) => ( subTitle={ } + title={} > diff --git a/src/pages/Dashboard/Analysis.js b/Analysis/src/index.js similarity index 62% rename from src/pages/Dashboard/Analysis.js rename to Analysis/src/index.js index 0b85db70bb39bb5923a209d432b9f7fe54528638..d175e701cf2f48ce9bb371d6eccfaebb7d83c974 100644 --- a/src/pages/Dashboard/Analysis.js +++ b/Analysis/src/index.js @@ -2,23 +2,22 @@ import React, { Component, Suspense } from 'react'; import { connect } from 'dva'; import { Row, Col, Icon, Menu, Dropdown } from 'antd'; -import GridContent from '@/components/PageHeaderWrapper/GridContent'; -import { getTimeDistance } from '@/utils/utils'; +import { getTimeDistance } from './utils/utils'; -import styles from './Analysis.less'; -import PageLoading from '@/components/PageLoading'; +import styles from './style.less'; +import PageLoading from './components/PageLoading'; -const IntroduceRow = React.lazy(() => import('./IntroduceRow')); -const SalesCard = React.lazy(() => import('./SalesCard')); -const TopSearch = React.lazy(() => import('./TopSearch')); -const ProportionSales = React.lazy(() => import('./ProportionSales')); -const OfflineData = React.lazy(() => import('./OfflineData')); +const IntroduceRow = React.lazy(() => import('./components/IntroduceRow')); +const SalesCard = React.lazy(() => import('./components/SalesCard')); +const TopSearch = React.lazy(() => import('./components/TopSearch')); +const ProportionSales = React.lazy(() => import('./components/ProportionSales')); +const OfflineData = React.lazy(() => import('./components/OfflineData')); -@connect(({ chart, loading }) => ({ - chart, - loading: loading.effects['chart/fetch'], +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ + BLOCK_NAME_CAMEL_CASE, + loading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetch'], })) -class Analysis extends Component { +class PAGE_NAME_UPPER_CAMEL_CASE extends Component { state = { salesType: 'all', currentTabKey: '', @@ -29,7 +28,7 @@ class Analysis extends Component { const { dispatch } = this.props; this.reqRef = requestAnimationFrame(() => { dispatch({ - type: 'chart/fetch', + type: 'BLOCK_NAME_CAMEL_CASE/fetch', }); }); } @@ -37,7 +36,7 @@ class Analysis extends Component { componentWillUnmount() { const { dispatch } = this.props; dispatch({ - type: 'chart/clear', + type: 'BLOCK_NAME_CAMEL_CASE/clear', }); cancelAnimationFrame(this.reqRef); clearTimeout(this.timeoutId); @@ -62,7 +61,7 @@ class Analysis extends Component { }); dispatch({ - type: 'chart/fetchSalesData', + type: 'BLOCK_NAME_CAMEL_CASE/fetchSalesData', }); }; @@ -73,7 +72,7 @@ class Analysis extends Component { }); dispatch({ - type: 'chart/fetchSalesData', + type: 'BLOCK_NAME_CAMEL_CASE/fetchSalesData', }); }; @@ -94,7 +93,7 @@ class Analysis extends Component { render() { const { rangePickerValue, salesType, currentTabKey } = this.state; - const { chart, loading } = this.props; + const { BLOCK_NAME_CAMEL_CASE, loading } = this.props; const { visitData, visitData2, @@ -105,7 +104,7 @@ class Analysis extends Component { salesTypeData, salesTypeDataOnline, salesTypeDataOffline, - } = chart; + } = BLOCK_NAME_CAMEL_CASE; let salesPieData; if (salesType === 'all') { salesPieData = salesTypeData; @@ -130,7 +129,7 @@ class Analysis extends Component { const activeKey = currentTabKey || (offlineData[0] && offlineData[0].name); return ( - + }> @@ -144,32 +143,30 @@ class Analysis extends Component { selectDate={this.selectDate} /> - - - - - - - - - - - - - - + + + + + + + + + + + + - + ); } } -export default Analysis; +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/Analysis/src/locales/en-US.js b/Analysis/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..dc611a18c309b8b0681b951229f0c9e8de50235c --- /dev/null +++ b/Analysis/src/locales/en-US.js @@ -0,0 +1,34 @@ +export default { + 'BLOCK_NAME.analysis.test': 'Gongzhuan No.{no} shop', + 'BLOCK_NAME.analysis.introduce': 'Introduce', + 'BLOCK_NAME.analysis.total-sales': 'Total Sales', + 'BLOCK_NAME.analysis.day-sales': 'Daily Sales', + 'BLOCK_NAME.analysis.visits': 'Visits', + 'BLOCK_NAME.analysis.visits-trend': 'Visits Trend', + 'BLOCK_NAME.analysis.visits-ranking': 'Visits Ranking', + 'BLOCK_NAME.analysis.day-visits': 'Daily Visits', + 'BLOCK_NAME.analysis.week': 'WoW Change', + 'BLOCK_NAME.analysis.day': 'DoD Change', + 'BLOCK_NAME.analysis.payments': 'Payments', + 'BLOCK_NAME.analysis.conversion-rate': 'Conversion Rate', + 'BLOCK_NAME.analysis.operational-effect': 'Operational Effect', + 'BLOCK_NAME.analysis.sales-trend': 'Stores Sales Trend', + 'BLOCK_NAME.analysis.sales-ranking': 'Sales Ranking', + 'BLOCK_NAME.analysis.all-year': 'All Year', + 'BLOCK_NAME.analysis.all-month': 'All Month', + 'BLOCK_NAME.analysis.all-week': 'All Week', + 'BLOCK_NAME.analysis.all-day': 'All day', + 'BLOCK_NAME.analysis.search-users': 'Search Users', + 'BLOCK_NAME.analysis.per-capita-search': 'Per Capita Search', + 'BLOCK_NAME.analysis.online-top-search': 'Online Top Search', + 'BLOCK_NAME.analysis.the-proportion-of-sales': 'The Proportion Of Sales', + 'BLOCK_NAME.channel.all': 'ALL', + 'BLOCK_NAME.channel.online': 'Online', + 'BLOCK_NAME.channel.stores': 'Stores', + 'BLOCK_NAME.analysis.sales': 'Sales', + 'BLOCK_NAME.analysis.traffic': 'Traffic', + 'BLOCK_NAME.table.rank': 'Rank', + 'BLOCK_NAME.table.search-keyword': 'Keyword', + 'BLOCK_NAME.table.users': 'Users', + 'BLOCK_NAME.table.weekly-range': 'Weekly Range', +}; diff --git a/Analysis/src/locales/pt-BR.js b/Analysis/src/locales/pt-BR.js new file mode 100644 index 0000000000000000000000000000000000000000..ead8d95952b2bc7d2b62191b3d13edf5223794ba --- /dev/null +++ b/Analysis/src/locales/pt-BR.js @@ -0,0 +1,34 @@ +export default { + 'BLOCK_NAME.analysis.test': 'Gongzhuan No.{no} shop', + 'BLOCK_NAME.analysis.introduce': 'Introduzir', + 'BLOCK_NAME.analysis.total-sales': 'Vendas Totais', + 'BLOCK_NAME.analysis.day-sales': 'Vendas do Dia', + 'BLOCK_NAME.analysis.visits': 'Visitas', + 'BLOCK_NAME.analysis.visits-trend': 'Tendência de Visitas', + 'BLOCK_NAME.analysis.visits-ranking': 'Ranking de Visitas', + 'BLOCK_NAME.analysis.day-visits': 'Visitas do Dia', + 'BLOCK_NAME.analysis.week': 'Taxa Semanal', + 'BLOCK_NAME.analysis.day': 'Taxa Diária', + 'BLOCK_NAME.analysis.payments': 'Pagamentos', + 'BLOCK_NAME.analysis.conversion-rate': 'Taxa de Conversão', + 'BLOCK_NAME.analysis.operational-effect': 'Efeito Operacional', + 'BLOCK_NAME.analysis.sales-trend': 'Tendência de Vendas das Lojas', + 'BLOCK_NAME.analysis.sales-ranking': 'Ranking de Vendas', + 'BLOCK_NAME.$2': 'Todo ano', + 'BLOCK_NAME.analysis.all-month': 'Todo mês', + 'BLOCK_NAME.analysis.all-week': 'Toda semana', + 'BLOCK_NAME.analysis.all-day': 'Todo dia', + 'BLOCK_NAME.analysis.search-users': 'Pesquisa de Usuários', + 'BLOCK_NAME.analysis.per-capita-search': 'Busca Per Capta', + 'BLOCK_NAME.analysis.online-top-search': 'Mais Buscadas Online', + 'BLOCK_NAME.analysis.the-proportion-of-sales': 'The Proportion Of Sales', + 'BLOCK_NAME.channel.all': 'Tudo', + 'BLOCK_NAME.channel.online': 'Online', + 'BLOCK_NAME.channel.stores': 'Lojas', + 'BLOCK_NAME.analysis.sales': 'Vendas', + 'BLOCK_NAME.analysis.traffic': 'Tráfego', + 'BLOCK_NAME.table.rank': 'Rank', + 'BLOCK_NAME.table.search-keyword': 'Palavra chave', + 'BLOCK_NAME.table.users': 'Usuários', + 'BLOCK_NAME.table.weekly-range': 'Faixa Semanal', +}; diff --git a/Analysis/src/locales/zh-CN.js b/Analysis/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..1c1620ef5a85b1cfa04338d9b6cb24356bd48478 --- /dev/null +++ b/Analysis/src/locales/zh-CN.js @@ -0,0 +1,34 @@ +export default { + 'BLOCK_NAME.analysis.test': '工专路 {no} 号店', + 'BLOCK_NAME.analysis.introduce': '指标说明', + 'BLOCK_NAME.analysis.total-sales': '总销售额', + 'BLOCK_NAME.analysis.day-sales': '日销售额', + 'BLOCK_NAME.analysis.visits': '访问量', + 'BLOCK_NAME.analysis.visits-trend': '访问量趋势', + 'BLOCK_NAME.analysis.visits-ranking': '门店访问量排名', + 'BLOCK_NAME.analysis.day-visits': '日访问量', + 'BLOCK_NAME.analysis.week': '周同比', + 'BLOCK_NAME.analysis.day': '日同比', + 'BLOCK_NAME.analysis.payments': '支付笔数', + 'BLOCK_NAME.analysis.conversion-rate': '转化率', + 'BLOCK_NAME.analysis.operational-effect': '运营活动效果', + 'BLOCK_NAME.analysis.sales-trend': '销售趋势', + 'BLOCK_NAME.analysis.sales-ranking': '门店销售额排名', + 'BLOCK_NAME.analysis.all-year': '全年', + 'BLOCK_NAME.analysis.all-month': '本月', + 'BLOCK_NAME.analysis.all-week': '本周', + 'BLOCK_NAME.analysis.all-day': '今日', + 'BLOCK_NAME.analysis.search-users': '搜索用户数', + 'BLOCK_NAME.analysis.per-capita-search': '人均搜索次数', + 'BLOCK_NAME.analysis.online-top-search': '线上热门搜索', + 'BLOCK_NAME.analysis.the-proportion-of-sales': '销售额类别占比', + 'BLOCK_NAME.channel.all': '全部渠道', + 'BLOCK_NAME.channel.online': '线上', + 'BLOCK_NAME.channel.stores': '门店', + 'BLOCK_NAME.analysis.sales': '销售额', + 'BLOCK_NAME.analysis.traffic': '客流量', + 'BLOCK_NAME.table.rank': '排名', + 'BLOCK_NAME.table.search-keyword': '搜索关键词', + 'BLOCK_NAME.table.users': '用户数', + 'BLOCK_NAME.table.weekly-range': '周涨幅', +}; diff --git a/Analysis/src/locales/zh-TW.js b/Analysis/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..2238e4413000dc1c9aae2b48170ab9b56ee982b3 --- /dev/null +++ b/Analysis/src/locales/zh-TW.js @@ -0,0 +1,34 @@ +export default { + 'BLOCK_NAME.analysis.test': '工專路 {no} 號店', + 'BLOCK_NAME.analysis.introduce': '指標說明', + 'BLOCK_NAME.analysis.total-sales': '總銷售額', + 'BLOCK_NAME.analysis.day-sales': '日銷售額', + 'BLOCK_NAME.analysis.visits': '訪問量', + 'BLOCK_NAME.analysis.visits-trend': '訪問量趨勢', + 'BLOCK_NAME.analysis.visits-ranking': '門店訪問量排名', + 'BLOCK_NAME.analysis.day-visits': '日訪問量', + 'BLOCK_NAME.analysis.week': '周同比', + 'BLOCK_NAME.analysis.day': '日同比', + 'BLOCK_NAME.analysis.payments': '支付筆數', + 'BLOCK_NAME.analysis.conversion-rate': '轉化率', + 'BLOCK_NAME.analysis.operational-effect': '運營活動效果', + 'BLOCK_NAME.analysis.sales-trend': '銷售趨勢', + 'BLOCK_NAME.analysis.sales-ranking': '門店銷售額排名', + 'BLOCK_NAME.analysis.all-year': '全年', + 'BLOCK_NAME.analysis.all-month': '本月', + 'BLOCK_NAME.analysis.all-week': '本周', + 'BLOCK_NAME.analysis.all-day': '今日', + 'BLOCK_NAME.analysis.search-users': '搜索用戶數', + 'BLOCK_NAME.analysis.per-capita-search': '人均搜索次數', + 'BLOCK_NAME.analysis.online-top-search': '線上熱門搜索', + 'BLOCK_NAME.analysis.the-proportion-of-sales': '銷售額類別占比', + 'BLOCK_NAME.channel.all': '全部渠道', + 'BLOCK_NAME.channel.online': '線上', + 'BLOCK_NAME.channel.stores': '門店', + 'BLOCK_NAME.analysis.sales': '銷售額', + 'BLOCK_NAME.analysis.traffic': '客流量', + 'BLOCK_NAME.table.rank': '排名', + 'BLOCK_NAME.table.search-keyword': '搜索關鍵詞', + 'BLOCK_NAME.table.users': '用戶數', + 'BLOCK_NAME.table.weekly-range': '周漲幅', +}; diff --git a/src/pages/Dashboard/models/chart.js b/Analysis/src/model.js similarity index 93% rename from src/pages/Dashboard/models/chart.js rename to Analysis/src/model.js index 8dfe4a93f5b9b1efbc957fc7034e9949b67f1d29..4e062cc3d5c754a193a46a7890998a469b23623a 100644 --- a/src/pages/Dashboard/models/chart.js +++ b/Analysis/src/model.js @@ -1,7 +1,7 @@ -import { fakeChartData } from '@/services/api'; +import { fakeChartData } from './service'; export default { - namespace: 'chart', + namespace: 'BLOCK_NAME_CAMEL_CASE', state: { visitData: [], diff --git a/Analysis/src/service.js b/Analysis/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..65a1eb216b35a29d86124f9a0810df99e5e16845 --- /dev/null +++ b/Analysis/src/service.js @@ -0,0 +1,5 @@ +import request from 'umi-request'; + +export async function fakeChartData() { + return request('/api/BLOCK_NAME/fake_chart_data'); +} diff --git a/src/pages/Dashboard/Analysis.less b/Analysis/src/style.less similarity index 89% rename from src/pages/Dashboard/Analysis.less rename to Analysis/src/style.less index 70877d6636cb5cffdadd44e242776cbdd4fdd663..4df48a03b85e6b8933688e478095e0f84d38ca17 100644 --- a/src/pages/Dashboard/Analysis.less +++ b/Analysis/src/style.less @@ -1,5 +1,5 @@ @import '~antd/lib/style/themes/default.less'; -@import '~@/utils/utils.less'; +@import './utils/utils.less'; .iconGroup { i { @@ -134,25 +134,6 @@ } } -.twoColLayout { - .salesCard { - height: calc(100% - 24px); - } - div[class^='ant-col']:last-child { - right: 0\9; - height: 100%\9; - position: absolute\9; - } - :global { - .ant-row { - display: flex; - display: block\9; - flex-flow: row wrap; - position: relative\9; - } - } -} - .trendText { margin-left: 8px; color: @heading-color; diff --git a/src/utils/Yuan.js b/Analysis/src/utils/Yuan.js similarity index 90% rename from src/utils/Yuan.js rename to Analysis/src/utils/Yuan.js index 434a57fb7cfc547015cfff71ac427b85be27817b..415e95574b059a85ba89116446f6f72620e34bdd 100644 --- a/src/utils/Yuan.js +++ b/Analysis/src/utils/Yuan.js @@ -1,5 +1,5 @@ import React from 'react'; -import { yuan } from '@/components/Charts'; +import { yuan } from 'ant-design-pro/lib/Charts'; /** * 减少使用 dangerouslySetInnerHTML */ diff --git a/Analysis/src/utils/utils.js b/Analysis/src/utils/utils.js new file mode 100644 index 0000000000000000000000000000000000000000..6e77bd481b045873e3b5853bca1fb361e02cd115 --- /dev/null +++ b/Analysis/src/utils/utils.js @@ -0,0 +1,50 @@ +import moment from 'moment'; + +export function fixedZero(val) { + return val * 1 < 10 ? `0${val}` : val; +} + +export function getTimeDistance(type) { + const now = new Date(); + const oneDay = 1000 * 60 * 60 * 24; + + if (type === 'today') { + now.setHours(0); + now.setMinutes(0); + now.setSeconds(0); + return [moment(now), moment(now.getTime() + (oneDay - 1000))]; + } + + if (type === 'week') { + let day = now.getDay(); + now.setHours(0); + now.setMinutes(0); + now.setSeconds(0); + + if (day === 0) { + day = 6; + } else { + day -= 1; + } + + const beginTime = now.getTime() - day * oneDay; + + return [moment(beginTime), moment(beginTime + (7 * oneDay - 1000))]; + } + + if (type === 'month') { + const year = now.getFullYear(); + const month = now.getMonth(); + const nextDate = moment(now).add(1, 'months'); + const nextYear = nextDate.year(); + const nextMonth = nextDate.month(); + + return [ + moment(`${year}-${fixedZero(month + 1)}-01 00:00:00`), + moment(moment(`${nextYear}-${fixedZero(nextMonth + 1)}-01 00:00:00`).valueOf() - 1000), + ]; + } + + const year = now.getFullYear(); + return [moment(`${year}-01-01 00:00:00`), moment(`${year}-12-31 23:59:59`)]; +} diff --git a/src/utils/utils.less b/Analysis/src/utils/utils.less similarity index 100% rename from src/utils/utils.less rename to Analysis/src/utils/utils.less diff --git a/BasicForm/.gitignore b/BasicForm/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/BasicForm/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/BasicForm/.umirc.js b/BasicForm/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/BasicForm/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/BasicForm/README.md b/BasicForm/README.md new file mode 100644 index 0000000000000000000000000000000000000000..69953537b61aaf96956d40ff11f1a7e5cd499ec8 --- /dev/null +++ b/BasicForm/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/basicform + +BasicForm + +## Usage + +```sh +umi block add ant-design-pro/basicform +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/BasicForm/package.json b/BasicForm/package.json new file mode 100644 index 0000000000000000000000000000000000000000..1f96d53fc5d3818656c3de984a31757e0a34dc2c --- /dev/null +++ b/BasicForm/package.json @@ -0,0 +1,26 @@ +{ + "name": "@umi-block/basic-form", + "version": "0.0.1", + "description": "BasicForm", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/basicform" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "dva": "^2.4.0", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/BasicForm/snapshot.png b/BasicForm/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..587cbcbf72eeda1e384d233af0dee728274922b3 Binary files /dev/null and b/BasicForm/snapshot.png differ diff --git a/BasicForm/src/_mock.js b/BasicForm/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..8e7996deae35737ca576735528af9f6eaa281b98 --- /dev/null +++ b/BasicForm/src/_mock.js @@ -0,0 +1,5 @@ +export default { + 'POST /api/BLOCK_NAME/forms': (req, res) => { + res.send({ message: 'Ok' }); + }, +}; diff --git a/BasicForm/src/components/PageHeaderWrapper/index.js b/BasicForm/src/components/PageHeaderWrapper/index.js new file mode 100644 index 0000000000000000000000000000000000000000..c11873f2c8c24d44391261910d5adb52ab916d1a --- /dev/null +++ b/BasicForm/src/components/PageHeaderWrapper/index.js @@ -0,0 +1,25 @@ +import React from 'react'; +import { FormattedMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { PageHeader } from 'ant-design-pro'; +import styles from './index.less'; + +const PageHeaderWrapper = ({ children, wrapperClassName, ...restProps }) => ( + + } + key="pageheader" + {...restProps} + linkElement={Link} + itemRender={item => { + if (item.locale) { + return ; + } + return item.title; + }} + /> + {children ? {children} : null} + +); + +export default PageHeaderWrapper; diff --git a/BasicForm/src/components/PageHeaderWrapper/index.less b/BasicForm/src/components/PageHeaderWrapper/index.less new file mode 100644 index 0000000000000000000000000000000000000000..39a449657a98b039c29e6654fd117267cbb5283a --- /dev/null +++ b/BasicForm/src/components/PageHeaderWrapper/index.less @@ -0,0 +1,11 @@ +@import '~antd/lib/style/themes/default.less'; + +.content { + margin: 24px 24px 0; +} + +@media screen and (max-width: @screen-sm) { + .content { + margin: 24px 0 0; + } +} diff --git a/src/pages/Forms/BasicForm.js b/BasicForm/src/index.js similarity index 66% rename from src/pages/Forms/BasicForm.js rename to BasicForm/src/index.js index 55833150a1ed63d053e894968d35ac548c3129ae..bdef2fee1739adaf2cc34e920a96293d805dffd9 100644 --- a/src/pages/Forms/BasicForm.js +++ b/BasicForm/src/index.js @@ -13,7 +13,7 @@ import { Icon, Tooltip, } from 'antd'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; +import PageHeaderWrapper from './components/PageHeaderWrapper'; import styles from './style.less'; const FormItem = Form.Item; @@ -22,17 +22,17 @@ const { RangePicker } = DatePicker; const { TextArea } = Input; @connect(({ loading }) => ({ - submitting: loading.effects['form/submitRegularForm'], + submitting: loading.effects['BLOCK_NAME_CAMEL_CASE/submitRegularForm'], })) @Form.create() -class BasicForms extends PureComponent { +class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { handleSubmit = e => { const { dispatch, form } = this.props; e.preventDefault(); form.validateFieldsAndScroll((err, values) => { if (!err) { dispatch({ - type: 'form/submitRegularForm', + type: 'BLOCK_NAME_CAMEL_CASE/submitRegularForm', payload: values, }); } @@ -66,67 +66,67 @@ class BasicForms extends PureComponent { return ( } - content={} + title={} + content={} > - }> + }> {getFieldDecorator('title', { rules: [ { required: true, - message: formatMessage({ id: 'validation.title.required' }), + message: formatMessage({ id: 'BLOCK_NAME.title.required' }), }, ], - })()} + })()} - }> + }> {getFieldDecorator('date', { rules: [ { required: true, - message: formatMessage({ id: 'validation.date.required' }), + message: formatMessage({ id: 'BLOCK_NAME.date.required' }), }, ], })( )} - }> + }> {getFieldDecorator('goal', { rules: [ { required: true, - message: formatMessage({ id: 'validation.goal.required' }), + message: formatMessage({ id: 'BLOCK_NAME.goal.required' }), }, ], })( )} - }> + }> {getFieldDecorator('standard', { rules: [ { required: true, - message: formatMessage({ id: 'validation.standard.required' }), + message: formatMessage({ id: 'BLOCK_NAME.standard.required' }), }, ], })( )} @@ -135,10 +135,10 @@ class BasicForms extends PureComponent { {...formItemLayout} label={ - + - - }> + + }> @@ -146,38 +146,38 @@ class BasicForms extends PureComponent { } > {getFieldDecorator('client')( - + )} - + - + } > {getFieldDecorator('invites')( - + )} - + - + } > {getFieldDecorator('weight')( @@ -186,8 +186,8 @@ class BasicForms extends PureComponent { } - help={} + label={} + help={} > {getFieldDecorator('public', { @@ -195,13 +195,13 @@ class BasicForms extends PureComponent { })( - + - + - + )} @@ -209,20 +209,20 @@ class BasicForms extends PureComponent { {getFieldDecorator('publicUsers')( - + - + - + )} @@ -231,10 +231,10 @@ class BasicForms extends PureComponent { - + - + @@ -244,4 +244,4 @@ class BasicForms extends PureComponent { } } -export default BasicForms; +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/BasicForm/src/locales/en-US.js b/BasicForm/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..3356dda0f90eaa80e52b8bc4bd9002f62d9d4bc8 --- /dev/null +++ b/BasicForm/src/locales/en-US.js @@ -0,0 +1,61 @@ +export default { + 'BLOCK_NAME.basic.title': 'Basic form', + 'BLOCK_NAME.basic.description': + 'Form pages are used to collect or verify information to users, and basic forms are common in scenarios where there are fewer data items.', + + 'BLOCK_NAME.email.required': 'Please enter your email!', + 'BLOCK_NAME.email.wrong-format': 'The email address is in the wrong format!', + 'BLOCK_NAME.userName.required': 'Please enter your userName!', + 'BLOCK_NAME.password.required': 'Please enter your password!', + 'BLOCK_NAME.password.twice': 'The passwords entered twice do not match!', + 'BLOCK_NAME.strength.msg': + "Please enter at least 6 characters and don't use passwords that are easy to guess.", + 'BLOCK_NAME.strength.strong': 'Strength: strong', + 'BLOCK_NAME.strength.medium': 'Strength: medium', + 'BLOCK_NAME.strength.short': 'Strength: too short', + 'BLOCK_NAME.confirm-password.required': 'Please confirm your password!', + 'BLOCK_NAME.phone-number.required': 'Please enter your phone number!', + 'BLOCK_NAME.phone-number.wrong-format': 'Malformed phone number!', + 'BLOCK_NAME.verification-code.required': 'Please enter the verification code!', + 'BLOCK_NAME.title.required': 'Please enter a title', + 'BLOCK_NAME.date.required': 'Please select the start and end date', + 'BLOCK_NAME.goal.required': 'Please enter a description of the goal', + 'BLOCK_NAME.standard.required': 'Please enter a metric', + + 'BLOCK_NAME.form.get-captcha': 'Get Captcha', + 'BLOCK_NAME.captcha.second': 'sec', + 'BLOCK_NAME.form.optional': ' (optional) ', + 'BLOCK_NAME.form.submit': 'Submit', + 'BLOCK_NAME.form.save': 'Save', + 'BLOCK_NAME.email.placeholder': 'Email', + 'BLOCK_NAME.password.placeholder': 'Password', + 'BLOCK_NAME.confirm-password.placeholder': 'Confirm password', + 'BLOCK_NAME.phone-number.placeholder': 'Phone number', + 'BLOCK_NAME.verification-code.placeholder': 'Verification code', + 'BLOCK_NAME.title.label': 'Title', + 'BLOCK_NAME.title.placeholder': 'Give the target a name', + 'BLOCK_NAME.date.label': 'Start and end date', + 'BLOCK_NAME.placeholder.start': 'Start date', + 'BLOCK_NAME.placeholder.end': 'End date', + 'BLOCK_NAME.goal.label': 'Goal description', + 'BLOCK_NAME.goal.placeholder': 'Please enter your work goals', + 'BLOCK_NAME.standard.label': 'Metrics', + 'BLOCK_NAME.standard.placeholder': 'Please enter a metric', + 'BLOCK_NAME.client.label': 'Client', + 'BLOCK_NAME.label.tooltip': 'Target service object', + 'BLOCK_NAME.client.placeholder': + 'Please describe your customer service, internal customers directly @ Name / job number', + 'BLOCK_NAME.invites.label': 'Inviting critics', + 'BLOCK_NAME.invites.placeholder': 'Please direct @ Name / job number, you can invite up to 5 people', + 'BLOCK_NAME.weight.label': 'Weight', + 'BLOCK_NAME.weight.placeholder': 'Please enter weight', + 'BLOCK_NAME.public.label': 'Target disclosure', + 'BLOCK_NAME.label.help': 'Customers and invitees are shared by default', + 'BLOCK_NAME.radio.public': 'Public', + 'BLOCK_NAME.radio.partially-public': 'Partially public', + 'BLOCK_NAME.radio.private': 'Private', + 'BLOCK_NAME.publicUsers.placeholder': 'Open to', + 'BLOCK_NAME.option.A': 'Colleague A', + 'BLOCK_NAME.option.B': 'Colleague B', + 'BLOCK_NAME.option.C': 'Colleague C', +}; diff --git a/BasicForm/src/locales/pt-BR.js b/BasicForm/src/locales/pt-BR.js new file mode 100644 index 0000000000000000000000000000000000000000..1cc9013111adbea37ac80892f11b28d487566f72 --- /dev/null +++ b/BasicForm/src/locales/pt-BR.js @@ -0,0 +1,57 @@ +export default { + 'BLOCK_NAME.basic.title': 'Basic form', + 'BLOCK_NAME.basic.description': + 'Form pages are used to collect or verify information to users, and basic forms are common in scenarios where there are fewer data items.', + + 'BLOCK_NAME.email.required': 'Por favor insira seu email!', + 'BLOCK_NAME.email.wrong-format': 'O email está errado!', + 'BLOCK_NAME.userName.required': 'Por favor insira nome de usuário!', + 'BLOCK_NAME.password.required': 'Por favor insira sua senha!', + 'BLOCK_NAME.password.twice': 'As senhas não estão iguais!', + 'BLOCK_NAME.strength.msg': + 'Por favor insira pelo menos 6 caracteres e não use senhas fáceis de adivinhar.', + 'BLOCK_NAME.strength.strong': 'Força: forte', + 'BLOCK_NAME.strength.medium': 'Força: média', + 'BLOCK_NAME.strength.short': 'Força: curta', + 'BLOCK_NAME.confirm-password.required': 'Por favor confirme sua senha!', + 'BLOCK_NAME.phone-number.required': 'Por favor insira seu telefone!', + 'BLOCK_NAME.phone-number.wrong-format': 'Formato de telefone errado!', + 'BLOCK_NAME.verification-code.required': 'Por favor insira seu código de verificação!', + + 'BLOCK_NAME.form.get-captcha': 'Get Captcha', + 'BLOCK_NAME.captcha.second': 'sec', + 'BLOCK_NAME.email.placeholder': 'Email', + 'BLOCK_NAME.password.placeholder': 'Senha', + 'BLOCK_NAME.confirm-password.placeholder': 'Confirme a senha', + 'BLOCK_NAME.phone-number.placeholder': 'Telefone', + 'BLOCK_NAME.verification-code.placeholder': 'Código de verificação', + 'BLOCK_NAME.form.optional': ' (optional) ', + 'BLOCK_NAME.form.submit': 'Submit', + 'BLOCK_NAME.form.save': 'Save', + 'BLOCK_NAME.title.label': 'Title', + 'BLOCK_NAME.title.placeholder': 'Give the target a name', + 'BLOCK_NAME.date.label': 'Start and end date', + 'BLOCK_NAME.placeholder.start': 'Start date', + 'BLOCK_NAME.placeholder.end': 'End date', + 'BLOCK_NAME.goal.label': 'Goal description', + 'BLOCK_NAME.goal.placeholder': 'Please enter your work goals', + 'BLOCK_NAME.standard.label': 'Metrics', + 'BLOCK_NAME.standard.placeholder': 'Please enter a metric', + 'BLOCK_NAME.client.label': 'Client', + 'BLOCK_NAME.label.tooltip': 'Target service object', + 'BLOCK_NAME.client.placeholder': + 'Please describe your customer service, internal customers directly @ Name / job number', + 'BLOCK_NAME.invites.label': 'Inviting critics', + 'BLOCK_NAME.invites.placeholder': 'Please direct @ Name / job number, you can invite up to 5 people', + 'BLOCK_NAME.weight.label': 'Weight', + 'BLOCK_NAME.weight.placeholder': 'Please enter weight', + 'BLOCK_NAME.public.label': 'Target disclosure', + 'BLOCK_NAME.label.help': 'Customers and invitees are shared by default', + 'BLOCK_NAME.radio.public': 'Public', + 'BLOCK_NAME.radio.partially-public': 'Partially public', + 'BLOCK_NAME.radio.private': 'Private', + 'BLOCK_NAME.publicUsers.placeholder': 'Open to', + 'BLOCK_NAME.option.A': 'Colleague A', + 'BLOCK_NAME.option.B': 'Colleague B', + 'BLOCK_NAME.option.C': 'Colleague C', +}; diff --git a/BasicForm/src/locales/zh-CN.js b/BasicForm/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..d9a4b1deb9b5d6f5aa748d6a7aa85ee087cbd416 --- /dev/null +++ b/BasicForm/src/locales/zh-CN.js @@ -0,0 +1,59 @@ +export default { + 'BLOCK_NAME.basic.title': '基础表单', + 'BLOCK_NAME.basic.description': + '表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。', + + 'BLOCK_NAME.email.required': '请输入邮箱地址!', + 'BLOCK_NAME.email.wrong-format': '邮箱地址格式错误!', + 'BLOCK_NAME.userName.required': '请输入用户名!', + 'BLOCK_NAME.password.required': '请输入密码!', + 'BLOCK_NAME.password.twice': '两次输入的密码不匹配!', + 'BLOCK_NAME.strength.msg': '请至少输入 6 个字符。请不要使用容易被猜到的密码。', + 'BLOCK_NAME.strength.strong': '强度:强', + 'BLOCK_NAME.strength.medium': '强度:中', + 'BLOCK_NAME.strength.short': '强度:太短', + 'BLOCK_NAME.confirm-password.required': '请确认密码!', + 'BLOCK_NAME.phone-number.required': '请输入手机号!', + 'BLOCK_NAME.phone-number.wrong-format': '手机号格式错误!', + 'BLOCK_NAME.verification-code.required': '请输入验证码!', + 'BLOCK_NAME.title.required': '请输入标题', + 'BLOCK_NAME.date.required': '请选择起止日期', + 'BLOCK_NAME.goal.required': '请输入目标描述', + 'BLOCK_NAME.standard.required': '请输入衡量标准', + + 'BLOCK_NAME.form.get-captcha': '获取验证码', + 'BLOCK_NAME.captcha.second': '秒', + 'BLOCK_NAME.form.optional': '(选填)', + 'BLOCK_NAME.form.submit': '提交', + 'BLOCK_NAME.form.save': '保存', + 'BLOCK_NAME.email.placeholder': '邮箱', + 'BLOCK_NAME.password.placeholder': '至少6位密码,区分大小写', + 'BLOCK_NAME.confirm-password.placeholder': '确认密码', + 'BLOCK_NAME.phone-number.placeholder': '手机号', + 'BLOCK_NAME.verification-code.placeholder': '验证码', + 'BLOCK_NAME.title.label': '标题', + 'BLOCK_NAME.title.placeholder': '给目标起个名字', + 'BLOCK_NAME.date.label': '起止日期', + 'BLOCK_NAME.placeholder.start': '开始日期', + 'BLOCK_NAME.placeholder.end': '结束日期', + 'BLOCK_NAME.goal.label': '目标描述', + 'BLOCK_NAME.goal.placeholder': '请输入你的阶段性工作目标', + 'BLOCK_NAME.standard.label': '衡量标准', + 'BLOCK_NAME.standard.placeholder': '请输入衡量标准', + 'BLOCK_NAME.client.label': '客户', + 'BLOCK_NAME.label.tooltip': '目标的服务对象', + 'BLOCK_NAME.client.placeholder': '请描述你服务的客户,内部客户直接 @姓名/工号', + 'BLOCK_NAME.invites.label': '邀评人', + 'BLOCK_NAME.invites.placeholder': '请直接 @姓名/工号,最多可邀请 5 人', + 'BLOCK_NAME.weight.label': '权重', + 'BLOCK_NAME.weight.placeholder': '请输入', + 'BLOCK_NAME.public.label': '目标公开', + 'BLOCK_NAME.label.help': '客户、邀评人默认被分享', + 'BLOCK_NAME.radio.public': '公开', + 'BLOCK_NAME.radio.partially-public': '部分公开', + 'BLOCK_NAME.radio.private': '不公开', + 'BLOCK_NAME.publicUsers.placeholder': '公开给', + 'BLOCK_NAME.option.A': '同事甲', + 'BLOCK_NAME.option.B': '同事乙', + 'BLOCK_NAME.option.C': '同事丙', +}; diff --git a/BasicForm/src/locales/zh-TW.js b/BasicForm/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..d42f8520ecb62730bdca8f6aa83ec32982c05932 --- /dev/null +++ b/BasicForm/src/locales/zh-TW.js @@ -0,0 +1,59 @@ +export default { + 'BLOCK_NAME.basic.title': '基礎表單', + 'BLOCK_NAME.basic.description': + '表單頁用於向用戶收集或驗證信息,基礎表單常見於數據項較少的表單場景。', + + 'BLOCK_NAME.email.required': '請輸入郵箱地址!', + 'BLOCK_NAME.email.wrong-format': '郵箱地址格式錯誤!', + 'BLOCK_NAME.userName.required': '請輸入賬戶!', + 'BLOCK_NAME.password.required': '請輸入密碼!', + 'BLOCK_NAME.password.twice': '兩次輸入的密碼不匹配!', + 'BLOCK_NAME.strength.msg': '請至少輸入 6 個字符。請不要使用容易被猜到的密碼。', + 'BLOCK_NAME.strength.strong': '強度:強', + 'BLOCK_NAME.strength.medium': '強度:中', + 'BLOCK_NAME.strength.short': '強度:太短', + 'BLOCK_NAME.confirm-password.required': '請確認密碼!', + 'BLOCK_NAME.phone-number.required': '請輸入手機號!', + 'BLOCK_NAME.phone-number.wrong-format': '手機號格式錯誤!', + 'BLOCK_NAME.verification-code.required': '請輸入驗證碼!', + 'BLOCK_NAME.title.required': '請輸入標題', + 'BLOCK_NAME.date.required': '請選擇起止日期', + 'BLOCK_NAME.goal.required': '請輸入目標描述', + 'BLOCK_NAME.standard.required': '請輸入衡量標淮', + + 'BLOCK_NAME.form.get-captcha': '獲取驗證碼', + 'BLOCK_NAME.captcha.second': '秒', + 'BLOCK_NAME.form.optional': '(選填)', + 'BLOCK_NAME.form.submit': '提交', + 'BLOCK_NAME.form.save': '保存', + 'BLOCK_NAME.email.placeholder': '郵箱', + 'BLOCK_NAME.password.placeholder': '至少6位密碼,區分大小寫', + 'BLOCK_NAME.confirm-password.placeholder': '確認密碼', + 'BLOCK_NAME.phone-number.placeholder': '手機號', + 'BLOCK_NAME.verification-code.placeholder': '驗證碼', + 'BLOCK_NAME.title.label': '標題', + 'BLOCK_NAME.title.placeholder': '給目標起個名字', + 'BLOCK_NAME.date.label': '起止日期', + 'BLOCK_NAME.placeholder.start': '開始日期', + 'BLOCK_NAME.placeholder.end': '結束日期', + 'BLOCK_NAME.goal.label': '目標描述', + 'BLOCK_NAME.goal.placeholder': '請輸入妳的階段性工作目標', + 'BLOCK_NAME.standard.label': '衡量標淮', + 'BLOCK_NAME.standard.placeholder': '請輸入衡量標淮', + 'BLOCK_NAME.client.label': '客戶', + 'BLOCK_NAME.label.tooltip': '目標的服務對象', + 'BLOCK_NAME.client.placeholder': '請描述妳服務的客戶,內部客戶直接 @姓名/工號', + 'BLOCK_NAME.invites.label': '邀評人', + 'BLOCK_NAME.invites.placeholder': '請直接 @姓名/工號,最多可邀請 5 人', + 'BLOCK_NAME.weight.label': '權重', + 'BLOCK_NAME.weight.placeholder': '請輸入', + 'BLOCK_NAME.public.label': '目標公開', + 'BLOCK_NAME.label.help': '客戶、邀評人默認被分享', + 'BLOCK_NAME.radio.public': '公開', + 'BLOCK_NAME.radio.partially-public': '部分公開', + 'BLOCK_NAME.radio.private': '不公開', + 'BLOCK_NAME.publicUsers.placeholder': '公開給', + 'BLOCK_NAME.option.A': '同事甲', + 'BLOCK_NAME.option.B': '同事乙', + 'BLOCK_NAME.option.C': '同事丙', +}; diff --git a/BasicForm/src/model.js b/BasicForm/src/model.js new file mode 100644 index 0000000000000000000000000000000000000000..010e5a590fc54347f3b49d74f7905b7680a82028 --- /dev/null +++ b/BasicForm/src/model.js @@ -0,0 +1,15 @@ +import { message } from 'antd'; +import { fakeSubmitForm } from './service'; + +export default { + namespace: 'BLOCK_NAME_CAMEL_CASE', + + state: {}, + + effects: { + *submitRegularForm({ payload }, { call }) { + yield call(fakeSubmitForm, payload); + message.success('提交成功'); + }, + }, +}; diff --git a/BasicForm/src/service.js b/BasicForm/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..77e522c8ca3527da73e4fc1e879705931c277028 --- /dev/null +++ b/BasicForm/src/service.js @@ -0,0 +1,8 @@ +import request from 'umi-request'; + +export async function fakeSubmitForm(params) { + return request('/api/BLOCK_NAME/forms', { + method: 'POST', + data: params, + }); +} diff --git a/BasicForm/src/style.less b/BasicForm/src/style.less new file mode 100644 index 0000000000000000000000000000000000000000..6b12d3c3eaf4ad2159d35b7a8550f20ac37d72e5 --- /dev/null +++ b/BasicForm/src/style.less @@ -0,0 +1,90 @@ +@import '~antd/lib/style/themes/default.less'; + +.card { + margin-bottom: 24px; +} + +.heading { + font-size: 14px; + line-height: 22px; + margin: 0 0 16px 0; +} + +.steps:global(.ant-steps) { + max-width: 750px; + margin: 16px auto; +} + +.errorIcon { + cursor: pointer; + color: @error-color; + margin-right: 24px; + i { + margin-right: 4px; + } +} + +.errorPopover { + :global { + .ant-popover-inner-content { + padding: 0; + max-height: 290px; + overflow: auto; + min-width: 256px; + } + } +} + +.errorListItem { + list-style: none; + border-bottom: 1px solid @border-color-split; + padding: 8px 16px; + cursor: pointer; + transition: all 0.3s; + &:hover { + background: @primary-1; + } + &:last-child { + border: 0; + } + .errorIcon { + color: @error-color; + float: left; + margin-top: 4px; + margin-right: 12px; + padding-bottom: 22px; + } + .errorField { + font-size: 12px; + color: @text-color-secondary; + margin-top: 2px; + } +} + +.editable { + td { + padding-top: 13px !important; + padding-bottom: 12.5px !important; + } +} + +// custom footer for fixed footer toolbar +.advancedForm + div { + padding-bottom: 64px; +} + +.advancedForm { + :global { + .ant-form .ant-row:last-child .ant-form-item { + margin-bottom: 24px; + } + .ant-table td { + transition: none !important; + } + } +} + +.optional { + color: @text-color-secondary; + font-style: normal; +} diff --git a/BasicList/.gitignore b/BasicList/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/BasicList/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/BasicList/.umirc.js b/BasicList/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/BasicList/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/BasicList/README.md b/BasicList/README.md new file mode 100644 index 0000000000000000000000000000000000000000..139bf7e734090544da333f2120c5decfe4c5f73c --- /dev/null +++ b/BasicList/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/basiclist + +BasicList + +## Usage + +```sh +umi block add ant-design-pro/basiclist +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/BasicList/package.json b/BasicList/package.json new file mode 100644 index 0000000000000000000000000000000000000000..ad52c543869302affd3827224af1e1c6aba1b0a1 --- /dev/null +++ b/BasicList/package.json @@ -0,0 +1,29 @@ +{ + "name": "@umi-block/basic-list", + "version": "0.0.1", + "description": "BasicList", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/basiclist" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "dva": "^2.4.0", + "hash.js": "^1.1.5", + "moment": "^2.22.2", + "react": "^16.6.3", + "react-dom": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/BasicList/snapshot.png b/BasicList/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..6071dd4d50c07c83beac62f4a1f8a92201dfb59f Binary files /dev/null and b/BasicList/snapshot.png differ diff --git a/BasicList/src/_mock.js b/BasicList/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..5c0578b52afee7e587cc3334c17e907d990c339f --- /dev/null +++ b/BasicList/src/_mock.js @@ -0,0 +1,144 @@ +const titles = [ + 'Alipay', + 'Angular', + 'Ant Design', + 'Ant Design Pro', + 'Bootstrap', + 'React', + 'Vue', + 'Webpack', +]; +const avatars = [ + 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png', // Alipay + 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png', // Angular + 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', // Ant Design + 'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', // Ant Design Pro + 'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png', // Bootstrap + 'https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png', // React + 'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png', // Vue + 'https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png', // Webpack +]; + +const covers = [ + 'https://gw.alipayobjects.com/zos/rmsportal/uMfMFlvUuceEyPpotzlq.png', + 'https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png', + 'https://gw.alipayobjects.com/zos/rmsportal/iXjVmWVHbCJAyqvDxdtx.png', + 'https://gw.alipayobjects.com/zos/rmsportal/gLaIAoVWTtLbBWZNYEMg.png', +]; +const desc = [ + '那是一种内在的东西, 他们到达不了,也无法触及的', + '希望是一个好东西,也许是最好的,好东西是不会消亡的', + '生命就像一盒巧克力,结果往往出人意料', + '城镇中有那么多的酒馆,她却偏偏走进了我的酒馆', + '那时候我只会想自己想要什么,从不想自己拥有什么', +]; + +const user = [ + '付小小', + '曲丽丽', + '林东东', + '周星星', + '吴加好', + '朱偏右', + '鱼酱', + '乐哥', + '谭小仪', + '仲尼', +]; + +function fakeList(count) { + const list = []; + for (let i = 0; i < count; i += 1) { + list.push({ + id: `fake-list-${i}`, + owner: user[i % 10], + title: titles[i % 8], + avatar: avatars[i % 8], + cover: parseInt(i / 4, 10) % 2 === 0 ? covers[i % 4] : covers[3 - (i % 4)], + status: ['active', 'exception', 'normal'][i % 3], + percent: Math.ceil(Math.random() * 50) + 50, + logo: avatars[i % 8], + href: 'https://ant.design', + updatedAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i), + createdAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i), + subDescription: desc[i % 5], + description: + '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。', + activeUser: Math.ceil(Math.random() * 100000) + 100000, + newUser: Math.ceil(Math.random() * 1000) + 1000, + star: Math.ceil(Math.random() * 100) + 100, + like: Math.ceil(Math.random() * 100) + 100, + message: Math.ceil(Math.random() * 10) + 10, + content: + '段落示意:蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。', + members: [ + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png', + name: '曲丽丽', + id: 'member1', + }, + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png', + name: '王昭君', + id: 'member2', + }, + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png', + name: '董娜娜', + id: 'member3', + }, + ], + }); + } + + return list; +} + +let sourceData; + +function getFakeList(req, res) { + const params = req.query; + + const count = params.count * 1 || 20; + + const result = fakeList(count); + sourceData = result; + return res.json(result); +} + +function postFakeList(req, res) { + const { /* url = '', */ body } = req; + // const params = getUrlParams(url); + const { method, id } = body; + // const count = (params.count * 1) || 20; + let result = sourceData; + + switch (method) { + case 'delete': + result = result.filter(item => item.id !== id); + break; + case 'update': + result.forEach((item, i) => { + if (item.id === id) { + result[i] = Object.assign(item, body); + } + }); + break; + case 'post': + result.unshift({ + body, + id: `fake-list-${result.length}`, + createdAt: new Date().getTime(), + }); + break; + default: + break; + } + + return res.json(result); +} + +export default { + 'GET /api/BLOCK_NAME/fake_list': getFakeList, + 'POST /api/BLOCK_NAME/fake_list': postFakeList, +}; diff --git a/src/pages/List/BasicList.js b/BasicList/src/index.js similarity index 93% rename from src/pages/List/BasicList.js rename to BasicList/src/index.js index b52a29999b999571e70e19c01c60699395d97acd..d75d6e4d27e02e722eca53815772f6708a5bc2ed 100644 --- a/src/pages/List/BasicList.js +++ b/BasicList/src/index.js @@ -1,4 +1,5 @@ import React, { PureComponent } from 'react'; +import { FormattedMessage } from 'umi/locale'; import { findDOMNode } from 'react-dom'; import moment from 'moment'; import { connect } from 'dva'; @@ -21,10 +22,9 @@ import { Select, } from 'antd'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; -import Result from '@/components/Result'; +import { Result } from 'ant-design-pro'; -import styles from './BasicList.less'; +import styles from './style.less'; const FormItem = Form.Item; const RadioButton = Radio.Button; @@ -32,12 +32,12 @@ const RadioGroup = Radio.Group; const SelectOption = Select.Option; const { Search, TextArea } = Input; -@connect(({ list, loading }) => ({ - list, - loading: loading.models.list, +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ + BLOCK_NAME_CAMEL_CASE, + loading: loading.models.BLOCK_NAME_CAMEL_CASE, })) @Form.create() -class BasicList extends PureComponent { +class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { state = { visible: false, done: false }; formLayout = { @@ -48,7 +48,7 @@ class BasicList extends PureComponent { componentDidMount() { const { dispatch } = this.props; dispatch({ - type: 'list/fetch', + type: 'BLOCK_NAME_CAMEL_CASE/fetch', payload: { count: 5, }, @@ -97,7 +97,7 @@ class BasicList extends PureComponent { done: true, }); dispatch({ - type: 'list/submit', + type: 'BLOCK_NAME_CAMEL_CASE/submit', payload: { id, ...fieldsValue }, }); }); @@ -106,14 +106,14 @@ class BasicList extends PureComponent { deleteItem = id => { const { dispatch } = this.props; dispatch({ - type: 'list/submit', + type: 'BLOCK_NAME_CAMEL_CASE/submit', payload: { id }, }); }; render() { const { - list: { list }, + BLOCK_NAME_CAMEL_CASE: { list }, loading, } = this.props; const { @@ -253,7 +253,7 @@ class BasicList extends PureComponent { ); }; return ( - + @@ -272,7 +272,7 @@ class BasicList extends PureComponent { } style={{ marginTop: 24 }} bodyStyle={{ padding: '0 32px 40px 32px' }} extra={extraContent} @@ -332,9 +332,9 @@ class BasicList extends PureComponent { > {getModalContent()} - + ); } } -export default BasicList; +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/BasicList/src/locales/en-US.js b/BasicList/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..6c4e442b69b2ab1156eb8af72c1130353ad61065 --- /dev/null +++ b/BasicList/src/locales/en-US.js @@ -0,0 +1,3 @@ +export default { + 'BLOCK_NAME.list.basiclist': 'Basic List', +}; diff --git a/BasicList/src/locales/pt-BR.js b/BasicList/src/locales/pt-BR.js new file mode 100644 index 0000000000000000000000000000000000000000..e116dffe0d164cd345a4c10a3b9009314b0fccad --- /dev/null +++ b/BasicList/src/locales/pt-BR.js @@ -0,0 +1,3 @@ +export default { + 'BLOCK_NAME.list.basiclist': 'Lista Básica', +}; diff --git a/BasicList/src/locales/zh-CN.js b/BasicList/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..738a82a3ef209c3914c11f1fb444f9a6836ef609 --- /dev/null +++ b/BasicList/src/locales/zh-CN.js @@ -0,0 +1,3 @@ +export default { + 'BLOCK_NAME.list.basiclist': '标准列表', +}; diff --git a/BasicList/src/locales/zh-TW.js b/BasicList/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..96ad59be2ed315cac90f37be41120f41f721e200 --- /dev/null +++ b/BasicList/src/locales/zh-TW.js @@ -0,0 +1,3 @@ +export default { + 'BLOCK_NAME.list.basiclist': '標淮列表', +}; diff --git a/src/models/list.js b/BasicList/src/model.js similarity index 95% rename from src/models/list.js rename to BasicList/src/model.js index 4758edaaa0a1611beb9ab8adf225202445f41468..8a5d37f23dcb876dbefa0a1eafb46591f6fdeb0a 100644 --- a/src/models/list.js +++ b/BasicList/src/model.js @@ -1,7 +1,7 @@ -import { queryFakeList, removeFakeList, addFakeList, updateFakeList } from '@/services/api'; +import { queryFakeList, removeFakeList, addFakeList, updateFakeList } from './service'; export default { - namespace: 'list', + namespace: 'BLOCK_NAME_CAMEL_CASE', state: { list: [], diff --git a/BasicList/src/service.js b/BasicList/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..1f7cfc8aad178c98d0e24c3d777064ab7092bcf3 --- /dev/null +++ b/BasicList/src/service.js @@ -0,0 +1,49 @@ +import request from 'umi-request'; + +export async function queryFakeList(params) { + return request('/api/BLOCK_NAME/fake_list', { + params, + }); +} + +export async function removeFakeList(params) { + const { count = 5, ...restParams } = params; + return request('/api/BLOCK_NAME/fake_list', { + method: 'POST', + params: { + count, + }, + data: { + ...restParams, + method: 'delete', + }, + }); +} + +export async function addFakeList(params) { + const { count = 5, ...restParams } = params; + return request('/api/BLOCK_NAME/fake_list', { + method: 'POST', + params: { + count, + }, + data: { + ...restParams, + method: 'post', + }, + }); +} + +export async function updateFakeList(params) { + const { count = 5, ...restParams } = params; + return request('/api/BLOCK_NAME/fake_list', { + method: 'POST', + params: { + count, + }, + data: { + ...restParams, + method: 'update', + }, + }); +} diff --git a/src/pages/List/BasicList.less b/BasicList/src/style.less similarity index 99% rename from src/pages/List/BasicList.less rename to BasicList/src/style.less index f086c501c887f985093d0e6cf0b99643a0ed44dc..6d291abea0d128b88d4c5938d763b52c8448397d 100644 --- a/src/pages/List/BasicList.less +++ b/BasicList/src/style.less @@ -1,5 +1,5 @@ @import '~antd/lib/style/themes/default.less'; -@import '~@/utils/utils.less'; +@import './utils/utils.less'; .standardList { :global { diff --git a/BasicList/src/utils/utils.less b/BasicList/src/utils/utils.less new file mode 100644 index 0000000000000000000000000000000000000000..725792252787f49efba4f4e887301195a9818f3f --- /dev/null +++ b/BasicList/src/utils/utils.less @@ -0,0 +1,50 @@ +.textOverflow() { + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + white-space: nowrap; +} + +.textOverflowMulti(@line: 3, @bg: #fff) { + overflow: hidden; + position: relative; + line-height: 1.5em; + max-height: @line * 1.5em; + text-align: justify; + margin-right: -1em; + padding-right: 1em; + &:before { + background: @bg; + content: '...'; + padding: 0 1px; + position: absolute; + right: 14px; + bottom: 0; + } + &:after { + background: white; + content: ''; + margin-top: 0.2em; + position: absolute; + right: 14px; + width: 1em; + height: 1em; + } +} + +// mixins for clearfix +// ------------------------ +.clearfix() { + zoom: 1; + &:before, + &:after { + content: ' '; + display: table; + } + &:after { + clear: both; + visibility: hidden; + font-size: 0; + height: 0; + } +} diff --git a/BasicProfile/.gitignore b/BasicProfile/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/BasicProfile/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/BasicProfile/.umirc.js b/BasicProfile/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/BasicProfile/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/BasicProfile/README.md b/BasicProfile/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ae47819548f0ab875fd85904bc2c655b66aead45 --- /dev/null +++ b/BasicProfile/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/basicprofile + +BasicProfile + +## Usage + +```sh +umi block add ant-design-pro/basicprofile +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/BasicProfile/package.json b/BasicProfile/package.json new file mode 100644 index 0000000000000000000000000000000000000000..36c6d2201de8ec6fc63f558420537fbd1d84bb40 --- /dev/null +++ b/BasicProfile/package.json @@ -0,0 +1,26 @@ +{ + "name": "@umi-block/basic-profile", + "version": "0.0.1", + "description": "BasicProfile", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/basicprofile" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "dva": "^2.4.0", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/BasicProfile/snapshot.png b/BasicProfile/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..b0ea79484ccfe531f6a9c866390cd7d3409576f5 Binary files /dev/null and b/BasicProfile/snapshot.png differ diff --git a/mock/profile.js b/BasicProfile/src/_mock.js similarity index 51% rename from mock/profile.js rename to BasicProfile/src/_mock.js index 03aecc56c01c33f8bd76a7131831e5754b4905b3..8fe12b97508cd5acc280208788753337880c6ada 100644 --- a/mock/profile.js +++ b/BasicProfile/src/_mock.js @@ -76,83 +76,11 @@ const basicProgress = [ }, ]; -const advancedOperation1 = [ - { - key: 'op1', - type: '订购关系生效', - name: '曲丽丽', - status: 'agree', - updatedAt: '2017-10-03 19:23:12', - memo: '-', - }, - { - key: 'op2', - type: '财务复审', - name: '付小小', - status: 'reject', - updatedAt: '2017-10-03 19:23:12', - memo: '不通过原因', - }, - { - key: 'op3', - type: '部门初审', - name: '周毛毛', - status: 'agree', - updatedAt: '2017-10-03 19:23:12', - memo: '-', - }, - { - key: 'op4', - type: '提交订单', - name: '林东东', - status: 'agree', - updatedAt: '2017-10-03 19:23:12', - memo: '很棒', - }, - { - key: 'op5', - type: '创建订单', - name: '汗牙牙', - status: 'agree', - updatedAt: '2017-10-03 19:23:12', - memo: '-', - }, -]; - -const advancedOperation2 = [ - { - key: 'op1', - type: '订购关系生效', - name: '曲丽丽', - status: 'agree', - updatedAt: '2017-10-03 19:23:12', - memo: '-', - }, -]; - -const advancedOperation3 = [ - { - key: 'op1', - type: '创建订单', - name: '汗牙牙', - status: 'agree', - updatedAt: '2017-10-03 19:23:12', - memo: '-', - }, -]; - const getProfileBasicData = { basicGoods, basicProgress, }; -const getProfileAdvancedData = { - advancedOperation1, - advancedOperation2, - advancedOperation3, -}; - export default { - 'GET /api/profile/advanced': getProfileAdvancedData, - 'GET /api/profile/basic': getProfileBasicData, + 'GET /api/BLOCK_NAME/basic': getProfileBasicData, }; diff --git a/BasicProfile/src/components/PageHeaderWrapper/index.js b/BasicProfile/src/components/PageHeaderWrapper/index.js new file mode 100644 index 0000000000000000000000000000000000000000..165ae2524640af9bfb6a72e918852e8e60480fc7 --- /dev/null +++ b/BasicProfile/src/components/PageHeaderWrapper/index.js @@ -0,0 +1,26 @@ +import React from 'react'; +import { FormattedMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { PageHeader } from 'ant-design-pro'; +import styles from './index.less'; + +const PageHeaderWrapper = ({ children, contentWidth, wrapperClassName, top, ...restProps }) => ( + + } + key="pageheader" + {...restProps} + linkElement={Link} + itemRender={item => { + if (item.locale) { + return ; + } + return item.title; + }} + /> + {children ? {children} : null} + +); + +export default PageHeaderWrapper; diff --git a/BasicProfile/src/components/PageHeaderWrapper/index.less b/BasicProfile/src/components/PageHeaderWrapper/index.less new file mode 100644 index 0000000000000000000000000000000000000000..39a449657a98b039c29e6654fd117267cbb5283a --- /dev/null +++ b/BasicProfile/src/components/PageHeaderWrapper/index.less @@ -0,0 +1,11 @@ +@import '~antd/lib/style/themes/default.less'; + +.content { + margin: 24px 24px 0; +} + +@media screen and (max-width: @screen-sm) { + .content { + margin: 24px 0 0; + } +} diff --git a/src/pages/Profile/BasicProfile.js b/BasicProfile/src/index.js similarity index 89% rename from src/pages/Profile/BasicProfile.js rename to BasicProfile/src/index.js index bd0b7c99fa54d7dff75efe62f87a06b9c440d626..864d3199ac2f6e9fffa77b55a1044f1af41197e3 100644 --- a/src/pages/Profile/BasicProfile.js +++ b/BasicProfile/src/index.js @@ -1,9 +1,9 @@ import React, { Component } from 'react'; import { connect } from 'dva'; import { Card, Badge, Table, Divider } from 'antd'; -import DescriptionList from '@/components/DescriptionList'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; -import styles from './BasicProfile.less'; +import { DescriptionList } from 'ant-design-pro'; +import PageHeaderWrapper from './components/PageHeaderWrapper'; +import styles from './style.less'; const { Description } = DescriptionList; @@ -41,21 +41,21 @@ const progressColumns = [ }, ]; -@connect(({ profile, loading }) => ({ - profile, - loading: loading.effects['profile/fetchBasic'], +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ + BLOCK_NAME_CAMEL_CASE, + loading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchBasic'], })) -class BasicProfile extends Component { +class PAGE_NAME_UPPER_CAMEL_CASE extends Component { componentDidMount() { const { dispatch } = this.props; dispatch({ - type: 'profile/fetchBasic', + type: 'BLOCK_NAME_CAMEL_CASE/fetchBasic', }); } render() { - const { profile, loading } = this.props; - const { basicGoods, basicProgress } = profile; + const { BLOCK_NAME_CAMEL_CASE, loading } = this.props; + const { basicGoods, basicProgress } = BLOCK_NAME_CAMEL_CASE; let goodsData = []; if (basicGoods.length) { let num = 0; @@ -182,4 +182,4 @@ class BasicProfile extends Component { } } -export default BasicProfile; +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/BasicProfile/src/model.js b/BasicProfile/src/model.js new file mode 100644 index 0000000000000000000000000000000000000000..904733cc1e76551c01f1a05e0523bfeeb3930ce2 --- /dev/null +++ b/BasicProfile/src/model.js @@ -0,0 +1,28 @@ +import { queryBasicProfile } from './service'; + +export default { + namespace: 'BLOCK_NAME_CAMEL_CASE', + + state: { + basicGoods: [], + }, + + effects: { + *fetchBasic(_, { call, put }) { + const response = yield call(queryBasicProfile); + yield put({ + type: 'show', + payload: response, + }); + }, + }, + + reducers: { + show(state, { payload }) { + return { + ...state, + ...payload, + }; + }, + }, +}; diff --git a/BasicProfile/src/service.js b/BasicProfile/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..26683af4e434fcff72514b1f4b64a36b3b65ba43 --- /dev/null +++ b/BasicProfile/src/service.js @@ -0,0 +1,5 @@ +import request from 'umi-request'; + +export async function queryBasicProfile() { + return request('/api/BLOCK_NAME/basic'); +} diff --git a/src/pages/Profile/BasicProfile.less b/BasicProfile/src/style.less similarity index 100% rename from src/pages/Profile/BasicProfile.less rename to BasicProfile/src/style.less diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 9e41f2e9f60185335b67843d8d9b57466b9c3ee8..0000000000000000000000000000000000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,46 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at afc163@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/CardList/.gitignore b/CardList/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/CardList/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/CardList/.umirc.js b/CardList/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/CardList/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/CardList/README.md b/CardList/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ceeb235fa6003deba1610ddf1efd20457131c09f --- /dev/null +++ b/CardList/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/cardlist + +CardList + +## Usage + +```sh +umi block add ant-design-pro/cardlist +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/CardList/package.json b/CardList/package.json new file mode 100644 index 0000000000000000000000000000000000000000..c3b42f501d56ead598331bf8659f8e9f5e304acd --- /dev/null +++ b/CardList/package.json @@ -0,0 +1,26 @@ +{ + "name": "@umi-block/card-list", + "version": "0.0.1", + "description": "CardList", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/cardlist" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "dva": "^2.4.0", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/CardList/snapshot.png b/CardList/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..6071dd4d50c07c83beac62f4a1f8a92201dfb59f Binary files /dev/null and b/CardList/snapshot.png differ diff --git a/CardList/src/_mock.js b/CardList/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..c6903658fb8dfc249d8bb6f1abf8ad7a371ab41f --- /dev/null +++ b/CardList/src/_mock.js @@ -0,0 +1,107 @@ +const titles = [ + 'Alipay', + 'Angular', + 'Ant Design', + 'Ant Design Pro', + 'Bootstrap', + 'React', + 'Vue', + 'Webpack', +]; +const avatars = [ + 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png', // Alipay + 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png', // Angular + 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', // Ant Design + 'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', // Ant Design Pro + 'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png', // Bootstrap + 'https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png', // React + 'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png', // Vue + 'https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png', // Webpack +]; + +const covers = [ + 'https://gw.alipayobjects.com/zos/rmsportal/uMfMFlvUuceEyPpotzlq.png', + 'https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png', + 'https://gw.alipayobjects.com/zos/rmsportal/iXjVmWVHbCJAyqvDxdtx.png', + 'https://gw.alipayobjects.com/zos/rmsportal/gLaIAoVWTtLbBWZNYEMg.png', +]; +const desc = [ + '那是一种内在的东西, 他们到达不了,也无法触及的', + '希望是一个好东西,也许是最好的,好东西是不会消亡的', + '生命就像一盒巧克力,结果往往出人意料', + '城镇中有那么多的酒馆,她却偏偏走进了我的酒馆', + '那时候我只会想自己想要什么,从不想自己拥有什么', +]; +const user = [ + '付小小', + '曲丽丽', + '林东东', + '周星星', + '吴加好', + '朱偏右', + '鱼酱', + '乐哥', + '谭小仪', + '仲尼', +]; + +function fakeList(count) { + const list = []; + for (let i = 0; i < count; i += 1) { + list.push({ + id: `fake-list-${i}`, + owner: user[i % 10], + title: titles[i % 8], + avatar: avatars[i % 8], + cover: parseInt(i / 4, 10) % 2 === 0 ? covers[i % 4] : covers[3 - (i % 4)], + status: ['active', 'exception', 'normal'][i % 3], + percent: Math.ceil(Math.random() * 50) + 50, + logo: avatars[i % 8], + href: 'https://ant.design', + updatedAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i), + createdAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i), + subDescription: desc[i % 5], + description: + '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。', + activeUser: Math.ceil(Math.random() * 100000) + 100000, + newUser: Math.ceil(Math.random() * 1000) + 1000, + star: Math.ceil(Math.random() * 100) + 100, + like: Math.ceil(Math.random() * 100) + 100, + message: Math.ceil(Math.random() * 10) + 10, + content: + '段落示意:蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。', + members: [ + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png', + name: '曲丽丽', + id: 'member1', + }, + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png', + name: '王昭君', + id: 'member2', + }, + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png', + name: '董娜娜', + id: 'member3', + }, + ], + }); + } + + return list; +} + +function getFakeList(req, res) { + const params = req.query; + + const count = params.count * 1 || 20; + + const result = fakeList(count); + return res.json(result); +} + +export default { + 'GET /api/BLOCK_NAME/fake_list': getFakeList, +}; diff --git a/CardList/src/components/PageHeaderWrapper/index.js b/CardList/src/components/PageHeaderWrapper/index.js new file mode 100644 index 0000000000000000000000000000000000000000..c11873f2c8c24d44391261910d5adb52ab916d1a --- /dev/null +++ b/CardList/src/components/PageHeaderWrapper/index.js @@ -0,0 +1,25 @@ +import React from 'react'; +import { FormattedMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { PageHeader } from 'ant-design-pro'; +import styles from './index.less'; + +const PageHeaderWrapper = ({ children, wrapperClassName, ...restProps }) => ( + + } + key="pageheader" + {...restProps} + linkElement={Link} + itemRender={item => { + if (item.locale) { + return ; + } + return item.title; + }} + /> + {children ? {children} : null} + +); + +export default PageHeaderWrapper; diff --git a/CardList/src/components/PageHeaderWrapper/index.less b/CardList/src/components/PageHeaderWrapper/index.less new file mode 100644 index 0000000000000000000000000000000000000000..39a449657a98b039c29e6654fd117267cbb5283a --- /dev/null +++ b/CardList/src/components/PageHeaderWrapper/index.less @@ -0,0 +1,11 @@ +@import '~antd/lib/style/themes/default.less'; + +.content { + margin: 24px 24px 0; +} + +@media screen and (max-width: @screen-sm) { + .content { + margin: 24px 0 0; + } +} diff --git a/src/pages/List/CardList.js b/CardList/src/index.js similarity index 87% rename from src/pages/List/CardList.js rename to CardList/src/index.js index 03f799a14feb9d70ec47a9ad7fcaf739123d2ae4..0904e5125d124bf5c86a1b55f8ca981d28c6e1bc 100644 --- a/src/pages/List/CardList.js +++ b/CardList/src/index.js @@ -2,20 +2,20 @@ import React, { PureComponent } from 'react'; import { connect } from 'dva'; import { Card, Button, Icon, List } from 'antd'; -import Ellipsis from '@/components/Ellipsis'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; +import { Ellipsis } from 'ant-design-pro'; +import PageHeaderWrapper from './components/PageHeaderWrapper'; -import styles from './CardList.less'; +import styles from './style.less'; -@connect(({ list, loading }) => ({ - list, +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ + BLOCK_NAME_CAMEL_CASE, loading: loading.models.list, })) -class CardList extends PureComponent { +class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { componentDidMount() { const { dispatch } = this.props; dispatch({ - type: 'list/fetch', + type: 'BLOCK_NAME_CAMEL_CASE/fetch', payload: { count: 8, }, @@ -24,7 +24,7 @@ class CardList extends PureComponent { render() { const { - list: { list }, + BLOCK_NAME_CAMEL_CASE: { list }, loading, } = this.props; @@ -98,4 +98,4 @@ class CardList extends PureComponent { } } -export default CardList; +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/src/pages/Dashboard/models/activities.js b/CardList/src/model.js similarity index 52% rename from src/pages/Dashboard/models/activities.js rename to CardList/src/model.js index 4e0a11e277f8b6e881da6eba44f884a04ce60aa9..ead65a8df48a91a8b103af60429206eb865c7230 100644 --- a/src/pages/Dashboard/models/activities.js +++ b/CardList/src/model.js @@ -1,24 +1,24 @@ -import { queryActivities } from '@/services/api'; +import { queryFakeList } from './service'; export default { - namespace: 'activities', + namespace: 'BLOCK_NAME_CAMEL_CASE', state: { list: [], }, effects: { - *fetchList(_, { call, put }) { - const response = yield call(queryActivities); + *fetch({ payload }, { call, put }) { + const response = yield call(queryFakeList, payload); yield put({ - type: 'saveList', + type: 'queryList', payload: Array.isArray(response) ? response : [], }); }, }, reducers: { - saveList(state, action) { + queryList(state, action) { return { ...state, list: action.payload, diff --git a/CardList/src/service.js b/CardList/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..f6d5bc70b96dc475843315338bd05e84667a7398 --- /dev/null +++ b/CardList/src/service.js @@ -0,0 +1,7 @@ +import request from 'umi-request'; + +export async function queryFakeList(params) { + return request(`/api/BLOCK_NAME/fake_list`, { + params, + }); +} diff --git a/src/pages/List/CardList.less b/CardList/src/style.less similarity index 98% rename from src/pages/List/CardList.less rename to CardList/src/style.less index 3d6feacc2635872b8c6006c529524cb107a5c584..0094c229553b9bebd75915ccacf903d128c5f3ad 100644 --- a/src/pages/List/CardList.less +++ b/CardList/src/style.less @@ -1,5 +1,5 @@ @import '~antd/lib/style/themes/default.less'; -@import '~@/utils/utils.less'; +@import './utils/utils.less'; .cardList { margin-bottom: -24px; diff --git a/CardList/src/utils/utils.less b/CardList/src/utils/utils.less new file mode 100644 index 0000000000000000000000000000000000000000..725792252787f49efba4f4e887301195a9818f3f --- /dev/null +++ b/CardList/src/utils/utils.less @@ -0,0 +1,50 @@ +.textOverflow() { + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + white-space: nowrap; +} + +.textOverflowMulti(@line: 3, @bg: #fff) { + overflow: hidden; + position: relative; + line-height: 1.5em; + max-height: @line * 1.5em; + text-align: justify; + margin-right: -1em; + padding-right: 1em; + &:before { + background: @bg; + content: '...'; + padding: 0 1px; + position: absolute; + right: 14px; + bottom: 0; + } + &:after { + background: white; + content: ''; + margin-top: 0.2em; + position: absolute; + right: 14px; + width: 1em; + height: 1em; + } +} + +// mixins for clearfix +// ------------------------ +.clearfix() { + zoom: 1; + &:before, + &:after { + content: ' '; + display: table; + } + &:after { + clear: both; + visibility: hidden; + font-size: 0; + height: 0; + } +} diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 7cbc5c31cd95e3cad949c50aa02103e126ae0c83..0000000000000000000000000000000000000000 --- a/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM circleci/node:latest-browsers - -WORKDIR /usr/src/app/ -USER root -COPY package.json ./ -RUN yarn - -COPY ./ ./ - -RUN npm run test:all - -CMD ["npm", "run", "build"] diff --git a/Dockerfile.dev b/Dockerfile.dev deleted file mode 100644 index f5a50e58a0cde0d980516f3fba9cccde02afcf9a..0000000000000000000000000000000000000000 --- a/Dockerfile.dev +++ /dev/null @@ -1,11 +0,0 @@ -FROM node:latest - -WORKDIR /usr/src/app/ - -COPY package.json ./ -RUN npm install --silent --no-cache - -COPY ./ ./ - - -CMD ["npm", "run", "start"] diff --git a/Dockerfile.hub b/Dockerfile.hub deleted file mode 100644 index 2e9c1ec9133f1762656e6bdc2672a1802bd24186..0000000000000000000000000000000000000000 --- a/Dockerfile.hub +++ /dev/null @@ -1,11 +0,0 @@ -FROM nginx - -WORKDIR /usr/src/app/ - -COPY ./docker/nginx.conf /etc/nginx/conf.d/default.conf - -COPY ./dist /usr/share/nginx/html/ - -EXPOSE 80 - -CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/Exception403/.gitignore b/Exception403/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/Exception403/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/Exception403/.umirc.js b/Exception403/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..e6e79ab6a2b871d1781de8ecf9843c00849ae065 --- /dev/null +++ b/Exception403/.umirc.js @@ -0,0 +1,10 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { layout: 'ant-design-pro', }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/Exception403/README.md b/Exception403/README.md new file mode 100644 index 0000000000000000000000000000000000000000..fce3028b929b18c8b3f55046b73e92b2a1679f50 --- /dev/null +++ b/Exception403/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/exception403 + +Exception403 + +## Usage + +```sh +umi block add ant-design-pro/exception403 +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/Exception403/package.json b/Exception403/package.json new file mode 100644 index 0000000000000000000000000000000000000000..21ead27ca8db51828d1786863d3a76ce28c75662 --- /dev/null +++ b/Exception403/package.json @@ -0,0 +1,25 @@ +{ + "name": "@umi-block/exception-403", + "version": "0.0.1", + "description": "Exception403", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/exception403" + }, + "dependencies": { + "react": "^16.6.3", + "ant-design-pro": "^2.1.1", + "dva": "^2.4.0", + "umi-request": "^1.0.0-beta.1" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/Exception403/snapshot.png b/Exception403/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..ed39c63ae9244c698024159a5a6fcfc1e47cbf78 Binary files /dev/null and b/Exception403/snapshot.png differ diff --git a/Exception403/src/index.js b/Exception403/src/index.js new file mode 100644 index 0000000000000000000000000000000000000000..f375a1006aa9d8fd71637b6be8e98101ab134357 --- /dev/null +++ b/Exception403/src/index.js @@ -0,0 +1,15 @@ +import React from 'react'; +import { formatMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { Exception } from 'ant-design-pro'; + +const PAGE_NAME_UPPER_CAMEL_CASE = () => ( + +); + +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/Exception403/src/locales/en-US.js b/Exception403/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..dedc47a09ef5e507afc8899e755b98c726804722 --- /dev/null +++ b/Exception403/src/locales/en-US.js @@ -0,0 +1,4 @@ +export default { + 'BLOCK_NAME.exception.back': 'Back to home', + 'BLOCK_NAME.description.403': "Sorry, you don't have access to this page", +}; diff --git a/Exception403/src/locales/pt-BR.js b/Exception403/src/locales/pt-BR.js new file mode 100644 index 0000000000000000000000000000000000000000..6302cb22181aa18781b784ec408c2184fa931c35 --- /dev/null +++ b/Exception403/src/locales/pt-BR.js @@ -0,0 +1,4 @@ +export default { + 'BLOCK_NAME.exception.back': 'Voltar para Início', + 'BLOCK_NAME.description.403': 'Desculpe, você não tem acesso a esta página', +}; diff --git a/Exception403/src/locales/zh-CN.js b/Exception403/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..e83c24c060a1d676b8024a10c4d84d421ebea769 --- /dev/null +++ b/Exception403/src/locales/zh-CN.js @@ -0,0 +1,4 @@ +export default { + 'BLOCK_NAME.exception.back': '返回首页', + 'BLOCK_NAME.description.403': '抱歉,你无权访问该页面', +}; diff --git a/Exception403/src/locales/zh-TW.js b/Exception403/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..a1c8274ab39552cedc043e5a7288a97d3cb18206 --- /dev/null +++ b/Exception403/src/locales/zh-TW.js @@ -0,0 +1,4 @@ +export default { + 'BLOCK_NAME.exception.back': '返回首頁', + 'BLOCK_NAME.description.403': '抱歉,妳無權訪問該頁面', +}; diff --git a/Exception404/.gitignore b/Exception404/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/Exception404/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/Exception404/.umirc.js b/Exception404/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..218e63be0626108feb8df1944a56ac016d287b25 --- /dev/null +++ b/Exception404/.umirc.js @@ -0,0 +1,10 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', {layout: 'ant-design-pro',}], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/Exception404/README.md b/Exception404/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ccbcdb8c8b154d232a523f1ee16768fe5d05797f --- /dev/null +++ b/Exception404/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/exception404 + +Exception404 + +## Usage + +```sh +umi block add ant-design-pro/exception404 +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/Exception404/package.json b/Exception404/package.json new file mode 100644 index 0000000000000000000000000000000000000000..02721d046ce0f95230e249047f2e33d8b63f1584 --- /dev/null +++ b/Exception404/package.json @@ -0,0 +1,25 @@ +{ + "name": "@umi-block/exception-404", + "version": "0.0.1", + "description": "Exception404", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/exception404" + }, + "dependencies": { + "react": "^16.6.3", + "ant-design-pro": "^2.1.1", + "dva": "^2.4.0", + "umi-request": "^1.0.0-beta.1" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/Exception404/snapshot.png b/Exception404/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..7f034dd25a90456aded36186cb009c1abc018231 Binary files /dev/null and b/Exception404/snapshot.png differ diff --git a/Exception404/src/index.js b/Exception404/src/index.js new file mode 100644 index 0000000000000000000000000000000000000000..d5b93d4367454c6428b4a444d7a672372857f381 --- /dev/null +++ b/Exception404/src/index.js @@ -0,0 +1,15 @@ +import React from 'react'; +import { formatMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { Exception } from 'ant-design-pro'; + +const PAGE_NAME_UPPER_CAMEL_CASE = () => ( + +); + +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/Exception404/src/locales/en-US.js b/Exception404/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..a8c3dfce27a9239394203af2a71fa4bffa58dc89 --- /dev/null +++ b/Exception404/src/locales/en-US.js @@ -0,0 +1,4 @@ +export default { + 'BLOCK_NAME.exception.back': 'Back to home', + 'BLOCK_NAME.description.404': 'Sorry, the page you visited does not exist', +}; diff --git a/Exception404/src/locales/pt-BR.js b/Exception404/src/locales/pt-BR.js new file mode 100644 index 0000000000000000000000000000000000000000..d7502abe20f18feeff5089052ac6d4b501f17e5b --- /dev/null +++ b/Exception404/src/locales/pt-BR.js @@ -0,0 +1,4 @@ +export default { + 'BLOCK_NAME.exception.back': 'Voltar para Início', + 'BLOCK_NAME.description.404': 'Desculpe, a página que você visitou não existe', +}; diff --git a/Exception404/src/locales/zh-CN.js b/Exception404/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..43ced44165e77b0ed7c799d9071d272ab8c7cc3c --- /dev/null +++ b/Exception404/src/locales/zh-CN.js @@ -0,0 +1,4 @@ +export default { + 'BLOCK_NAME.exception.back': '返回首页', + 'BLOCK_NAME.description.404': '抱歉,你访问的页面不存在', +}; diff --git a/Exception404/src/locales/zh-TW.js b/Exception404/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..2448bb66af7f64340f8c883bda68a3e75665f7bd --- /dev/null +++ b/Exception404/src/locales/zh-TW.js @@ -0,0 +1,4 @@ +export default { + 'BLOCK_NAME.exception.back': '返回首頁', + 'BLOCK_NAME.description.404': '抱歉,妳訪問的頁面不存在', +}; diff --git a/Exception500/.gitignore b/Exception500/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/Exception500/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/Exception500/.umirc.js b/Exception500/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..218e63be0626108feb8df1944a56ac016d287b25 --- /dev/null +++ b/Exception500/.umirc.js @@ -0,0 +1,10 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', {layout: 'ant-design-pro',}], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/Exception500/README.md b/Exception500/README.md new file mode 100644 index 0000000000000000000000000000000000000000..aa01c5109b5c998fee6d72c7dedd7689c9b283f5 --- /dev/null +++ b/Exception500/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/exception500 + +Exception500 + +## Usage + +```sh +umi block add ant-design-pro/exception500 +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/Exception500/package.json b/Exception500/package.json new file mode 100644 index 0000000000000000000000000000000000000000..8b4f47fb8223287bb989b6aee605164531220d1f --- /dev/null +++ b/Exception500/package.json @@ -0,0 +1,25 @@ +{ + "name": "@umi-block/exception-500", + "version": "0.0.1", + "description": "Exception500", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/exception500" + }, + "dependencies": { + "react": "^16.6.3", + "ant-design-pro": "^2.1.1", + "dva": "^2.4.0", + "umi-request": "^1.0.0-beta.1" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/Exception500/snapshot.png b/Exception500/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..9be494c9a2a80599bbe080ca6b7a95bff8739f65 Binary files /dev/null and b/Exception500/snapshot.png differ diff --git a/Exception500/src/index.js b/Exception500/src/index.js new file mode 100644 index 0000000000000000000000000000000000000000..bef7707fecb97257f396d2b4bc46eeb70fcedd90 --- /dev/null +++ b/Exception500/src/index.js @@ -0,0 +1,15 @@ +import React from 'react'; +import { formatMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { Exception } from 'ant-design-pro'; + +const PAGE_NAME_UPPER_CAMEL_CASE = () => ( + +); + +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/Exception500/src/locales/en-US.js b/Exception500/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..522d939eb37a7887cd7129c3881b9bfcab282a76 --- /dev/null +++ b/Exception500/src/locales/en-US.js @@ -0,0 +1,4 @@ +export default { + 'BLOCK_NAME.exception.back': 'Back to home', + 'BLOCK_NAME.description.500': 'Sorry, the server is reporting an error', +}; diff --git a/Exception500/src/locales/pt-BR.js b/Exception500/src/locales/pt-BR.js new file mode 100644 index 0000000000000000000000000000000000000000..fb9a8044a354776241a653ba44b2a2260626914e --- /dev/null +++ b/Exception500/src/locales/pt-BR.js @@ -0,0 +1,4 @@ +export default { + 'BLOCK_NAME.exception.back': 'Voltar para Início', + 'BLOCK_NAME.description.500': 'Desculpe, o servidor está reportando um erro', +}; diff --git a/Exception500/src/locales/zh-CN.js b/Exception500/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..608fe8e8f720de216cd167143a3078ca2c67a94b --- /dev/null +++ b/Exception500/src/locales/zh-CN.js @@ -0,0 +1,4 @@ +export default { + 'BLOCK_NAME.exception.back': '返回首页', + 'BLOCK_NAME.description.500': '抱歉,服务器出错了', +}; diff --git a/Exception500/src/locales/zh-TW.js b/Exception500/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..bde7e357d1d97cd4796b89125f63bd18a9448737 --- /dev/null +++ b/Exception500/src/locales/zh-TW.js @@ -0,0 +1,4 @@ +export default { + 'BLOCK_NAME.exception.back': '返回首頁', + 'BLOCK_NAME.description.500': '抱歉,服務器出錯了', +}; diff --git a/LICENSE b/LICENSE index c17ba2fb848af3fca998074297d00f38536d5d13..375ea0ec1c7b089f6a2d5eaee3a44e8727bc5bb5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Alipay.inc +Copyright (c) 2018 umijs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Monitor/.gitignore b/Monitor/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/Monitor/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/Monitor/.umirc.js b/Monitor/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..70ab1e9b79813e2a091d036d763edc262cdf23bf --- /dev/null +++ b/Monitor/.umirc.js @@ -0,0 +1,18 @@ +export default { + plugins: [ + [ + 'umi-plugin-block-dev', + { + layout: 'ant-design-pro', + }, + ], + [ + 'umi-plugin-react', + { + dva: true, + locale: true, + antd: true, + }, + ], + ], +}; diff --git a/Monitor/README.md b/Monitor/README.md new file mode 100644 index 0000000000000000000000000000000000000000..bc22281fb0d1087cd10a87490f4d3d58e590ed9f --- /dev/null +++ b/Monitor/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/monitor + +Monitor + +## Usage + +```sh +umi block add ant-design-pro/monitor +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/Monitor/package.json b/Monitor/package.json new file mode 100644 index 0000000000000000000000000000000000000000..a64c33a336b81b52bf3896aae1bd964ae1ecb953 --- /dev/null +++ b/Monitor/package.json @@ -0,0 +1,28 @@ +{ + "name": "@umi-block/monitor", + "version": "0.0.1", + "description": "Monitor", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/monitor" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "dva": "^2.4.0", + "numeral": "^2.0.6", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "mockjs": "^1.0.1-beta3", + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/Monitor/snapshot.png b/Monitor/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..4fed165e448266adb07a02777977c1a5ccb6589d Binary files /dev/null and b/Monitor/snapshot.png differ diff --git a/Monitor/src/_mock.js b/Monitor/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..e6db3d9c696a0d034de5384a2562a9e5f588f35c --- /dev/null +++ b/Monitor/src/_mock.js @@ -0,0 +1,7 @@ +import mockjs from 'mockjs'; + +export default { + 'GET /api/BLOCK_NAME/tags': mockjs.mock({ + 'list|100': [{ name: '@city', 'value|1-100': 150, 'type|0-2': 1 }], + }), +}; diff --git a/src/components/ActiveChart/index.js b/Monitor/src/components/ActiveChart/index.js similarity index 96% rename from src/components/ActiveChart/index.js rename to Monitor/src/components/ActiveChart/index.js index 3d9fbbaf2e62d7eff4e9b70ba80375383e4629b4..c72c89d0fe0a1ab97768433b69a35c38cb76acee 100644 --- a/src/components/ActiveChart/index.js +++ b/Monitor/src/components/ActiveChart/index.js @@ -1,9 +1,10 @@ import React, { Component } from 'react'; -import { MiniArea } from '../Charts'; -import NumberInfo from '../NumberInfo'; +import { Charts, NumberInfo } from 'ant-design-pro'; import styles from './index.less'; +const { MiniArea } = Charts; + function fixedZero(val) { return val * 1 < 10 ? `0${val}` : val; } diff --git a/src/components/ActiveChart/index.less b/Monitor/src/components/ActiveChart/index.less similarity index 100% rename from src/components/ActiveChart/index.less rename to Monitor/src/components/ActiveChart/index.less diff --git a/src/pages/Dashboard/Monitor.js b/Monitor/src/index.js similarity index 75% rename from src/pages/Dashboard/Monitor.js rename to Monitor/src/index.js index 629091747c22a65cc6e62d7d4e87af362c2fc7fb..f90e0190d9015039899771624ff8dfc09ee520ff 100644 --- a/src/pages/Dashboard/Monitor.js +++ b/Monitor/src/index.js @@ -2,51 +2,41 @@ import React, { PureComponent } from 'react'; import { connect } from 'dva'; import { formatMessage, FormattedMessage } from 'umi/locale'; import { Row, Col, Card, Tooltip } from 'antd'; -import { Pie, WaterWave, Gauge, TagCloud } from '@/components/Charts'; -import NumberInfo from '@/components/NumberInfo'; -import CountDown from '@/components/CountDown'; -import ActiveChart from '@/components/ActiveChart'; +import { NumberInfo, Charts } from 'ant-design-pro'; +import CountDown from 'ant-design-pro/lib/CountDown'; import numeral from 'numeral'; -import GridContent from '@/components/PageHeaderWrapper/GridContent'; -import Authorized from '@/utils/Authorized'; -import styles from './Monitor.less'; +import ActiveChart from './components/ActiveChart'; +import styles from './style.less'; -const { Secured } = Authorized; +const { Pie, WaterWave, Gauge, TagCloud } = Charts; const targetTime = new Date().getTime() + 3900000; -// use permission as a parameter -const havePermissionAsync = new Promise(resolve => { - // Call resolve on behalf of passed - setTimeout(() => resolve(), 300); -}); - -@Secured(havePermissionAsync) -@connect(({ monitor, loading }) => ({ - monitor, +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ + BLOCK_NAME_CAMEL_CASE, loading: loading.models.monitor, })) -class Monitor extends PureComponent { +class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { componentDidMount() { const { dispatch } = this.props; dispatch({ - type: 'monitor/fetchTags', + type: 'BLOCK_NAME_CAMEL_CASE/fetchTags', }); } render() { - const { monitor, loading } = this.props; - const { tags } = monitor; + const { BLOCK_NAME_CAMEL_CASE, loading } = this.props; + const { tags } = BLOCK_NAME_CAMEL_CASE; return ( - + } @@ -57,7 +47,7 @@ class Monitor extends PureComponent { } @@ -69,7 +59,7 @@ class Monitor extends PureComponent { } @@ -80,7 +70,7 @@ class Monitor extends PureComponent { } @@ -91,7 +81,7 @@ class Monitor extends PureComponent { } @@ -104,7 +94,7 @@ class Monitor extends PureComponent { } @@ -121,7 +111,7 @@ class Monitor extends PureComponent { } @@ -131,13 +121,13 @@ class Monitor extends PureComponent { } + title={} style={{ marginBottom: 24 }} bodyStyle={{ textAlign: 'center' }} bordered={false} > @@ -149,7 +139,7 @@ class Monitor extends PureComponent { } @@ -162,7 +152,7 @@ class Monitor extends PureComponent { animate={false} percent={28} subTitle={ - + } total="28%" height={128} @@ -176,7 +166,7 @@ class Monitor extends PureComponent { percent={22} subTitle={ } @@ -191,7 +181,7 @@ class Monitor extends PureComponent { color="#2FC25B" percent={32} subTitle={ - + } total="32%" height={128} @@ -205,7 +195,7 @@ class Monitor extends PureComponent { } @@ -220,7 +210,7 @@ class Monitor extends PureComponent { } @@ -230,16 +220,16 @@ class Monitor extends PureComponent { + } percent={34} /> - + ); } } -export default Monitor; +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/Monitor/src/locales/en-US.js b/Monitor/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..b64c50bd4fb12a99c8e560650135041c29704afb --- /dev/null +++ b/Monitor/src/locales/en-US.js @@ -0,0 +1,18 @@ +export default { + 'BLOCK_NAME.monitor.trading-activity': 'Real-Time Trading Activity', + 'BLOCK_NAME.monitor.total-transactions': 'Total transactions today', + 'BLOCK_NAME.monitor.sales-target': 'Sales target completion rate', + 'BLOCK_NAME.monitor.remaining-time': 'Remaining time of activity', + 'BLOCK_NAME.monitor.total-transactions-per-second': 'Total transactions per second', + 'BLOCK_NAME.monitor.activity-forecast': 'Activity forecast', + 'BLOCK_NAME.monitor.efficiency': 'Efficiency', + 'BLOCK_NAME.monitor.ratio': 'Ratio', + 'BLOCK_NAME.monitor.proportion-per-category': 'Proportion Per Category', + 'BLOCK_NAME.monitor.fast-food': 'Fast food', + 'BLOCK_NAME.monitor.western-food': 'Western food', + 'BLOCK_NAME.monitor.hot-pot': 'Hot pot', + 'BLOCK_NAME.monitor.waiting-for-implementation': 'Waiting for implementation', + 'BLOCK_NAME.monitor.popular-searches': 'Popular Searches', + 'BLOCK_NAME.monitor.resource-surplus': 'Resource Surplus', + 'BLOCK_NAME.monitor.fund-surplus': 'Fund Surplus', +}; diff --git a/Monitor/src/locales/pt-BR.js b/Monitor/src/locales/pt-BR.js new file mode 100644 index 0000000000000000000000000000000000000000..bba097963109015c51b26b1dfbba345958fe2feb --- /dev/null +++ b/Monitor/src/locales/pt-BR.js @@ -0,0 +1,19 @@ +export default { + 'BLOCK_NAME.monitor.trading-activity': 'Real-Time Trading Activity', + 'BLOCK_NAME.monitor.total-transactions': 'Total transactions today', + 'BLOCK_NAME.monitor.sales-target': 'Sales target completion rate', + 'BLOCK_NAME.monitor.remaining-time': 'Remaining time of activity', + 'BLOCK_NAME.monitor.total-transactions-per-second': 'Total transactions per second', + 'BLOCK_NAME.monitor.activity-forecast': 'Activity forecast', + 'BLOCK_NAME.monitor.efficiency': 'Efficiency', + 'BLOCK_NAME.monitor.ratio': 'Ratio', + 'BLOCK_NAME.monitor.proportion-per-category': 'Proportion Per Category', + 'BLOCK_NAME.monitor.fast-food': 'Fast food', + 'BLOCK_NAME.monitor.western-food': 'Western food', + 'BLOCK_NAME.monitor.hot-pot': 'Hot pot', + 'BLOCK_NAME.monitor.waiting-for-implementation': 'Waiting for implementation', + 'BLOCK_NAME.monitor.popular-searches': 'Popular Searches', + 'BLOCK_NAME.monitor.resource-surplus': 'Resource Surplus', + 'BLOCK_NAME.monitor.fund-surplus': 'Fund Surplus', + 'BLOCK_NAME.exception.back': 'Back to home', +}; diff --git a/Monitor/src/locales/zh-CN.js b/Monitor/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..6acddfeab7d4917adfb5e47faaae8d7e8062009b --- /dev/null +++ b/Monitor/src/locales/zh-CN.js @@ -0,0 +1,18 @@ +export default { + 'BLOCK_NAME.monitor.trading-activity': '活动实时交易情况', + 'BLOCK_NAME.monitor.total-transactions': '今日交易总额', + 'BLOCK_NAME.monitor.sales-target': '销售目标完成率', + 'BLOCK_NAME.monitor.remaining-time': '活动剩余时间', + 'BLOCK_NAME.monitor.total-transactions-per-second': '每秒交易总额', + 'BLOCK_NAME.monitor.activity-forecast': '活动情况预测', + 'BLOCK_NAME.monitor.efficiency': '券核效率', + 'BLOCK_NAME.monitor.ratio': '跳出率', + 'BLOCK_NAME.monitor.proportion-per-category': '各品类占比', + 'BLOCK_NAME.monitor.fast-food': '中式快餐', + 'BLOCK_NAME.monitor.western-food': '西餐', + 'BLOCK_NAME.monitor.hot-pot': '火锅', + 'BLOCK_NAME.monitor.waiting-for-implementation': 'Waiting for implementation', + 'BLOCK_NAME.monitor.popular-searches': '热门搜索', + 'BLOCK_NAME.monitor.resource-surplus': '资源剩余', + 'BLOCK_NAME.monitor.fund-surplus': '补贴资金剩余', +}; diff --git a/Monitor/src/locales/zh-TW.js b/Monitor/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..4325e3955e2ca26785207dd9b929f25c2a699d39 --- /dev/null +++ b/Monitor/src/locales/zh-TW.js @@ -0,0 +1,18 @@ +export default { + 'BLOCK_NAME.monitor.trading-activity': '活動實時交易情況', + 'BLOCK_NAME.monitor.total-transactions': '今日交易總額', + 'BLOCK_NAME.monitor.sales-target': '銷售目標完成率', + 'BLOCK_NAME.monitor.remaining-time': '活動剩余時間', + 'BLOCK_NAME.monitor.total-transactions-per-second': '每秒交易總額', + 'BLOCK_NAME.monitor.activity-forecast': '活動情況預測', + 'BLOCK_NAME.monitor.efficiency': '券核效率', + 'BLOCK_NAME.monitor.ratio': '跳出率', + 'BLOCK_NAME.monitor.proportion-per-category': '各品類占比', + 'BLOCK_NAME.monitor.fast-food': '中式快餐', + 'BLOCK_NAME.monitor.western-food': '西餐', + 'BLOCK_NAME.monitor.hot-pot': '火鍋', + 'BLOCK_NAME.monitor.waiting-for-implementation': 'Waiting for implementation', + 'BLOCK_NAME.monitor.popular-searches': '熱門搜索', + 'BLOCK_NAME.monitor.resource-surplus': '資源剩余', + 'BLOCK_NAME.monitor.fund-surplus': '補貼資金剩余', +}; diff --git a/src/pages/Dashboard/models/monitor.js b/Monitor/src/model.js similarity index 82% rename from src/pages/Dashboard/models/monitor.js rename to Monitor/src/model.js index e3e832ff8bc79e34430a69e671d1017023c317fa..82d3b6949f4031c4a44a7637ff7bcdc07c658823 100644 --- a/src/pages/Dashboard/models/monitor.js +++ b/Monitor/src/model.js @@ -1,7 +1,7 @@ -import { queryTags } from '@/services/api'; +import { queryTags } from './service'; export default { - namespace: 'monitor', + namespace: 'BLOCK_NAME_CAMEL_CASE', state: { tags: [], diff --git a/Monitor/src/service.js b/Monitor/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..9f97787cd93d9c437d55d822173b20e1e58d65ba --- /dev/null +++ b/Monitor/src/service.js @@ -0,0 +1,5 @@ +import request from 'umi-request'; + +export async function queryTags() { + return request('/api/BLOCK_NAME/tags'); +} diff --git a/src/pages/Dashboard/Monitor.less b/Monitor/src/style.less similarity index 91% rename from src/pages/Dashboard/Monitor.less rename to Monitor/src/style.less index ca41f33e3cc29540c6c4dc72f483eedc2860cb53..f73a6efd81656afd0bdac3c4d14d7c00d98deda8 100644 --- a/src/pages/Dashboard/Monitor.less +++ b/Monitor/src/style.less @@ -1,5 +1,4 @@ @import '~antd/lib/style/themes/default.less'; -@import '~@/utils/utils.less'; .mapChart { padding-top: 24px; diff --git a/README.md b/README.md index 21268cc68e2c4695536357999c24702eabe92fc1..718927b89154adbccd138d755a7644a1726ac5ae 100644 --- a/README.md +++ b/README.md @@ -1,137 +1,22 @@ -English | [简体中文](./README.zh-CN.md) | [Русский](./README.ru-RU.md) +# umi-blocks -Ant Design Pro - - - -An out-of-box UI solution for enterprise applications as a React boilerplate. - -[](https://circleci.com/gh/ant-design/ant-design-pro/) -[](https://ci.appveyor.com/project/afc163/ant-design-pro/branch/master) -[](https://david-dm.org/ant-design/ant-design-pro) -[](https://david-dm.org/ant-design/ant-design-pro?type=dev) -[](https://gitter.im/ant-design/pro-english?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)(🇺🇸) -[](https://gitter.im/ant-design/ant-design-pro?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)(🇨🇳) - - - - - - -- Preview: http://preview.pro.ant.design -- Home Page: http://pro.ant.design -- Documentation: http://pro.ant.design/docs/getting-started -- ChangeLog: http://pro.ant.design/docs/changelog -- FAQ: http://pro.ant.design/docs/faq -- Mirror Site in China: http://ant-design-pro.gitee.io - -## 2.0 Released Now! 🎉🎉🎉 -[Announcing Ant Design Pro 2.0.0](https://medium.com/ant-design/beautiful-and-powerful-ant-design-pro-2-0-release-51358da5af95) - -## Translation Recruitment :loudspeaker: - -We need your help: https://github.com/ant-design/ant-design-pro/issues/120 - -## Features - -- :gem: **Neat Design**: Follow [Ant Design specification](http://ant.design/) -- :triangular_ruler: **Common Templates**: Typical templates for enterprise applications -- :rocket: **State of The Art Development**: Newest development stack of React/umi/dva/antd -- :iphone: **Responsive**: Designed for variable screen sizes -- :art: **Theming**: Customizable theme with simple config -- :globe_with_meridians: **International**: Built-in i18n solution -- :gear: **Best Practices**: Solid workflow to make your code healthy -- :1234: **Mock development**: Easy to use mock development solution -- :white_check_mark: **UI Test**: Fly safely with unit and e2e tests - -## Templates - -``` -- Dashboard - - Analytic - - Monitor - - Workspace -- Form - - Basic Form - - Step Form - - Advanced From -- List - - Standard Table - - Standard List - - Card List - - Search List (Project/Applications/Article) -- Profile - - Simple Profile - - Advanced Profile -- Account - - Account Center - - Account Settings -- Result - - Success - - Failed -- Exception - - 403 - - 404 - - 500 -- User - - Login - - Register - - Register Result -``` +Official collection of some high quality blocks. ## Usage -### Use bash - -```bash -$ git clone https://github.com/ant-design/ant-design-pro.git --depth=1 -$ cd ant-design-pro -$ npm install -$ npm start # visit http://localhost:8000 +```shell +$ umi block list +$ umi block add [A block name in list, or any github address of a umi block] ``` -### Use by docker - -```bash -# preview -$ docker pull antdesign/ant-design-pro -$ docker run -p 80:80 antdesign/ant-design-pro -# open http://localhost - -# dev -$ npm run docker:dev +You can visit umi [doc](https://umijs.org/guide/block.html) for find out more info about umi block. -# build -$ npm run docker:build +## Contribute +You can create a umi block and make a PR for us! -# production dev -$ npm run docker-prod:dev +How to create a block: -# production build -$ npm run docker-prod:build +```shell +$ yarn create umi --block ``` - -### Use Gitpod - -Open the project in Gitpod (free online dev environment for GitHub) and start coding immediately. - -[](https://gitpod.io/#https://github.com/ant-design/ant-design-pro) - -More instructions at [documentation](http://pro.ant.design/docs/getting-started). - -## Browsers support - -Modern browsers and IE11. - -| [](http://godban.github.io/browsers-support-badges/)IE / Edge | [](http://godban.github.io/browsers-support-badges/)Firefox | [](http://godban.github.io/browsers-support-badges/)Chrome | [](http://godban.github.io/browsers-support-badges/)Safari | [](http://godban.github.io/browsers-support-badges/)Opera | -| --------- | --------- | --------- | --------- | --------- | -| IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions - -## Contributing - -Any type of contribution is welcome, here are some examples of how you may contribute to this project: - -- Use Ant Design Pro in your daily work. -- Submit [issues](http://github.com/ant-design/ant-design-pro/issues) to report bugs or ask questions. -- Propose [pull requests](http://github.com/ant-design/ant-design-pro/pulls) to improve our code. diff --git a/README.ru-RU.md b/README.ru-RU.md deleted file mode 100644 index c20880ee8104c76327f9aaff48f5ebb1fb224942..0000000000000000000000000000000000000000 --- a/README.ru-RU.md +++ /dev/null @@ -1,102 +0,0 @@ -[English](./README.md) | [简体中文](./README.zh-CN.md) | Русский - -Ant Design Pro - - - -UI-решение "из коробки" для корпоративных приложений как React boilerplate - -[](https://circleci.com/gh/ant-design/ant-design-pro/) -[](https://ci.appveyor.com/project/afc163/ant-design-pro/branch/master) -[](https://david-dm.org/ant-design/ant-design-pro) -[](https://david-dm.org/ant-design/ant-design-pro?type=dev) -[](https://gitter.im/ant-design/ant-design-pro?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) - - - - - -- Демо: http://preview.pro.ant.design -- Домашняя страница: http://pro.ant.design -- Документация: http://pro.ant.design/docs/getting-started -- История изменений: http://pro.ant.design/docs/changelog -- FAQ: http://pro.ant.design/docs/faq -- Китайское зеркало сайта: http://ant-design-pro.gitee.io - -## Поиск переводчиков :loudspeaker: - -Нам нужна ваша помощь: https://github.com/ant-design/ant-design-pro/issues/120 - -## Возможности - -- :gem: **Аккуратный дизайн**: Посмотрите [спецификацию Ant Design](http://ant.design/) -- :triangular_ruler: **Общие шаблоны**: Стандартные шаблоны для корпоративных приложений -- :rocket: **Разработка, как искусство**: Новейший стек технологий React/umi/dva/antd -- :iphone: **Отзывчивая верстка**: Создан для экранов разных размеров -- :art: **Темизация**: Возможность изменения темы с помощью конфигурации -- :globe_with_meridians: **Мультиязычность**: Встроенное i18n решение -- :gear: **Лучшие практики**: Надежные процессы для хорошего кода -- :1234: **Разработка по шаблону**: Простое в использовании решение для разработки -- :white_check_mark: **UI тесты**: Разрабатывайте безопасно с юнит и e2e тестами - -## Шаблоны - -``` -- Dashboard - - Analytic - - Monitor - - Workspace -- Form - - Basic Form - - Step Form - - Advanced From -- List - - Standard Table - - Standard List - - Card List - - Search List (Project/Applications/Article) -- Profile - - Simple Profile - - Advanced Profile -- Account - - Account Center - - Account Settings -- Result - - Success - - Failed -- Exception - - 403 - - 404 - - 500 -- User - - Login - - Register - - Register Result -``` - -## Использование - -```bash -$ git clone https://github.com/ant-design/ant-design-pro.git --depth=1 -$ cd ant-design-pro -$ npm install -$ npm start # visit http://localhost:8000 -``` - -Больше информации в [документации](http://pro.ant.design/docs/getting-started). - -## Совместимость - -Современные браузеры и IE11. - -| [](http://godban.github.io/browsers-support-badges/)IE / Edge | [](http://godban.github.io/browsers-support-badges/)Firefox | [](http://godban.github.io/browsers-support-badges/)Chrome | [](http://godban.github.io/browsers-support-badges/)Safari | [](http://godban.github.io/browsers-support-badges/)Opera | -| --------- | --------- | --------- | --------- | --------- | -| IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions - -## Распространение - -Любые варианты распространения приветствуются! Вот несколько примеров того, как вы можете помочь распространению проекта: - -- Использовать Ant Design Pro в ежедневной работе. -- Создавать [задачи](http://github.com/ant-design/ant-design-pro/issues) заводить баги или отвечать на вопросы. -- Делать [pull-реквесты](http://github.com/ant-design/ant-design-pro/pulls) для совершенствования нашего кода. diff --git a/README.zh-CN.md b/README.zh-CN.md deleted file mode 100644 index e1682437558d7af9a73d8fd8ce4de4eec4bce434..0000000000000000000000000000000000000000 --- a/README.zh-CN.md +++ /dev/null @@ -1,121 +0,0 @@ -[English](./README.md) | 简体中文 | [Русский](./README.ru-RU.md) - -Ant Design Pro - - - -开箱即用的中台前端/设计解决方案。 - -[](https://circleci.com/gh/ant-design/ant-design-pro/) -[](https://ci.appveyor.com/project/afc163/ant-design-pro/branch/master) -[](https://david-dm.org/ant-design/ant-design-pro) -[](https://david-dm.org/ant-design/ant-design-pro?type=dev) -[](https://gitter.im/ant-design/ant-design-pro?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) - - - - - -- 预览:http://preview.pro.ant.design -- 首页:http://pro.ant.design/index-cn -- 使用文档:http://pro.ant.design/docs/getting-started-cn -- 更新日志: http://pro.ant.design/docs/changelog-cn -- 常见问题:http://pro.ant.design/docs/faq-cn -- 国内镜像:http://ant-design-pro.gitee.io - -## 特性 - -- :gem: **优雅美观**:基于 Ant Design 体系精心设计 -- :triangular_ruler: **常见设计模式**:提炼自中后台应用的典型页面和场景 -- :rocket: **最新技术栈**:使用 React/umi/dva/antd 等前端前沿技术开发 -- :iphone: **响应式**:针对不同屏幕大小设计 -- :art: **主题**:可配置的主题满足多样化的品牌诉求 -- :globe_with_meridians: **国际化**:内建业界通用的国际化方案 -- :gear: **最佳实践**:良好的工程实践助您持续产出高质量代码 -- :1234: **Mock 数据**:实用的本地数据调试方案 -- :white_check_mark: **UI 测试**:自动化测试保障前端产品质量 - -## 模板 - -``` -- Dashboard - - 分析页 - - 监控页 - - 工作台 -- 表单页 - - 基础表单页 - - 分步表单页 - - 高级表单页 -- 列表页 - - 查询表格 - - 标准列表 - - 卡片列表 - - 搜索列表(项目/应用/文章) -- 详情页 - - 基础详情页 - - 高级详情页 -- 用户 - - 用户中心页 - - 用户设置页 -- 结果 - - 成功页 - - 失败页 -- 异常 - - 403 无权限 - - 404 找不到 - - 500 服务器出错 -- 帐户 - - 登录 - - 注册 - - 注册成功 -``` - -## 使用 - -### 使用命令行 -```bash -$ git clone https://github.com/ant-design/ant-design-pro.git --depth=1 -$ cd ant-design-pro -$ npm install -$ npm start # 访问 http://localhost:8000 -``` - -### 使用 docker - -```bash -# preview -$ docker pull chenshuai2144/ant-design-pro -$ docker run -p 80:80 chenshuai2144/ant-design-pro -# open http://localhost - -# dev -$ npm run docker:dev - -# build -$ npm run docker:build - - -# production dev -$ npm run docker-prod:dev - -// production build -$ npm run docker-prod:build -``` - -更多信息请参考 [使用文档](http://pro.ant.design/docs/getting-started)。 - -## 支持环境 - -现代浏览器及 IE11。 - -| [](http://godban.github.io/browsers-support-badges/)IE / Edge | [](http://godban.github.io/browsers-support-badges/)Firefox | [](http://godban.github.io/browsers-support-badges/)Chrome | [](http://godban.github.io/browsers-support-badges/)Safari | [](http://godban.github.io/browsers-support-badges/)Opera | -| --------- | --------- | --------- | --------- | --------- | -| IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions - -## 参与贡献 - -我们非常欢迎你的贡献,你可以通过以下方式和我们一起共建 :smiley:: - -- 在你的公司或个人项目中使用 Ant Design Pro。 -- 通过 [Issue](http://github.com/ant-design/ant-design-pro/issues) 报告 bug 或进行咨询。 -- 提交 [Pull Request](http://github.com/ant-design/ant-design-pro/pulls) 改进 Pro 的代码。 diff --git a/ResultFail/.gitignore b/ResultFail/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/ResultFail/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/ResultFail/.umirc.js b/ResultFail/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/ResultFail/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/ResultFail/README.md b/ResultFail/README.md new file mode 100644 index 0000000000000000000000000000000000000000..66633a0bc656aec8393bb9b0e2d122c9889998ef --- /dev/null +++ b/ResultFail/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/resulterror + +ResultError + +## Usage + +```sh +umi block add ant-design-pro/resulterror +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/ResultFail/package.json b/ResultFail/package.json new file mode 100644 index 0000000000000000000000000000000000000000..dd42ba5179f25f26c8d5cba5b7ef6f9c3739d02f --- /dev/null +++ b/ResultFail/package.json @@ -0,0 +1,24 @@ +{ + "name": "@umi-block/result-fail", + "version": "0.0.1", + "description": "ResultFail", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/resultfail" + }, + "dependencies": { + "react": "^16.6.3", + "antd": "^3.10.9", + "ant-design-pro": "^2.1.1" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/ResultFail/snapshot.png b/ResultFail/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..a81d160047f8d05975a7e8e85a9352cdd06230e0 Binary files /dev/null and b/ResultFail/snapshot.png differ diff --git a/src/pages/Result/Error.js b/ResultFail/src/index.js similarity index 60% rename from src/pages/Result/Error.js rename to ResultFail/src/index.js index fba2da6d13c08785b0443c8760308b0aeebd2863..6077ce97a313ef40cdddd83647010a52e4a9669a 100644 --- a/src/pages/Result/Error.js +++ b/ResultFail/src/index.js @@ -1,8 +1,7 @@ import React, { Fragment } from 'react'; import { formatMessage, FormattedMessage } from 'umi/locale'; import { Button, Icon, Card } from 'antd'; -import Result from '@/components/Result'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; +import { Result } from 'ant-design-pro'; const extra = ( @@ -15,29 +14,29 @@ const extra = ( }} > - + - + @@ -46,21 +45,19 @@ const extra = ( const actions = ( - + ); export default () => ( - - - - - + + + ); diff --git a/ResultFail/src/locales/en-US.js b/ResultFail/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..e3614df73f2362a9ffe40de7d5dc9ebc3b333d68 --- /dev/null +++ b/ResultFail/src/locales/en-US.js @@ -0,0 +1,11 @@ +export default { + 'BLOCK_NAME.error.title': 'Submission Failed', + 'BLOCK_NAME.error.description': + 'Please check and modify the following information before resubmitting.', + 'BLOCK_NAME.error.hint-title': 'The content you submitted has the following error:', + 'BLOCK_NAME.error.hint-text1': 'Your account has been frozen', + 'BLOCK_NAME.error.hint-btn1': 'Thaw immediately', + 'BLOCK_NAME.error.hint-text2': 'Your account is not yet eligible to apply', + 'BLOCK_NAME.error.hint-btn2': 'Upgrade immediately', + 'BLOCK_NAME.error.btn-text': 'Return to modify', +}; diff --git a/ResultFail/src/locales/zh-CN.js b/ResultFail/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..dbff13807ed4a3cafa5859d98cff7f6aca5ffc8f --- /dev/null +++ b/ResultFail/src/locales/zh-CN.js @@ -0,0 +1,10 @@ +export default { + 'BLOCK_NAME.error.title': '提交失败', + 'BLOCK_NAME.error.description': '请核对并修改以下信息后,再重新提交。', + 'BLOCK_NAME.error.hint-title': '您提交的内容有如下错误:', + 'BLOCK_NAME.error.hint-text1': '您的账户已被冻结', + 'BLOCK_NAME.error.hint-btn1': '立即解冻', + 'BLOCK_NAME.error.hint-text2': '您的账户还不具备申请资格', + 'BLOCK_NAME.error.hint-btn2': '立即升级', + 'BLOCK_NAME.error.btn-text': '返回修改', +}; diff --git a/ResultFail/src/locales/zh-TW.js b/ResultFail/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..7be4bc73062789ebf1bf22bb27f15944cdb22fbd --- /dev/null +++ b/ResultFail/src/locales/zh-TW.js @@ -0,0 +1,10 @@ +export default { + 'BLOCK_NAME.error.title': '提交失敗', + 'BLOCK_NAME.error.description': '請核對並修改以下信息後,再重新提交。', + 'BLOCK_NAME.error.hint-title': '您提交的內容有如下錯誤:', + 'BLOCK_NAME.error.hint-text1': '您的賬戶已被凍結', + 'BLOCK_NAME.error.hint-btn1': '立即解凍', + 'BLOCK_NAME.error.hint-text2': '您的賬戶還不具備申請資格', + 'BLOCK_NAME.error.hint-btn2': '立即升級', + 'BLOCK_NAME.error.btn-text': '返回修改', +}; diff --git a/ResultSuccess/.gitignore b/ResultSuccess/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/ResultSuccess/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/ResultSuccess/.umirc.js b/ResultSuccess/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/ResultSuccess/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/ResultSuccess/README.md b/ResultSuccess/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a13b9ee23c289abdb2cf0fbbe42f34b46999231e --- /dev/null +++ b/ResultSuccess/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/resultsuccess + +ResultSuccess + +## Usage + +```sh +umi block add ant-design-pro/resultsuccess +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/ResultSuccess/package.json b/ResultSuccess/package.json new file mode 100644 index 0000000000000000000000000000000000000000..971e1a739dd29c3f79bde7a755cdf12d757ea18f --- /dev/null +++ b/ResultSuccess/package.json @@ -0,0 +1,24 @@ +{ + "name": "@umi-block/result-success", + "version": "0.0.1", + "description": "ResultSuccess", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/resultsuccess" + }, + "dependencies": { + "react": "^16.6.3", + "antd": "^3.10.9", + "ant-design-pro": "^2.1.1" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/ResultSuccess/snapshot.png b/ResultSuccess/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..151391d439cd018553d4ec704a932f9505da4f78 Binary files /dev/null and b/ResultSuccess/snapshot.png differ diff --git a/src/pages/Result/Success.js b/ResultSuccess/src/index.js similarity index 67% rename from src/pages/Result/Success.js rename to ResultSuccess/src/index.js index 74d19dc38c23dc39c73f107c6407cb577bbcb3e7..615be18115f8fcb978c9a47989e98c069984e729 100644 --- a/src/pages/Result/Success.js +++ b/ResultSuccess/src/index.js @@ -1,8 +1,7 @@ import React, { Fragment } from 'react'; import { formatMessage, FormattedMessage } from 'umi/locale'; import { Button, Row, Col, Icon, Steps, Card } from 'antd'; -import Result from '@/components/Result'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; +import { Result } from 'ant-design-pro'; const { Step } = Steps; @@ -17,7 +16,7 @@ const desc1 = ( }} > - + 2016-12-12 12:32 @@ -27,12 +26,12 @@ const desc1 = ( const desc2 = ( - + - + @@ -48,25 +47,25 @@ const extra = ( marginBottom: 20, }} > - + - + 23421 - + - + @@ -77,7 +76,7 @@ const extra = ( - + } description={desc1} @@ -86,7 +85,7 @@ const extra = ( title={ @@ -97,7 +96,7 @@ const extra = ( title={ @@ -106,7 +105,7 @@ const extra = ( - + } /> @@ -117,28 +116,26 @@ const extra = ( const actions = ( - + - + - + ); export default () => ( - - - - - + + + ); diff --git a/ResultSuccess/src/locales/en-US.js b/ResultSuccess/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..e870ed40c50b674a22fda0273a16958c2c47d84f --- /dev/null +++ b/ResultSuccess/src/locales/en-US.js @@ -0,0 +1,19 @@ +export default { + 'BLOCK_NAME.success.title': 'Submission Success', + 'BLOCK_NAME.success.description': + 'The submission results page is used to feed back the results of a series of operational tasks. If it is a simple operation, use the Message global prompt feedback. This text area can show a simple supplementary explanation. If there is a similar requirement for displaying “documents”, the following gray area can present more complicated content.', + 'BLOCK_NAME.success.operate-title': 'Project Name', + 'BLOCK_NAME.success.operate-id': 'Project ID:', + 'BLOCK_NAME.success.principal': 'Principal:', + 'BLOCK_NAME.success.operate-time': 'Effective time:', + 'BLOCK_NAME.success.step1-title': 'Create project', + 'BLOCK_NAME.success.step1-operator': 'Qu Lili', + 'BLOCK_NAME.success.step2-title': 'Departmental preliminary review', + 'BLOCK_NAME.success.step2-operator': 'Zhou Maomao', + 'BLOCK_NAME.success.step2-extra': 'Urge', + 'BLOCK_NAME.success.step3-title': 'Financial review', + 'BLOCK_NAME.success.step4-title': 'Finish', + 'BLOCK_NAME.success.btn-return': 'Back to list', + 'BLOCK_NAME.success.btn-project': 'View project', + 'BLOCK_NAME.success.btn-print': 'Print', +}; diff --git a/ResultSuccess/src/locales/zh-CN.js b/ResultSuccess/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..b73ec03a1e1b3c0fb28f3ce491899f6ad0c9f945 --- /dev/null +++ b/ResultSuccess/src/locales/zh-CN.js @@ -0,0 +1,19 @@ +export default { + 'BLOCK_NAME.success.title': '提交成功', + 'BLOCK_NAME.success.description': + '提交结果页用于反馈一系列操作任务的处理结果, 如果仅是简单操作,使用 Message 全局提示反馈即可。 本文字区域可以展示简单的补充说明,如果有类似展示 “单据”的需求,下面这个灰色区域可以呈现比较复杂的内容。', + 'BLOCK_NAME.success.operate-title': '项目名称', + 'BLOCK_NAME.success.operate-id': '项目 ID:', + 'BLOCK_NAME.success.principal': '负责人:', + 'BLOCK_NAME.success.operate-time': '生效时间:', + 'BLOCK_NAME.success.step1-title': '创建项目', + 'BLOCK_NAME.success.step1-operator': '曲丽丽', + 'BLOCK_NAME.success.step2-title': '部门初审', + 'BLOCK_NAME.success.step2-operator': '周毛毛', + 'BLOCK_NAME.success.step2-extra': '催一下', + 'BLOCK_NAME.success.step3-title': '财务复核', + 'BLOCK_NAME.success.step4-title': '完成', + 'BLOCK_NAME.success.btn-return': '返回列表', + 'BLOCK_NAME.success.btn-project': '查看项目', + 'BLOCK_NAME.success.btn-print': '打印', +}; diff --git a/ResultSuccess/src/locales/zh-TW.js b/ResultSuccess/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..1f733839c895386f250cf5fcb0ce1174f013117c --- /dev/null +++ b/ResultSuccess/src/locales/zh-TW.js @@ -0,0 +1,19 @@ +export default { + 'BLOCK_NAME.success.title': '提交成功', + 'BLOCK_NAME.success.description': + '提交結果頁用於反饋壹系列操作任務的處理結果, 如果僅是簡單操作,使用 Message 全局提示反饋即可。 本文字區域可以展示簡單的補充說明,如果有類似展示 “單據”的需求,下面這個灰色區域可以呈現比較復雜的內容。', + 'BLOCK_NAME.success.operate-title': '項目名稱', + 'BLOCK_NAME.success.operate-id': '項目 ID:', + 'BLOCK_NAME.success.principal': '負責人:', + 'BLOCK_NAME.success.operate-time': '生效時間:', + 'BLOCK_NAME.success.step1-title': '創建項目', + 'BLOCK_NAME.success.step1-operator': '曲麗麗', + 'BLOCK_NAME.success.step2-title': '部門初審', + 'BLOCK_NAME.success.step2-operator': '周毛毛', + 'BLOCK_NAME.success.step2-extra': '催壹下', + 'BLOCK_NAME.success.step3-title': '財務復核', + 'BLOCK_NAME.success.step4-title': '完成', + 'BLOCK_NAME.success.btn-return': '返回列表', + 'BLOCK_NAME.success.btn-project': '查看項目', + 'BLOCK_NAME.success.btn-print': '打印', +}; diff --git a/SearchListApplications/.gitignore b/SearchListApplications/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/SearchListApplications/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/SearchListApplications/.umirc.js b/SearchListApplications/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/SearchListApplications/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/SearchListApplications/README.md b/SearchListApplications/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c1a14217f4502372309d527550e0ca5a00849882 --- /dev/null +++ b/SearchListApplications/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/searchlistapplications + +SearchListApplications + +## Usage + +```sh +umi block add ant-design-pro/searchlistapplications +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/SearchListApplications/package.json b/SearchListApplications/package.json new file mode 100644 index 0000000000000000000000000000000000000000..c909fae2f2ac90b74871d8ad2552681a8fc329f8 --- /dev/null +++ b/SearchListApplications/package.json @@ -0,0 +1,31 @@ +{ + "name": "@umi-block/search-list-applications", + "version": "0.0.1", + "description": "SearchListApplications", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/searchlistapplications" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "classnames": "^2.2.6", + "dva": "^2.4.0", + "hash.js": "^1.1.5", + "moment": "^2.22.2", + "numeral": "^2.0.6", + "nzh": "^1.0.3", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/SearchListApplications/snapshot.png b/SearchListApplications/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..4b4d265a65bfb3c2d634db7d51478163427dc87b Binary files /dev/null and b/SearchListApplications/snapshot.png differ diff --git a/SearchListApplications/src/_mock.js b/SearchListApplications/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..c6903658fb8dfc249d8bb6f1abf8ad7a371ab41f --- /dev/null +++ b/SearchListApplications/src/_mock.js @@ -0,0 +1,107 @@ +const titles = [ + 'Alipay', + 'Angular', + 'Ant Design', + 'Ant Design Pro', + 'Bootstrap', + 'React', + 'Vue', + 'Webpack', +]; +const avatars = [ + 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png', // Alipay + 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png', // Angular + 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', // Ant Design + 'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', // Ant Design Pro + 'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png', // Bootstrap + 'https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png', // React + 'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png', // Vue + 'https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png', // Webpack +]; + +const covers = [ + 'https://gw.alipayobjects.com/zos/rmsportal/uMfMFlvUuceEyPpotzlq.png', + 'https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png', + 'https://gw.alipayobjects.com/zos/rmsportal/iXjVmWVHbCJAyqvDxdtx.png', + 'https://gw.alipayobjects.com/zos/rmsportal/gLaIAoVWTtLbBWZNYEMg.png', +]; +const desc = [ + '那是一种内在的东西, 他们到达不了,也无法触及的', + '希望是一个好东西,也许是最好的,好东西是不会消亡的', + '生命就像一盒巧克力,结果往往出人意料', + '城镇中有那么多的酒馆,她却偏偏走进了我的酒馆', + '那时候我只会想自己想要什么,从不想自己拥有什么', +]; +const user = [ + '付小小', + '曲丽丽', + '林东东', + '周星星', + '吴加好', + '朱偏右', + '鱼酱', + '乐哥', + '谭小仪', + '仲尼', +]; + +function fakeList(count) { + const list = []; + for (let i = 0; i < count; i += 1) { + list.push({ + id: `fake-list-${i}`, + owner: user[i % 10], + title: titles[i % 8], + avatar: avatars[i % 8], + cover: parseInt(i / 4, 10) % 2 === 0 ? covers[i % 4] : covers[3 - (i % 4)], + status: ['active', 'exception', 'normal'][i % 3], + percent: Math.ceil(Math.random() * 50) + 50, + logo: avatars[i % 8], + href: 'https://ant.design', + updatedAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i), + createdAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i), + subDescription: desc[i % 5], + description: + '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。', + activeUser: Math.ceil(Math.random() * 100000) + 100000, + newUser: Math.ceil(Math.random() * 1000) + 1000, + star: Math.ceil(Math.random() * 100) + 100, + like: Math.ceil(Math.random() * 100) + 100, + message: Math.ceil(Math.random() * 10) + 10, + content: + '段落示意:蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。', + members: [ + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png', + name: '曲丽丽', + id: 'member1', + }, + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png', + name: '王昭君', + id: 'member2', + }, + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png', + name: '董娜娜', + id: 'member3', + }, + ], + }); + } + + return list; +} + +function getFakeList(req, res) { + const params = req.query; + + const count = params.count * 1 || 20; + + const result = fakeList(count); + return res.json(result); +} + +export default { + 'GET /api/BLOCK_NAME/fake_list': getFakeList, +}; diff --git a/SearchListApplications/src/components/PageHeaderWrapper/index.js b/SearchListApplications/src/components/PageHeaderWrapper/index.js new file mode 100644 index 0000000000000000000000000000000000000000..c11873f2c8c24d44391261910d5adb52ab916d1a --- /dev/null +++ b/SearchListApplications/src/components/PageHeaderWrapper/index.js @@ -0,0 +1,25 @@ +import React from 'react'; +import { FormattedMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { PageHeader } from 'ant-design-pro'; +import styles from './index.less'; + +const PageHeaderWrapper = ({ children, wrapperClassName, ...restProps }) => ( + + } + key="pageheader" + {...restProps} + linkElement={Link} + itemRender={item => { + if (item.locale) { + return ; + } + return item.title; + }} + /> + {children ? {children} : null} + +); + +export default PageHeaderWrapper; diff --git a/SearchListApplications/src/components/PageHeaderWrapper/index.less b/SearchListApplications/src/components/PageHeaderWrapper/index.less new file mode 100644 index 0000000000000000000000000000000000000000..39a449657a98b039c29e6654fd117267cbb5283a --- /dev/null +++ b/SearchListApplications/src/components/PageHeaderWrapper/index.less @@ -0,0 +1,11 @@ +@import '~antd/lib/style/themes/default.less'; + +.content { + margin: 24px 24px 0; +} + +@media screen and (max-width: @screen-sm) { + .content { + margin: 24px 0 0; + } +} diff --git a/src/components/StandardFormRow/index.js b/SearchListApplications/src/components/StandardFormRow/index.js similarity index 100% rename from src/components/StandardFormRow/index.js rename to SearchListApplications/src/components/StandardFormRow/index.js diff --git a/src/components/StandardFormRow/index.less b/SearchListApplications/src/components/StandardFormRow/index.less similarity index 100% rename from src/components/StandardFormRow/index.less rename to SearchListApplications/src/components/StandardFormRow/index.less diff --git a/SearchListApplications/src/index.js b/SearchListApplications/src/index.js new file mode 100644 index 0000000000000000000000000000000000000000..e9e458b2f07f15b03838f76972f1ee981d564084 --- /dev/null +++ b/SearchListApplications/src/index.js @@ -0,0 +1,201 @@ +import React, { PureComponent } from 'react'; +import numeral from 'numeral'; +import { connect } from 'dva'; +import { Row, Col, Form, Card, Select, Icon, Avatar, List, Tooltip, Dropdown, Menu, Input } from 'antd'; +import { TagSelect } from 'ant-design-pro'; + +import StandardFormRow from './components/StandardFormRow'; +import PageHeaderWrapper from './components/PageHeaderWrapper'; +import { formatWan } from './utils/utils'; +import styles from './style.less'; + +const { Option } = Select; +const FormItem = Form.Item; + +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ + BLOCK_NAME_CAMEL_CASE, + loading: loading.models.BLOCK_NAME_CAMEL_CASE, +})) +@Form.create({ + onValuesChange({ dispatch }, changedValues, allValues) { + // 表单项变化时请求数据 + // eslint-disable-next-line + console.log(changedValues, allValues); + // 模拟查询表单生效 + dispatch({ + type: 'BLOCK_NAME_CAMEL_CASE/fetch', + payload: { + count: 8, + }, + }); + }, +}) +class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { + componentDidMount() { + const { dispatch } = this.props; + dispatch({ + type: 'BLOCK_NAME_CAMEL_CASE/fetch', + payload: { + count: 8, + }, + }); + } + + render() { + const { + BLOCK_NAME_CAMEL_CASE: { list }, + loading, + form, + } = this.props; + const { getFieldDecorator } = form; + + const CardInfo = ({ activeUser, newUser }) => ( + + + 活跃用户 + {activeUser} + + + 新增用户 + {newUser} + + + ); + + const formItemLayout = { + wrapperCol: { + xs: { span: 24 }, + sm: { span: 16 }, + }, + }; + + const itemMenu = ( + + + + 1st menu item + + + + + 2nd menu item + + + + + 3d menu item + + + + ); + + const mainSearch = ( + + + + ); + + return ( + + + + + + + {getFieldDecorator('category')( + + 类目一 + 类目二 + 类目三 + 类目四 + 类目五 + 类目六 + 类目七 + 类目八 + 类目九 + 类目十 + 类目十一 + 类目十二 + + )} + + + + + + + {getFieldDecorator('author', {})( + + 王昭君 + + )} + + + + + {getFieldDecorator('rate', {})( + + 优秀 + 普通 + + )} + + + + + + + ( + + + + , + + + , + + + , + + + , + ]} + > + } title={item.title} /> + + + + + + )} + /> + + + ); + } +} + +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/SearchListApplications/src/model.js b/SearchListApplications/src/model.js new file mode 100644 index 0000000000000000000000000000000000000000..ead65a8df48a91a8b103af60429206eb865c7230 --- /dev/null +++ b/SearchListApplications/src/model.js @@ -0,0 +1,28 @@ +import { queryFakeList } from './service'; + +export default { + namespace: 'BLOCK_NAME_CAMEL_CASE', + + state: { + list: [], + }, + + effects: { + *fetch({ payload }, { call, put }) { + const response = yield call(queryFakeList, payload); + yield put({ + type: 'queryList', + payload: Array.isArray(response) ? response : [], + }); + }, + }, + + reducers: { + queryList(state, action) { + return { + ...state, + list: action.payload, + }; + }, + }, +}; diff --git a/SearchListApplications/src/service.js b/SearchListApplications/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..f6d5bc70b96dc475843315338bd05e84667a7398 --- /dev/null +++ b/SearchListApplications/src/service.js @@ -0,0 +1,7 @@ +import request from 'umi-request'; + +export async function queryFakeList(params) { + return request(`/api/BLOCK_NAME/fake_list`, { + params, + }); +} diff --git a/src/pages/List/Applications.less b/SearchListApplications/src/style.less similarity index 96% rename from src/pages/List/Applications.less rename to SearchListApplications/src/style.less index 8f5cb368d3931865ad68f330e4d2ceb0b4df21cd..861876f689d6603707bd4a9f443ba94aebc159c7 100644 --- a/src/pages/List/Applications.less +++ b/SearchListApplications/src/style.less @@ -1,5 +1,5 @@ @import '~antd/lib/style/themes/default.less'; -@import '~@/utils/utils.less'; +@import './utils/utils.less'; .filterCardList { margin-bottom: -24px; diff --git a/SearchListApplications/src/utils/utils.js b/SearchListApplications/src/utils/utils.js new file mode 100644 index 0000000000000000000000000000000000000000..ad46b9c9fa3ba1322d951d8df8dc7b8120a45b71 --- /dev/null +++ b/SearchListApplications/src/utils/utils.js @@ -0,0 +1,28 @@ +import React from 'react'; + +export function formatWan(val) { + const v = val * 1; + if (!v || Number.isNaN(v)) return ''; + + let result = val; + if (val > 10000) { + result = Math.floor(val / 10000); + result = ( + + {result} + + 万 + + + ); + } + return result; +} diff --git a/SearchListApplications/src/utils/utils.less b/SearchListApplications/src/utils/utils.less new file mode 100644 index 0000000000000000000000000000000000000000..725792252787f49efba4f4e887301195a9818f3f --- /dev/null +++ b/SearchListApplications/src/utils/utils.less @@ -0,0 +1,50 @@ +.textOverflow() { + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + white-space: nowrap; +} + +.textOverflowMulti(@line: 3, @bg: #fff) { + overflow: hidden; + position: relative; + line-height: 1.5em; + max-height: @line * 1.5em; + text-align: justify; + margin-right: -1em; + padding-right: 1em; + &:before { + background: @bg; + content: '...'; + padding: 0 1px; + position: absolute; + right: 14px; + bottom: 0; + } + &:after { + background: white; + content: ''; + margin-top: 0.2em; + position: absolute; + right: 14px; + width: 1em; + height: 1em; + } +} + +// mixins for clearfix +// ------------------------ +.clearfix() { + zoom: 1; + &:before, + &:after { + content: ' '; + display: table; + } + &:after { + clear: both; + visibility: hidden; + font-size: 0; + height: 0; + } +} diff --git a/SearchListArticles/.gitignore b/SearchListArticles/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/SearchListArticles/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/SearchListArticles/.umirc.js b/SearchListArticles/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/SearchListArticles/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/SearchListArticles/README.md b/SearchListArticles/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f1e42db4cd4c994584ebf9f8ffcef9e4eb6999bb --- /dev/null +++ b/SearchListArticles/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/searchlistarticles + +SearchListArticles + +## Usage + +```sh +umi block add ant-design-pro/searchlistarticles +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/SearchListArticles/package.json b/SearchListArticles/package.json new file mode 100644 index 0000000000000000000000000000000000000000..0a4317f17e11288ffb244c508f2be05475ac7b7b --- /dev/null +++ b/SearchListArticles/package.json @@ -0,0 +1,28 @@ +{ + "name": "@umi-block/search-list-articles", + "version": "0.0.1", + "description": "SearchListArticles", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/searchlistarticles" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "classnames": "^2.2.6", + "dva": "^2.4.0", + "moment": "^2.22.2", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/SearchListArticles/snapshot.png b/SearchListArticles/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..cd74fb76a28e03ee2919dbd19425da9ebf1e8325 Binary files /dev/null and b/SearchListArticles/snapshot.png differ diff --git a/SearchListArticles/src/_mock.js b/SearchListArticles/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..c6903658fb8dfc249d8bb6f1abf8ad7a371ab41f --- /dev/null +++ b/SearchListArticles/src/_mock.js @@ -0,0 +1,107 @@ +const titles = [ + 'Alipay', + 'Angular', + 'Ant Design', + 'Ant Design Pro', + 'Bootstrap', + 'React', + 'Vue', + 'Webpack', +]; +const avatars = [ + 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png', // Alipay + 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png', // Angular + 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', // Ant Design + 'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', // Ant Design Pro + 'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png', // Bootstrap + 'https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png', // React + 'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png', // Vue + 'https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png', // Webpack +]; + +const covers = [ + 'https://gw.alipayobjects.com/zos/rmsportal/uMfMFlvUuceEyPpotzlq.png', + 'https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png', + 'https://gw.alipayobjects.com/zos/rmsportal/iXjVmWVHbCJAyqvDxdtx.png', + 'https://gw.alipayobjects.com/zos/rmsportal/gLaIAoVWTtLbBWZNYEMg.png', +]; +const desc = [ + '那是一种内在的东西, 他们到达不了,也无法触及的', + '希望是一个好东西,也许是最好的,好东西是不会消亡的', + '生命就像一盒巧克力,结果往往出人意料', + '城镇中有那么多的酒馆,她却偏偏走进了我的酒馆', + '那时候我只会想自己想要什么,从不想自己拥有什么', +]; +const user = [ + '付小小', + '曲丽丽', + '林东东', + '周星星', + '吴加好', + '朱偏右', + '鱼酱', + '乐哥', + '谭小仪', + '仲尼', +]; + +function fakeList(count) { + const list = []; + for (let i = 0; i < count; i += 1) { + list.push({ + id: `fake-list-${i}`, + owner: user[i % 10], + title: titles[i % 8], + avatar: avatars[i % 8], + cover: parseInt(i / 4, 10) % 2 === 0 ? covers[i % 4] : covers[3 - (i % 4)], + status: ['active', 'exception', 'normal'][i % 3], + percent: Math.ceil(Math.random() * 50) + 50, + logo: avatars[i % 8], + href: 'https://ant.design', + updatedAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i), + createdAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i), + subDescription: desc[i % 5], + description: + '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。', + activeUser: Math.ceil(Math.random() * 100000) + 100000, + newUser: Math.ceil(Math.random() * 1000) + 1000, + star: Math.ceil(Math.random() * 100) + 100, + like: Math.ceil(Math.random() * 100) + 100, + message: Math.ceil(Math.random() * 10) + 10, + content: + '段落示意:蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。', + members: [ + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png', + name: '曲丽丽', + id: 'member1', + }, + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png', + name: '王昭君', + id: 'member2', + }, + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png', + name: '董娜娜', + id: 'member3', + }, + ], + }); + } + + return list; +} + +function getFakeList(req, res) { + const params = req.query; + + const count = params.count * 1 || 20; + + const result = fakeList(count); + return res.json(result); +} + +export default { + 'GET /api/BLOCK_NAME/fake_list': getFakeList, +}; diff --git a/src/components/ArticleListContent/index.js b/SearchListArticles/src/components/ArticleListContent/index.js similarity index 100% rename from src/components/ArticleListContent/index.js rename to SearchListArticles/src/components/ArticleListContent/index.js diff --git a/src/components/ArticleListContent/index.less b/SearchListArticles/src/components/ArticleListContent/index.less similarity index 100% rename from src/components/ArticleListContent/index.less rename to SearchListArticles/src/components/ArticleListContent/index.less diff --git a/SearchListArticles/src/components/PageHeaderWrapper/index.js b/SearchListArticles/src/components/PageHeaderWrapper/index.js new file mode 100644 index 0000000000000000000000000000000000000000..c11873f2c8c24d44391261910d5adb52ab916d1a --- /dev/null +++ b/SearchListArticles/src/components/PageHeaderWrapper/index.js @@ -0,0 +1,25 @@ +import React from 'react'; +import { FormattedMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { PageHeader } from 'ant-design-pro'; +import styles from './index.less'; + +const PageHeaderWrapper = ({ children, wrapperClassName, ...restProps }) => ( + + } + key="pageheader" + {...restProps} + linkElement={Link} + itemRender={item => { + if (item.locale) { + return ; + } + return item.title; + }} + /> + {children ? {children} : null} + +); + +export default PageHeaderWrapper; diff --git a/SearchListArticles/src/components/PageHeaderWrapper/index.less b/SearchListArticles/src/components/PageHeaderWrapper/index.less new file mode 100644 index 0000000000000000000000000000000000000000..39a449657a98b039c29e6654fd117267cbb5283a --- /dev/null +++ b/SearchListArticles/src/components/PageHeaderWrapper/index.less @@ -0,0 +1,11 @@ +@import '~antd/lib/style/themes/default.less'; + +.content { + margin: 24px 24px 0; +} + +@media screen and (max-width: @screen-sm) { + .content { + margin: 24px 0 0; + } +} diff --git a/SearchListArticles/src/components/StandardFormRow/index.js b/SearchListArticles/src/components/StandardFormRow/index.js new file mode 100644 index 0000000000000000000000000000000000000000..8cb0e444e6d488ae4cdfeceb8eb94ee4adbb9248 --- /dev/null +++ b/SearchListArticles/src/components/StandardFormRow/index.js @@ -0,0 +1,24 @@ +import React from 'react'; +import classNames from 'classnames'; +import styles from './index.less'; + +const StandardFormRow = ({ title, children, last, block, grid, ...rest }) => { + const cls = classNames(styles.standardFormRow, { + [styles.standardFormRowBlock]: block, + [styles.standardFormRowLast]: last, + [styles.standardFormRowGrid]: grid, + }); + + return ( + + {title && ( + + {title} + + )} + {children} + + ); +}; + +export default StandardFormRow; diff --git a/SearchListArticles/src/components/StandardFormRow/index.less b/SearchListArticles/src/components/StandardFormRow/index.less new file mode 100644 index 0000000000000000000000000000000000000000..83ab019f43217c2ee53d037b24a327e92c4a00c2 --- /dev/null +++ b/SearchListArticles/src/components/StandardFormRow/index.less @@ -0,0 +1,72 @@ +@import '~antd/lib/style/themes/default.less'; + +.standardFormRow { + border-bottom: 1px dashed @border-color-split; + padding-bottom: 16px; + margin-bottom: 16px; + display: flex; + :global { + .ant-form-item { + margin-right: 24px; + } + .ant-form-item-label label { + color: @text-color; + margin-right: 0; + } + .ant-form-item-label, + .ant-form-item-control { + padding: 0; + line-height: 32px; + } + } + .label { + color: @heading-color; + font-size: @font-size-base; + margin-right: 24px; + flex: 0 0 auto; + text-align: right; + & > span { + display: inline-block; + height: 32px; + line-height: 32px; + &:after { + content: ':'; + } + } + } + .content { + flex: 1 1 0; + :global { + .ant-form-item:last-child { + margin-right: 0; + } + } + } +} + +.standardFormRowLast { + border: none; + padding-bottom: 0; + margin-bottom: 0; +} + +.standardFormRowBlock { + :global { + .ant-form-item, + div.ant-form-item-control-wrapper { + display: block; + } + } +} + +.standardFormRowGrid { + :global { + .ant-form-item, + div.ant-form-item-control-wrapper { + display: block; + } + .ant-form-item-label { + float: left; + } + } +} diff --git a/src/pages/List/Articles.js b/SearchListArticles/src/index.js similarity index 85% rename from src/pages/List/Articles.js rename to SearchListArticles/src/index.js index 5df46d5fc11f7d7ba0c67b7cdc40a901a24a1d34..69e4ae0b2bf143fce74dbd45dcb3db4ba6c23d98 100644 --- a/src/pages/List/Articles.js +++ b/SearchListArticles/src/index.js @@ -1,20 +1,21 @@ -import React, { Component, Fragment } from 'react'; +import React, { Component } from 'react'; import { connect } from 'dva'; -import { Form, Card, Select, List, Tag, Icon, Row, Col, Button } from 'antd'; +import { Form, Card, Select, List, Tag, Icon, Row, Col, Button, Input } from 'antd'; -import TagSelect from '@/components/TagSelect'; -import StandardFormRow from '@/components/StandardFormRow'; -import ArticleListContent from '@/components/ArticleListContent'; -import styles from './Articles.less'; +import TagSelect from 'ant-design-pro/lib/TagSelect'; +import StandardFormRow from './components/StandardFormRow'; +import ArticleListContent from './components/ArticleListContent'; +import PageHeaderWrapper from './components/PageHeaderWrapper'; +import styles from './style.less'; const { Option } = Select; const FormItem = Form.Item; const pageSize = 5; -@connect(({ list, loading }) => ({ - list, - loading: loading.models.list, +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ + BLOCK_NAME_CAMEL_CASE, + loading: loading.models.BLOCK_NAME_CAMEL_CASE, })) @Form.create({ onValuesChange({ dispatch }, changedValues, allValues) { @@ -23,7 +24,7 @@ const pageSize = 5; console.log(changedValues, allValues); // 模拟查询表单生效 dispatch({ - type: 'list/fetch', + type: 'BLOCK_NAME_CAMEL_CASE/fetch', payload: { count: 5, }, @@ -34,7 +35,7 @@ class SearchList extends Component { componentDidMount() { const { dispatch } = this.props; dispatch({ - type: 'list/fetch', + type: 'BLOCK_NAME_CAMEL_CASE/fetch', payload: { count: 5, }, @@ -51,7 +52,7 @@ class SearchList extends Component { fetchMore = () => { const { dispatch } = this.props; dispatch({ - type: 'list/appendFetch', + type: 'BLOCK_NAME_CAMEL_CASE/appendFetch', payload: { count: pageSize, }, @@ -61,7 +62,7 @@ class SearchList extends Component { render() { const { form, - list: { list }, + BLOCK_NAME_CAMEL_CASE: { list }, loading, } = this.props; const { getFieldDecorator } = form; @@ -119,8 +120,24 @@ class SearchList extends Component { ) : null; + const mainSearch = ( + + + + ); + return ( - + @@ -234,7 +251,7 @@ class SearchList extends Component { )} /> - + ); } } diff --git a/SearchListArticles/src/model.js b/SearchListArticles/src/model.js new file mode 100644 index 0000000000000000000000000000000000000000..c32dedec9fa8202b9afc824654377908020723e9 --- /dev/null +++ b/SearchListArticles/src/model.js @@ -0,0 +1,41 @@ +import { queryFakeList } from './service'; + +export default { + namespace: 'BLOCK_NAME_CAMEL_CASE', + + state: { + list: [], + }, + + effects: { + *fetch({ payload }, { call, put }) { + const response = yield call(queryFakeList, payload); + yield put({ + type: 'queryList', + payload: Array.isArray(response) ? response : [], + }); + }, + *appendFetch({ payload }, { call, put }) { + const response = yield call(queryFakeList, payload); + yield put({ + type: 'appendList', + payload: Array.isArray(response) ? response : [], + }); + }, + }, + + reducers: { + queryList(state, action) { + return { + ...state, + list: action.payload, + }; + }, + appendList(state, action) { + return { + ...state, + list: state.list.concat(action.payload), + }; + }, + }, +}; diff --git a/SearchListArticles/src/service.js b/SearchListArticles/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..f6d5bc70b96dc475843315338bd05e84667a7398 --- /dev/null +++ b/SearchListArticles/src/service.js @@ -0,0 +1,7 @@ +import request from 'umi-request'; + +export async function queryFakeList(params) { + return request(`/api/BLOCK_NAME/fake_list`, { + params, + }); +} diff --git a/src/pages/List/Articles.less b/SearchListArticles/src/style.less similarity index 100% rename from src/pages/List/Articles.less rename to SearchListArticles/src/style.less diff --git a/SearchListProjects/.gitignore b/SearchListProjects/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/SearchListProjects/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/SearchListProjects/.umirc.js b/SearchListProjects/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/SearchListProjects/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/SearchListProjects/README.md b/SearchListProjects/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f039a877f2eaf822aacb6656e2a9f88c38f744f3 --- /dev/null +++ b/SearchListProjects/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/searchlistprojects + +SearchListProjects + +## Usage + +```sh +umi block add ant-design-pro/searchlistprojects +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/SearchListProjects/package.json b/SearchListProjects/package.json new file mode 100644 index 0000000000000000000000000000000000000000..81d1f3e24f7937f17f37447844c7f909680a1731 --- /dev/null +++ b/SearchListProjects/package.json @@ -0,0 +1,28 @@ +{ + "name": "@umi-block/search-list-projects", + "version": "0.0.1", + "description": "SearchListProjects", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/searchlistprojects" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "classnames": "^2.2.6", + "dva": "^2.4.0", + "moment": "^2.22.2", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/SearchListProjects/snapshot.png b/SearchListProjects/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..82a96dc068318185d90fc313cc7f147f56213a97 Binary files /dev/null and b/SearchListProjects/snapshot.png differ diff --git a/SearchListProjects/src/_mock.js b/SearchListProjects/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..c6903658fb8dfc249d8bb6f1abf8ad7a371ab41f --- /dev/null +++ b/SearchListProjects/src/_mock.js @@ -0,0 +1,107 @@ +const titles = [ + 'Alipay', + 'Angular', + 'Ant Design', + 'Ant Design Pro', + 'Bootstrap', + 'React', + 'Vue', + 'Webpack', +]; +const avatars = [ + 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png', // Alipay + 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png', // Angular + 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', // Ant Design + 'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', // Ant Design Pro + 'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png', // Bootstrap + 'https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png', // React + 'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png', // Vue + 'https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png', // Webpack +]; + +const covers = [ + 'https://gw.alipayobjects.com/zos/rmsportal/uMfMFlvUuceEyPpotzlq.png', + 'https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png', + 'https://gw.alipayobjects.com/zos/rmsportal/iXjVmWVHbCJAyqvDxdtx.png', + 'https://gw.alipayobjects.com/zos/rmsportal/gLaIAoVWTtLbBWZNYEMg.png', +]; +const desc = [ + '那是一种内在的东西, 他们到达不了,也无法触及的', + '希望是一个好东西,也许是最好的,好东西是不会消亡的', + '生命就像一盒巧克力,结果往往出人意料', + '城镇中有那么多的酒馆,她却偏偏走进了我的酒馆', + '那时候我只会想自己想要什么,从不想自己拥有什么', +]; +const user = [ + '付小小', + '曲丽丽', + '林东东', + '周星星', + '吴加好', + '朱偏右', + '鱼酱', + '乐哥', + '谭小仪', + '仲尼', +]; + +function fakeList(count) { + const list = []; + for (let i = 0; i < count; i += 1) { + list.push({ + id: `fake-list-${i}`, + owner: user[i % 10], + title: titles[i % 8], + avatar: avatars[i % 8], + cover: parseInt(i / 4, 10) % 2 === 0 ? covers[i % 4] : covers[3 - (i % 4)], + status: ['active', 'exception', 'normal'][i % 3], + percent: Math.ceil(Math.random() * 50) + 50, + logo: avatars[i % 8], + href: 'https://ant.design', + updatedAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i), + createdAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i), + subDescription: desc[i % 5], + description: + '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。', + activeUser: Math.ceil(Math.random() * 100000) + 100000, + newUser: Math.ceil(Math.random() * 1000) + 1000, + star: Math.ceil(Math.random() * 100) + 100, + like: Math.ceil(Math.random() * 100) + 100, + message: Math.ceil(Math.random() * 10) + 10, + content: + '段落示意:蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。', + members: [ + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png', + name: '曲丽丽', + id: 'member1', + }, + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png', + name: '王昭君', + id: 'member2', + }, + { + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png', + name: '董娜娜', + id: 'member3', + }, + ], + }); + } + + return list; +} + +function getFakeList(req, res) { + const params = req.query; + + const count = params.count * 1 || 20; + + const result = fakeList(count); + return res.json(result); +} + +export default { + 'GET /api/BLOCK_NAME/fake_list': getFakeList, +}; diff --git a/SearchListProjects/src/components/PageHeaderWrapper/index.js b/SearchListProjects/src/components/PageHeaderWrapper/index.js new file mode 100644 index 0000000000000000000000000000000000000000..c11873f2c8c24d44391261910d5adb52ab916d1a --- /dev/null +++ b/SearchListProjects/src/components/PageHeaderWrapper/index.js @@ -0,0 +1,25 @@ +import React from 'react'; +import { FormattedMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { PageHeader } from 'ant-design-pro'; +import styles from './index.less'; + +const PageHeaderWrapper = ({ children, wrapperClassName, ...restProps }) => ( + + } + key="pageheader" + {...restProps} + linkElement={Link} + itemRender={item => { + if (item.locale) { + return ; + } + return item.title; + }} + /> + {children ? {children} : null} + +); + +export default PageHeaderWrapper; diff --git a/SearchListProjects/src/components/PageHeaderWrapper/index.less b/SearchListProjects/src/components/PageHeaderWrapper/index.less new file mode 100644 index 0000000000000000000000000000000000000000..39a449657a98b039c29e6654fd117267cbb5283a --- /dev/null +++ b/SearchListProjects/src/components/PageHeaderWrapper/index.less @@ -0,0 +1,11 @@ +@import '~antd/lib/style/themes/default.less'; + +.content { + margin: 24px 24px 0; +} + +@media screen and (max-width: @screen-sm) { + .content { + margin: 24px 0 0; + } +} diff --git a/SearchListProjects/src/components/StandardFormRow/index.js b/SearchListProjects/src/components/StandardFormRow/index.js new file mode 100644 index 0000000000000000000000000000000000000000..8cb0e444e6d488ae4cdfeceb8eb94ee4adbb9248 --- /dev/null +++ b/SearchListProjects/src/components/StandardFormRow/index.js @@ -0,0 +1,24 @@ +import React from 'react'; +import classNames from 'classnames'; +import styles from './index.less'; + +const StandardFormRow = ({ title, children, last, block, grid, ...rest }) => { + const cls = classNames(styles.standardFormRow, { + [styles.standardFormRowBlock]: block, + [styles.standardFormRowLast]: last, + [styles.standardFormRowGrid]: grid, + }); + + return ( + + {title && ( + + {title} + + )} + {children} + + ); +}; + +export default StandardFormRow; diff --git a/SearchListProjects/src/components/StandardFormRow/index.less b/SearchListProjects/src/components/StandardFormRow/index.less new file mode 100644 index 0000000000000000000000000000000000000000..83ab019f43217c2ee53d037b24a327e92c4a00c2 --- /dev/null +++ b/SearchListProjects/src/components/StandardFormRow/index.less @@ -0,0 +1,72 @@ +@import '~antd/lib/style/themes/default.less'; + +.standardFormRow { + border-bottom: 1px dashed @border-color-split; + padding-bottom: 16px; + margin-bottom: 16px; + display: flex; + :global { + .ant-form-item { + margin-right: 24px; + } + .ant-form-item-label label { + color: @text-color; + margin-right: 0; + } + .ant-form-item-label, + .ant-form-item-control { + padding: 0; + line-height: 32px; + } + } + .label { + color: @heading-color; + font-size: @font-size-base; + margin-right: 24px; + flex: 0 0 auto; + text-align: right; + & > span { + display: inline-block; + height: 32px; + line-height: 32px; + &:after { + content: ':'; + } + } + } + .content { + flex: 1 1 0; + :global { + .ant-form-item:last-child { + margin-right: 0; + } + } + } +} + +.standardFormRowLast { + border: none; + padding-bottom: 0; + margin-bottom: 0; +} + +.standardFormRowBlock { + :global { + .ant-form-item, + div.ant-form-item-control-wrapper { + display: block; + } + } +} + +.standardFormRowGrid { + :global { + .ant-form-item, + div.ant-form-item-control-wrapper { + display: block; + } + .ant-form-item-label { + float: left; + } + } +} diff --git a/SearchListProjects/src/index.js b/SearchListProjects/src/index.js new file mode 100644 index 0000000000000000000000000000000000000000..89d510bd07b090538d1cbc04f50ac260e5ca0572 --- /dev/null +++ b/SearchListProjects/src/index.js @@ -0,0 +1,170 @@ +import React, { PureComponent } from 'react'; +import moment from 'moment'; +import { connect } from 'dva'; +import { Row, Col, Form, Card, Select, List, Input } from 'antd'; + +import { TagSelect, AvatarList, Ellipsis } from 'ant-design-pro'; + +import StandardFormRow from './components/StandardFormRow'; +import PageHeaderWrapper from './components/PageHeaderWrapper'; +import styles from './style.less'; + +const { Option } = Select; +const FormItem = Form.Item; + +/* eslint react/no-array-index-key: 0 */ + +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ + BLOCK_NAME_CAMEL_CASE, + loading: loading.models.BLOCK_NAME_CAMEL_CASE, +})) +@Form.create({ + onValuesChange({ dispatch }, changedValues, allValues) { + // 表单项变化时请求数据 + // eslint-disable-next-line + console.log(changedValues, allValues); + // 模拟查询表单生效 + dispatch({ + type: 'BLOCK_NAME_CAMEL_CASE/fetch', + payload: { + count: 8, + }, + }); + }, +}) +class CoverCardList extends PureComponent { + componentDidMount() { + const { dispatch } = this.props; + dispatch({ + type: 'BLOCK_NAME_CAMEL_CASE/fetch', + payload: { + count: 8, + }, + }); + } + + render() { + const { + BLOCK_NAME_CAMEL_CASE: { list = [] }, + loading, + form, + } = this.props; + const { getFieldDecorator } = form; + + const cardList = list ? ( + ( + + } + > + {item.title}} + description={{item.subDescription}} + /> + + {moment(item.updatedAt).fromNow()} + + + {item.members.map((member, i) => ( + + ))} + + + + + + )} + /> + ) : null; + + const formItemLayout = { + wrapperCol: { + xs: { span: 24 }, + sm: { span: 16 }, + }, + }; + const mainSearch = ( + + + + ); + + return ( + + + + + + + {getFieldDecorator('category')( + + 类目一 + 类目二 + 类目三 + 类目四 + 类目五 + 类目六 + 类目七 + 类目八 + 类目九 + 类目十 + 类目十一 + 类目十二 + + )} + + + + + + + {getFieldDecorator('author', {})( + + 王昭君 + + )} + + + + + {getFieldDecorator('rate', {})( + + 优秀 + 普通 + + )} + + + + + + + {cardList} + + + ); + } +} + +export default CoverCardList; diff --git a/SearchListProjects/src/model.js b/SearchListProjects/src/model.js new file mode 100644 index 0000000000000000000000000000000000000000..ead65a8df48a91a8b103af60429206eb865c7230 --- /dev/null +++ b/SearchListProjects/src/model.js @@ -0,0 +1,28 @@ +import { queryFakeList } from './service'; + +export default { + namespace: 'BLOCK_NAME_CAMEL_CASE', + + state: { + list: [], + }, + + effects: { + *fetch({ payload }, { call, put }) { + const response = yield call(queryFakeList, payload); + yield put({ + type: 'queryList', + payload: Array.isArray(response) ? response : [], + }); + }, + }, + + reducers: { + queryList(state, action) { + return { + ...state, + list: action.payload, + }; + }, + }, +}; diff --git a/SearchListProjects/src/service.js b/SearchListProjects/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..f6d5bc70b96dc475843315338bd05e84667a7398 --- /dev/null +++ b/SearchListProjects/src/service.js @@ -0,0 +1,7 @@ +import request from 'umi-request'; + +export async function queryFakeList(params) { + return request(`/api/BLOCK_NAME/fake_list`, { + params, + }); +} diff --git a/src/pages/List/Projects.less b/SearchListProjects/src/style.less similarity index 96% rename from src/pages/List/Projects.less rename to SearchListProjects/src/style.less index 43b8d72655bafe27dbd31ad33c93e9b934289f17..adad803742df291977197246b7a7e9e0b9bfa729 100644 --- a/src/pages/List/Projects.less +++ b/SearchListProjects/src/style.less @@ -1,5 +1,5 @@ @import '~antd/lib/style/themes/default.less'; -@import '~@/utils/utils.less'; +@import './utils/utils.less'; .coverCardList { margin-bottom: -24px; diff --git a/SearchListProjects/src/utils/utils.less b/SearchListProjects/src/utils/utils.less new file mode 100644 index 0000000000000000000000000000000000000000..725792252787f49efba4f4e887301195a9818f3f --- /dev/null +++ b/SearchListProjects/src/utils/utils.less @@ -0,0 +1,50 @@ +.textOverflow() { + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + white-space: nowrap; +} + +.textOverflowMulti(@line: 3, @bg: #fff) { + overflow: hidden; + position: relative; + line-height: 1.5em; + max-height: @line * 1.5em; + text-align: justify; + margin-right: -1em; + padding-right: 1em; + &:before { + background: @bg; + content: '...'; + padding: 0 1px; + position: absolute; + right: 14px; + bottom: 0; + } + &:after { + background: white; + content: ''; + margin-top: 0.2em; + position: absolute; + right: 14px; + width: 1em; + height: 1em; + } +} + +// mixins for clearfix +// ------------------------ +.clearfix() { + zoom: 1; + &:before, + &:after { + content: ' '; + display: table; + } + &:after { + clear: both; + visibility: hidden; + font-size: 0; + height: 0; + } +} diff --git a/StepForm/.gitignore b/StepForm/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/StepForm/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/StepForm/.umirc.js b/StepForm/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/StepForm/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/StepForm/README.md b/StepForm/README.md new file mode 100644 index 0000000000000000000000000000000000000000..bf3260edece33c77ff905a267fa6e46eed728938 --- /dev/null +++ b/StepForm/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/stepform + +StepForm + +## Usage + +```sh +umi block add ant-design-pro/stepform +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/StepForm/package.json b/StepForm/package.json new file mode 100644 index 0000000000000000000000000000000000000000..ad8ce32393ec58ffb1d6269bfcefa226e609e1da --- /dev/null +++ b/StepForm/package.json @@ -0,0 +1,27 @@ +{ + "name": "@umi-block/step-form", + "version": "0.0.1", + "description": "StepForm", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/stepform" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "dva": "^2.4.0", + "react": "^16.6.3", + "umi-request": "^1.0.0", + "nzh": "^1.0.3" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/StepForm/snapshot.png b/StepForm/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..653be0e67ef1f9b82d2d7522069f8ee4818d548e Binary files /dev/null and b/StepForm/snapshot.png differ diff --git a/StepForm/src/_mock.js b/StepForm/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..8e7996deae35737ca576735528af9f6eaa281b98 --- /dev/null +++ b/StepForm/src/_mock.js @@ -0,0 +1,5 @@ +export default { + 'POST /api/BLOCK_NAME/forms': (req, res) => { + res.send({ message: 'Ok' }); + }, +}; diff --git a/StepForm/src/components/PageHeaderWrapper/index.js b/StepForm/src/components/PageHeaderWrapper/index.js new file mode 100644 index 0000000000000000000000000000000000000000..c11873f2c8c24d44391261910d5adb52ab916d1a --- /dev/null +++ b/StepForm/src/components/PageHeaderWrapper/index.js @@ -0,0 +1,25 @@ +import React from 'react'; +import { FormattedMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { PageHeader } from 'ant-design-pro'; +import styles from './index.less'; + +const PageHeaderWrapper = ({ children, wrapperClassName, ...restProps }) => ( + + } + key="pageheader" + {...restProps} + linkElement={Link} + itemRender={item => { + if (item.locale) { + return ; + } + return item.title; + }} + /> + {children ? {children} : null} + +); + +export default PageHeaderWrapper; diff --git a/StepForm/src/components/PageHeaderWrapper/index.less b/StepForm/src/components/PageHeaderWrapper/index.less new file mode 100644 index 0000000000000000000000000000000000000000..39a449657a98b039c29e6654fd117267cbb5283a --- /dev/null +++ b/StepForm/src/components/PageHeaderWrapper/index.less @@ -0,0 +1,11 @@ +@import '~antd/lib/style/themes/default.less'; + +.content { + margin: 24px 24px 0; +} + +@media screen and (max-width: @screen-sm) { + .content { + margin: 24px 0 0; + } +} diff --git a/src/pages/Forms/StepForm/Step1.js b/StepForm/src/components/Step1/index.js similarity index 92% rename from src/pages/Forms/StepForm/Step1.js rename to StepForm/src/components/Step1/index.js index a62e294192b1cfcc74ef3ee5f817d005d05f22a2..8476d220f14ec4e776be4cf60e1de2dd716336cc 100644 --- a/src/pages/Forms/StepForm/Step1.js +++ b/StepForm/src/components/Step1/index.js @@ -1,8 +1,7 @@ import React, { Fragment } from 'react'; import { connect } from 'dva'; import { Form, Input, Button, Select, Divider } from 'antd'; -import router from 'umi/router'; -import styles from './style.less'; +import styles from './index.less'; const { Option } = Select; @@ -15,8 +14,8 @@ const formItemLayout = { }, }; -@connect(({ form }) => ({ - data: form.step, +@connect(({ BLOCK_NAME_CAMEL_CASE }) => ({ + data: BLOCK_NAME_CAMEL_CASE.step, })) @Form.create() class Step1 extends React.PureComponent { @@ -27,10 +26,13 @@ class Step1 extends React.PureComponent { validateFields((err, values) => { if (!err) { dispatch({ - type: 'form/saveStepFormData', + type: 'BLOCK_NAME_CAMEL_CASE/saveStepFormData', payload: values, }); - router.push('/form/step-form/confirm'); + dispatch({ + type: 'BLOCK_NAME_CAMEL_CASE/saveCurrentStep', + payload: 'confirm', + }); } }); }; diff --git a/src/pages/Forms/StepForm/style.less b/StepForm/src/components/Step1/index.less similarity index 100% rename from src/pages/Forms/StepForm/style.less rename to StepForm/src/components/Step1/index.less diff --git a/src/pages/Forms/StepForm/Step2.js b/StepForm/src/components/Step2/index.js similarity index 86% rename from src/pages/Forms/StepForm/Step2.js rename to StepForm/src/components/Step2/index.js index 3e3b05bf2fe769c3994829ffff059844cb0f7146..5c1ca6c4ac757d9ccea0654f86e14aa4e7508740 100644 --- a/src/pages/Forms/StepForm/Step2.js +++ b/StepForm/src/components/Step2/index.js @@ -1,9 +1,8 @@ import React from 'react'; import { connect } from 'dva'; import { Form, Input, Button, Alert, Divider } from 'antd'; -import router from 'umi/router'; -import { digitUppercase } from '@/utils/utils'; -import styles from './style.less'; +import { digitUppercase } from '../../utils/utils'; +import styles from './index.less'; const formItemLayout = { labelCol: { @@ -14,9 +13,9 @@ const formItemLayout = { }, }; -@connect(({ form, loading }) => ({ - submitting: loading.effects['form/submitStepForm'], - data: form.step, +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ + submitting: loading.effects['BLOCK_NAME_CAMEL_CASE/submitStepForm'], + data: BLOCK_NAME_CAMEL_CASE.step, })) @Form.create() class Step2 extends React.PureComponent { @@ -24,14 +23,17 @@ class Step2 extends React.PureComponent { const { form, data, dispatch, submitting } = this.props; const { getFieldDecorator, validateFields } = form; const onPrev = () => { - router.push('/form/step-form/info'); + dispatch({ + type: 'BLOCK_NAME_CAMEL_CASE/saveCurrentStep', + payload: 'info', + }); }; const onValidateForm = e => { e.preventDefault(); validateFields((err, values) => { if (!err) { dispatch({ - type: 'form/submitStepForm', + type: 'BLOCK_NAME_CAMEL_CASE/submitStepForm', payload: { ...data, ...values, diff --git a/StepForm/src/components/Step2/index.less b/StepForm/src/components/Step2/index.less new file mode 100644 index 0000000000000000000000000000000000000000..713dd54c5ba3fbc58f50f77cffbedd2b30a361c9 --- /dev/null +++ b/StepForm/src/components/Step2/index.less @@ -0,0 +1,78 @@ +@import '~antd/lib/style/themes/default.less'; + +.stepForm { + margin: 40px auto 0; + max-width: 500px; +} + +.stepFormText { + margin-bottom: 24px; + :global { + .ant-form-item-label, + .ant-form-item-control { + line-height: 22px; + } + } +} + +.result { + margin: 0 auto; + max-width: 560px; + padding: 24px 0 8px; +} + +.desc { + padding: 0 56px; + color: @text-color-secondary; + h3 { + font-size: 16px; + margin: 0 0 12px 0; + color: @text-color-secondary; + line-height: 32px; + } + h4 { + margin: 0 0 4px 0; + color: @text-color-secondary; + font-size: 14px; + line-height: 22px; + } + p { + margin-top: 0; + margin-bottom: 12px; + line-height: 22px; + } +} + +@media screen and (max-width: @screen-md) { + .desc { + padding: 0; + } +} + +.information { + line-height: 22px; + :global { + .ant-row:not(:last-child) { + margin-bottom: 24px; + } + } + .label { + color: @heading-color; + text-align: right; + padding-right: 8px; + @media screen and (max-width: @screen-sm) { + text-align: left; + } + } +} + +.money { + font-family: 'Helvetica Neue', sans-serif; + font-weight: 500; + font-size: 20px; + line-height: 14px; +} + +.uppercase { + font-size: 12px; +} diff --git a/src/pages/Forms/StepForm/Step3.js b/StepForm/src/components/Step3/index.js similarity index 84% rename from src/pages/Forms/StepForm/Step3.js rename to StepForm/src/components/Step3/index.js index 74e1a6b8add060d063a141f905976c80effbb2ab..d1570665f7dd6670971d65fd8c490e8f4e54d303 100644 --- a/src/pages/Forms/StepForm/Step3.js +++ b/StepForm/src/components/Step3/index.js @@ -1,18 +1,20 @@ import React, { Fragment } from 'react'; import { connect } from 'dva'; import { Button, Row, Col } from 'antd'; -import router from 'umi/router'; -import Result from '@/components/Result'; -import styles from './style.less'; +import { Result } from 'ant-design-pro'; +import styles from './index.less'; -@connect(({ form }) => ({ - data: form.step, +@connect(({ BLOCK_NAME_CAMEL_CASE }) => ({ + data: BLOCK_NAME_CAMEL_CASE.step, })) class Step3 extends React.PureComponent { render() { - const { data } = this.props; + const { data, dispatch } = this.props; const onFinish = () => { - router.push('/form/step-form/info'); + dispatch({ + type: 'BLOCK_NAME_CAMEL_CASE/saveCurrentStep', + payload: 'info', + }); }; const information = ( diff --git a/StepForm/src/components/Step3/index.less b/StepForm/src/components/Step3/index.less new file mode 100644 index 0000000000000000000000000000000000000000..713dd54c5ba3fbc58f50f77cffbedd2b30a361c9 --- /dev/null +++ b/StepForm/src/components/Step3/index.less @@ -0,0 +1,78 @@ +@import '~antd/lib/style/themes/default.less'; + +.stepForm { + margin: 40px auto 0; + max-width: 500px; +} + +.stepFormText { + margin-bottom: 24px; + :global { + .ant-form-item-label, + .ant-form-item-control { + line-height: 22px; + } + } +} + +.result { + margin: 0 auto; + max-width: 560px; + padding: 24px 0 8px; +} + +.desc { + padding: 0 56px; + color: @text-color-secondary; + h3 { + font-size: 16px; + margin: 0 0 12px 0; + color: @text-color-secondary; + line-height: 32px; + } + h4 { + margin: 0 0 4px 0; + color: @text-color-secondary; + font-size: 14px; + line-height: 22px; + } + p { + margin-top: 0; + margin-bottom: 12px; + line-height: 22px; + } +} + +@media screen and (max-width: @screen-md) { + .desc { + padding: 0; + } +} + +.information { + line-height: 22px; + :global { + .ant-row:not(:last-child) { + margin-bottom: 24px; + } + } + .label { + color: @heading-color; + text-align: right; + padding-right: 8px; + @media screen and (max-width: @screen-sm) { + text-align: left; + } + } +} + +.money { + font-family: 'Helvetica Neue', sans-serif; + font-weight: 500; + font-size: 20px; + line-height: 14px; +} + +.uppercase { + font-size: 12px; +} diff --git a/StepForm/src/index.js b/StepForm/src/index.js new file mode 100644 index 0000000000000000000000000000000000000000..7ac32b27f8b354837cf23915b0019fc42eb630c0 --- /dev/null +++ b/StepForm/src/index.js @@ -0,0 +1,60 @@ +import React, { PureComponent, Fragment } from 'react'; +import { Card, Steps } from 'antd'; +import { connect } from 'dva'; +import PageHeaderWrapper from './components/PageHeaderWrapper'; +import Step1 from './components/Step1'; +import Step2 from './components/Step2'; +import Step3 from './components/Step3'; +import styles from './style.less'; + +const { Step } = Steps; + +@connect(({ BLOCK_NAME_CAMEL_CASE }) => ({ + current: BLOCK_NAME_CAMEL_CASE.current, +})) +class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { + getCurrentStep() { + const { current } = this.props; + switch (current) { + case 'info': + return 0; + case 'confirm': + return 1; + case 'result': + return 2; + default: + return 0; + } + } + + render() { + const currentStep = this.getCurrentStep(); + let stepComponent; + if (currentStep === 1) { + stepComponent = ; + } else if (currentStep === 2) { + stepComponent = ; + } else { + stepComponent = ; + } + return ( + + + + + + + + + {stepComponent} + + + + ); + } +} + +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/StepForm/src/locales/en-US.js b/StepForm/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..3356dda0f90eaa80e52b8bc4bd9002f62d9d4bc8 --- /dev/null +++ b/StepForm/src/locales/en-US.js @@ -0,0 +1,61 @@ +export default { + 'BLOCK_NAME.basic.title': 'Basic form', + 'BLOCK_NAME.basic.description': + 'Form pages are used to collect or verify information to users, and basic forms are common in scenarios where there are fewer data items.', + + 'BLOCK_NAME.email.required': 'Please enter your email!', + 'BLOCK_NAME.email.wrong-format': 'The email address is in the wrong format!', + 'BLOCK_NAME.userName.required': 'Please enter your userName!', + 'BLOCK_NAME.password.required': 'Please enter your password!', + 'BLOCK_NAME.password.twice': 'The passwords entered twice do not match!', + 'BLOCK_NAME.strength.msg': + "Please enter at least 6 characters and don't use passwords that are easy to guess.", + 'BLOCK_NAME.strength.strong': 'Strength: strong', + 'BLOCK_NAME.strength.medium': 'Strength: medium', + 'BLOCK_NAME.strength.short': 'Strength: too short', + 'BLOCK_NAME.confirm-password.required': 'Please confirm your password!', + 'BLOCK_NAME.phone-number.required': 'Please enter your phone number!', + 'BLOCK_NAME.phone-number.wrong-format': 'Malformed phone number!', + 'BLOCK_NAME.verification-code.required': 'Please enter the verification code!', + 'BLOCK_NAME.title.required': 'Please enter a title', + 'BLOCK_NAME.date.required': 'Please select the start and end date', + 'BLOCK_NAME.goal.required': 'Please enter a description of the goal', + 'BLOCK_NAME.standard.required': 'Please enter a metric', + + 'BLOCK_NAME.form.get-captcha': 'Get Captcha', + 'BLOCK_NAME.captcha.second': 'sec', + 'BLOCK_NAME.form.optional': ' (optional) ', + 'BLOCK_NAME.form.submit': 'Submit', + 'BLOCK_NAME.form.save': 'Save', + 'BLOCK_NAME.email.placeholder': 'Email', + 'BLOCK_NAME.password.placeholder': 'Password', + 'BLOCK_NAME.confirm-password.placeholder': 'Confirm password', + 'BLOCK_NAME.phone-number.placeholder': 'Phone number', + 'BLOCK_NAME.verification-code.placeholder': 'Verification code', + 'BLOCK_NAME.title.label': 'Title', + 'BLOCK_NAME.title.placeholder': 'Give the target a name', + 'BLOCK_NAME.date.label': 'Start and end date', + 'BLOCK_NAME.placeholder.start': 'Start date', + 'BLOCK_NAME.placeholder.end': 'End date', + 'BLOCK_NAME.goal.label': 'Goal description', + 'BLOCK_NAME.goal.placeholder': 'Please enter your work goals', + 'BLOCK_NAME.standard.label': 'Metrics', + 'BLOCK_NAME.standard.placeholder': 'Please enter a metric', + 'BLOCK_NAME.client.label': 'Client', + 'BLOCK_NAME.label.tooltip': 'Target service object', + 'BLOCK_NAME.client.placeholder': + 'Please describe your customer service, internal customers directly @ Name / job number', + 'BLOCK_NAME.invites.label': 'Inviting critics', + 'BLOCK_NAME.invites.placeholder': 'Please direct @ Name / job number, you can invite up to 5 people', + 'BLOCK_NAME.weight.label': 'Weight', + 'BLOCK_NAME.weight.placeholder': 'Please enter weight', + 'BLOCK_NAME.public.label': 'Target disclosure', + 'BLOCK_NAME.label.help': 'Customers and invitees are shared by default', + 'BLOCK_NAME.radio.public': 'Public', + 'BLOCK_NAME.radio.partially-public': 'Partially public', + 'BLOCK_NAME.radio.private': 'Private', + 'BLOCK_NAME.publicUsers.placeholder': 'Open to', + 'BLOCK_NAME.option.A': 'Colleague A', + 'BLOCK_NAME.option.B': 'Colleague B', + 'BLOCK_NAME.option.C': 'Colleague C', +}; diff --git a/StepForm/src/locales/pt-BR.js b/StepForm/src/locales/pt-BR.js new file mode 100644 index 0000000000000000000000000000000000000000..1cc9013111adbea37ac80892f11b28d487566f72 --- /dev/null +++ b/StepForm/src/locales/pt-BR.js @@ -0,0 +1,57 @@ +export default { + 'BLOCK_NAME.basic.title': 'Basic form', + 'BLOCK_NAME.basic.description': + 'Form pages are used to collect or verify information to users, and basic forms are common in scenarios where there are fewer data items.', + + 'BLOCK_NAME.email.required': 'Por favor insira seu email!', + 'BLOCK_NAME.email.wrong-format': 'O email está errado!', + 'BLOCK_NAME.userName.required': 'Por favor insira nome de usuário!', + 'BLOCK_NAME.password.required': 'Por favor insira sua senha!', + 'BLOCK_NAME.password.twice': 'As senhas não estão iguais!', + 'BLOCK_NAME.strength.msg': + 'Por favor insira pelo menos 6 caracteres e não use senhas fáceis de adivinhar.', + 'BLOCK_NAME.strength.strong': 'Força: forte', + 'BLOCK_NAME.strength.medium': 'Força: média', + 'BLOCK_NAME.strength.short': 'Força: curta', + 'BLOCK_NAME.confirm-password.required': 'Por favor confirme sua senha!', + 'BLOCK_NAME.phone-number.required': 'Por favor insira seu telefone!', + 'BLOCK_NAME.phone-number.wrong-format': 'Formato de telefone errado!', + 'BLOCK_NAME.verification-code.required': 'Por favor insira seu código de verificação!', + + 'BLOCK_NAME.form.get-captcha': 'Get Captcha', + 'BLOCK_NAME.captcha.second': 'sec', + 'BLOCK_NAME.email.placeholder': 'Email', + 'BLOCK_NAME.password.placeholder': 'Senha', + 'BLOCK_NAME.confirm-password.placeholder': 'Confirme a senha', + 'BLOCK_NAME.phone-number.placeholder': 'Telefone', + 'BLOCK_NAME.verification-code.placeholder': 'Código de verificação', + 'BLOCK_NAME.form.optional': ' (optional) ', + 'BLOCK_NAME.form.submit': 'Submit', + 'BLOCK_NAME.form.save': 'Save', + 'BLOCK_NAME.title.label': 'Title', + 'BLOCK_NAME.title.placeholder': 'Give the target a name', + 'BLOCK_NAME.date.label': 'Start and end date', + 'BLOCK_NAME.placeholder.start': 'Start date', + 'BLOCK_NAME.placeholder.end': 'End date', + 'BLOCK_NAME.goal.label': 'Goal description', + 'BLOCK_NAME.goal.placeholder': 'Please enter your work goals', + 'BLOCK_NAME.standard.label': 'Metrics', + 'BLOCK_NAME.standard.placeholder': 'Please enter a metric', + 'BLOCK_NAME.client.label': 'Client', + 'BLOCK_NAME.label.tooltip': 'Target service object', + 'BLOCK_NAME.client.placeholder': + 'Please describe your customer service, internal customers directly @ Name / job number', + 'BLOCK_NAME.invites.label': 'Inviting critics', + 'BLOCK_NAME.invites.placeholder': 'Please direct @ Name / job number, you can invite up to 5 people', + 'BLOCK_NAME.weight.label': 'Weight', + 'BLOCK_NAME.weight.placeholder': 'Please enter weight', + 'BLOCK_NAME.public.label': 'Target disclosure', + 'BLOCK_NAME.label.help': 'Customers and invitees are shared by default', + 'BLOCK_NAME.radio.public': 'Public', + 'BLOCK_NAME.radio.partially-public': 'Partially public', + 'BLOCK_NAME.radio.private': 'Private', + 'BLOCK_NAME.publicUsers.placeholder': 'Open to', + 'BLOCK_NAME.option.A': 'Colleague A', + 'BLOCK_NAME.option.B': 'Colleague B', + 'BLOCK_NAME.option.C': 'Colleague C', +}; diff --git a/StepForm/src/locales/zh-CN.js b/StepForm/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..d9a4b1deb9b5d6f5aa748d6a7aa85ee087cbd416 --- /dev/null +++ b/StepForm/src/locales/zh-CN.js @@ -0,0 +1,59 @@ +export default { + 'BLOCK_NAME.basic.title': '基础表单', + 'BLOCK_NAME.basic.description': + '表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。', + + 'BLOCK_NAME.email.required': '请输入邮箱地址!', + 'BLOCK_NAME.email.wrong-format': '邮箱地址格式错误!', + 'BLOCK_NAME.userName.required': '请输入用户名!', + 'BLOCK_NAME.password.required': '请输入密码!', + 'BLOCK_NAME.password.twice': '两次输入的密码不匹配!', + 'BLOCK_NAME.strength.msg': '请至少输入 6 个字符。请不要使用容易被猜到的密码。', + 'BLOCK_NAME.strength.strong': '强度:强', + 'BLOCK_NAME.strength.medium': '强度:中', + 'BLOCK_NAME.strength.short': '强度:太短', + 'BLOCK_NAME.confirm-password.required': '请确认密码!', + 'BLOCK_NAME.phone-number.required': '请输入手机号!', + 'BLOCK_NAME.phone-number.wrong-format': '手机号格式错误!', + 'BLOCK_NAME.verification-code.required': '请输入验证码!', + 'BLOCK_NAME.title.required': '请输入标题', + 'BLOCK_NAME.date.required': '请选择起止日期', + 'BLOCK_NAME.goal.required': '请输入目标描述', + 'BLOCK_NAME.standard.required': '请输入衡量标准', + + 'BLOCK_NAME.form.get-captcha': '获取验证码', + 'BLOCK_NAME.captcha.second': '秒', + 'BLOCK_NAME.form.optional': '(选填)', + 'BLOCK_NAME.form.submit': '提交', + 'BLOCK_NAME.form.save': '保存', + 'BLOCK_NAME.email.placeholder': '邮箱', + 'BLOCK_NAME.password.placeholder': '至少6位密码,区分大小写', + 'BLOCK_NAME.confirm-password.placeholder': '确认密码', + 'BLOCK_NAME.phone-number.placeholder': '手机号', + 'BLOCK_NAME.verification-code.placeholder': '验证码', + 'BLOCK_NAME.title.label': '标题', + 'BLOCK_NAME.title.placeholder': '给目标起个名字', + 'BLOCK_NAME.date.label': '起止日期', + 'BLOCK_NAME.placeholder.start': '开始日期', + 'BLOCK_NAME.placeholder.end': '结束日期', + 'BLOCK_NAME.goal.label': '目标描述', + 'BLOCK_NAME.goal.placeholder': '请输入你的阶段性工作目标', + 'BLOCK_NAME.standard.label': '衡量标准', + 'BLOCK_NAME.standard.placeholder': '请输入衡量标准', + 'BLOCK_NAME.client.label': '客户', + 'BLOCK_NAME.label.tooltip': '目标的服务对象', + 'BLOCK_NAME.client.placeholder': '请描述你服务的客户,内部客户直接 @姓名/工号', + 'BLOCK_NAME.invites.label': '邀评人', + 'BLOCK_NAME.invites.placeholder': '请直接 @姓名/工号,最多可邀请 5 人', + 'BLOCK_NAME.weight.label': '权重', + 'BLOCK_NAME.weight.placeholder': '请输入', + 'BLOCK_NAME.public.label': '目标公开', + 'BLOCK_NAME.label.help': '客户、邀评人默认被分享', + 'BLOCK_NAME.radio.public': '公开', + 'BLOCK_NAME.radio.partially-public': '部分公开', + 'BLOCK_NAME.radio.private': '不公开', + 'BLOCK_NAME.publicUsers.placeholder': '公开给', + 'BLOCK_NAME.option.A': '同事甲', + 'BLOCK_NAME.option.B': '同事乙', + 'BLOCK_NAME.option.C': '同事丙', +}; diff --git a/StepForm/src/locales/zh-TW.js b/StepForm/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..d42f8520ecb62730bdca8f6aa83ec32982c05932 --- /dev/null +++ b/StepForm/src/locales/zh-TW.js @@ -0,0 +1,59 @@ +export default { + 'BLOCK_NAME.basic.title': '基礎表單', + 'BLOCK_NAME.basic.description': + '表單頁用於向用戶收集或驗證信息,基礎表單常見於數據項較少的表單場景。', + + 'BLOCK_NAME.email.required': '請輸入郵箱地址!', + 'BLOCK_NAME.email.wrong-format': '郵箱地址格式錯誤!', + 'BLOCK_NAME.userName.required': '請輸入賬戶!', + 'BLOCK_NAME.password.required': '請輸入密碼!', + 'BLOCK_NAME.password.twice': '兩次輸入的密碼不匹配!', + 'BLOCK_NAME.strength.msg': '請至少輸入 6 個字符。請不要使用容易被猜到的密碼。', + 'BLOCK_NAME.strength.strong': '強度:強', + 'BLOCK_NAME.strength.medium': '強度:中', + 'BLOCK_NAME.strength.short': '強度:太短', + 'BLOCK_NAME.confirm-password.required': '請確認密碼!', + 'BLOCK_NAME.phone-number.required': '請輸入手機號!', + 'BLOCK_NAME.phone-number.wrong-format': '手機號格式錯誤!', + 'BLOCK_NAME.verification-code.required': '請輸入驗證碼!', + 'BLOCK_NAME.title.required': '請輸入標題', + 'BLOCK_NAME.date.required': '請選擇起止日期', + 'BLOCK_NAME.goal.required': '請輸入目標描述', + 'BLOCK_NAME.standard.required': '請輸入衡量標淮', + + 'BLOCK_NAME.form.get-captcha': '獲取驗證碼', + 'BLOCK_NAME.captcha.second': '秒', + 'BLOCK_NAME.form.optional': '(選填)', + 'BLOCK_NAME.form.submit': '提交', + 'BLOCK_NAME.form.save': '保存', + 'BLOCK_NAME.email.placeholder': '郵箱', + 'BLOCK_NAME.password.placeholder': '至少6位密碼,區分大小寫', + 'BLOCK_NAME.confirm-password.placeholder': '確認密碼', + 'BLOCK_NAME.phone-number.placeholder': '手機號', + 'BLOCK_NAME.verification-code.placeholder': '驗證碼', + 'BLOCK_NAME.title.label': '標題', + 'BLOCK_NAME.title.placeholder': '給目標起個名字', + 'BLOCK_NAME.date.label': '起止日期', + 'BLOCK_NAME.placeholder.start': '開始日期', + 'BLOCK_NAME.placeholder.end': '結束日期', + 'BLOCK_NAME.goal.label': '目標描述', + 'BLOCK_NAME.goal.placeholder': '請輸入妳的階段性工作目標', + 'BLOCK_NAME.standard.label': '衡量標淮', + 'BLOCK_NAME.standard.placeholder': '請輸入衡量標淮', + 'BLOCK_NAME.client.label': '客戶', + 'BLOCK_NAME.label.tooltip': '目標的服務對象', + 'BLOCK_NAME.client.placeholder': '請描述妳服務的客戶,內部客戶直接 @姓名/工號', + 'BLOCK_NAME.invites.label': '邀評人', + 'BLOCK_NAME.invites.placeholder': '請直接 @姓名/工號,最多可邀請 5 人', + 'BLOCK_NAME.weight.label': '權重', + 'BLOCK_NAME.weight.placeholder': '請輸入', + 'BLOCK_NAME.public.label': '目標公開', + 'BLOCK_NAME.label.help': '客戶、邀評人默認被分享', + 'BLOCK_NAME.radio.public': '公開', + 'BLOCK_NAME.radio.partially-public': '部分公開', + 'BLOCK_NAME.radio.private': '不公開', + 'BLOCK_NAME.publicUsers.placeholder': '公開給', + 'BLOCK_NAME.option.A': '同事甲', + 'BLOCK_NAME.option.B': '同事乙', + 'BLOCK_NAME.option.C': '同事丙', +}; diff --git a/src/pages/Forms/models/form.js b/StepForm/src/model.js similarity index 55% rename from src/pages/Forms/models/form.js rename to StepForm/src/model.js index 0b241b133d5fb8c0147f8bf81f8400df1a97ffd7..36a6aae2e0e9e288c5db881d9b7a23c37ac258e4 100644 --- a/src/pages/Forms/models/form.js +++ b/StepForm/src/model.js @@ -1,11 +1,10 @@ -import { routerRedux } from 'dva/router'; -import { message } from 'antd'; -import { fakeSubmitForm } from '@/services/api'; +import { fakeSubmitForm } from './service'; export default { - namespace: 'form', + namespace: 'BLOCK_NAME_CAMEL_CASE', state: { + current: 'info', step: { payAccount: 'ant-design@alipay.com', receiverAccount: 'test@example.com', @@ -15,25 +14,27 @@ export default { }, effects: { - *submitRegularForm({ payload }, { call }) { - yield call(fakeSubmitForm, payload); - message.success('提交成功'); - }, *submitStepForm({ payload }, { call, put }) { yield call(fakeSubmitForm, payload); yield put({ type: 'saveStepFormData', payload, }); - yield put(routerRedux.push('/form/step-form/result')); - }, - *submitAdvancedForm({ payload }, { call }) { - yield call(fakeSubmitForm, payload); - message.success('提交成功'); + yield put({ + type: 'saveCurrentStep', + payload: 'result', + }); }, }, reducers: { + saveCurrentStep(state, { payload }) { + return { + ...state, + current: payload, + }; + }, + saveStepFormData(state, { payload }) { return { ...state, diff --git a/StepForm/src/service.js b/StepForm/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..77e522c8ca3527da73e4fc1e879705931c277028 --- /dev/null +++ b/StepForm/src/service.js @@ -0,0 +1,8 @@ +import request from 'umi-request'; + +export async function fakeSubmitForm(params) { + return request('/api/BLOCK_NAME/forms', { + method: 'POST', + data: params, + }); +} diff --git a/StepForm/src/style.less b/StepForm/src/style.less new file mode 100644 index 0000000000000000000000000000000000000000..6b12d3c3eaf4ad2159d35b7a8550f20ac37d72e5 --- /dev/null +++ b/StepForm/src/style.less @@ -0,0 +1,90 @@ +@import '~antd/lib/style/themes/default.less'; + +.card { + margin-bottom: 24px; +} + +.heading { + font-size: 14px; + line-height: 22px; + margin: 0 0 16px 0; +} + +.steps:global(.ant-steps) { + max-width: 750px; + margin: 16px auto; +} + +.errorIcon { + cursor: pointer; + color: @error-color; + margin-right: 24px; + i { + margin-right: 4px; + } +} + +.errorPopover { + :global { + .ant-popover-inner-content { + padding: 0; + max-height: 290px; + overflow: auto; + min-width: 256px; + } + } +} + +.errorListItem { + list-style: none; + border-bottom: 1px solid @border-color-split; + padding: 8px 16px; + cursor: pointer; + transition: all 0.3s; + &:hover { + background: @primary-1; + } + &:last-child { + border: 0; + } + .errorIcon { + color: @error-color; + float: left; + margin-top: 4px; + margin-right: 12px; + padding-bottom: 22px; + } + .errorField { + font-size: 12px; + color: @text-color-secondary; + margin-top: 2px; + } +} + +.editable { + td { + padding-top: 13px !important; + padding-bottom: 12.5px !important; + } +} + +// custom footer for fixed footer toolbar +.advancedForm + div { + padding-bottom: 64px; +} + +.advancedForm { + :global { + .ant-form .ant-row:last-child .ant-form-item { + margin-bottom: 24px; + } + .ant-table td { + transition: none !important; + } + } +} + +.optional { + color: @text-color-secondary; + font-style: normal; +} diff --git a/StepForm/src/utils/utils.js b/StepForm/src/utils/utils.js new file mode 100644 index 0000000000000000000000000000000000000000..042d3ec77ee08a9f67519fa98743dbf55432e622 --- /dev/null +++ b/StepForm/src/utils/utils.js @@ -0,0 +1,5 @@ +import nzh from 'nzh/cn'; + +export function digitUppercase(n) { + return nzh.toMoney(n); +} diff --git a/TableList/.gitignore b/TableList/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/TableList/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/TableList/.umirc.js b/TableList/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..545b4c7a99507a4973cd944fc2eafbd612ead8ef --- /dev/null +++ b/TableList/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/TableList/README.md b/TableList/README.md new file mode 100644 index 0000000000000000000000000000000000000000..dfa334226e2b2cdc7e95d58f9f357a9a4e7a62c1 --- /dev/null +++ b/TableList/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/tablelist + +TableList + +## Usage + +```sh +umi block add ant-design-pro/TableList +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/TableList/package.json b/TableList/package.json new file mode 100644 index 0000000000000000000000000000000000000000..67a10fcef41068ccd77a0e984658fec4117f4170 --- /dev/null +++ b/TableList/package.json @@ -0,0 +1,27 @@ +{ + "name": "@umi-block/table-list", + "version": "0.0.1", + "description": "TableList", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/tablelist" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "dva": "^2.4.0", + "moment": "^2.22.2", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "ISC" +} diff --git a/TableList/snapshot.png b/TableList/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..d45beade9bbaf79ae23a4f281f9ebca1a04ab08d Binary files /dev/null and b/TableList/snapshot.png differ diff --git a/mock/rule.js b/TableList/src/_mock.js similarity index 94% rename from mock/rule.js rename to TableList/src/_mock.js index 87d235b03ef83f4d229ef4dd2812a8a83a219ecc..96ebed0bf3ea0546f39e45334ad4025b5f02d6aa 100644 --- a/mock/rule.js +++ b/TableList/src/_mock.js @@ -122,10 +122,17 @@ function postRule(req, res, u, b) { break; } - return getRule(req, res, u); + const result = { + list: tableListDataSource, + pagination: { + total: tableListDataSource.length, + }, + }; + + return res.json(result); } export default { - 'GET /api/rule': getRule, - 'POST /api/rule': postRule, + 'GET /api/BLOCK_NAME': getRule, + 'POST /api/BLOCK_NAME': postRule, }; diff --git a/src/components/StandardTable/index.js b/TableList/src/components/StandardTable/index.js similarity index 100% rename from src/components/StandardTable/index.js rename to TableList/src/components/StandardTable/index.js diff --git a/src/components/StandardTable/index.less b/TableList/src/components/StandardTable/index.less similarity index 100% rename from src/components/StandardTable/index.less rename to TableList/src/components/StandardTable/index.less diff --git a/src/pages/List/TableList.js b/TableList/src/index.js similarity index 96% rename from src/pages/List/TableList.js rename to TableList/src/index.js index 13f5fb60d04ebfd2dbb78420bfb36e600aa8c12e..d6e5b79102a8d0257263c2bad006af6eae0eb74a 100644 --- a/src/pages/List/TableList.js +++ b/TableList/src/index.js @@ -21,10 +21,9 @@ import { Steps, Radio, } from 'antd'; -import StandardTable from '@/components/StandardTable'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; +import StandardTable from './components/StandardTable'; -import styles from './TableList.less'; +import styles from './style.less'; const FormItem = Form.Item; const { Step } = Steps; @@ -273,8 +272,8 @@ class UpdateForm extends PureComponent { } /* eslint react/no-multi-comp:0 */ -@connect(({ rule, loading }) => ({ - rule, +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ + BLOCK_NAME_CAMEL_CASE, loading: loading.models.rule, })) @Form.create() @@ -352,7 +351,7 @@ class TableList extends PureComponent { componentDidMount() { const { dispatch } = this.props; dispatch({ - type: 'rule/fetch', + type: 'BLOCK_NAME_CAMEL_CASE/fetch', }); } @@ -377,7 +376,7 @@ class TableList extends PureComponent { } dispatch({ - type: 'rule/fetch', + type: 'BLOCK_NAME_CAMEL_CASE/fetch', payload: params, }); }; @@ -389,7 +388,7 @@ class TableList extends PureComponent { formValues: {}, }); dispatch({ - type: 'rule/fetch', + type: 'BLOCK_NAME_CAMEL_CASE/fetch', payload: {}, }); }; @@ -405,11 +404,11 @@ class TableList extends PureComponent { const { dispatch } = this.props; const { selectedRows } = this.state; - if (selectedRows.length === 0) return; + if (!selectedRows) return; switch (e.key) { case 'remove': dispatch({ - type: 'rule/remove', + type: 'BLOCK_NAME_CAMEL_CASE/remove', payload: { key: selectedRows.map(row => row.key), }, @@ -449,7 +448,7 @@ class TableList extends PureComponent { }); dispatch({ - type: 'rule/fetch', + type: 'BLOCK_NAME_CAMEL_CASE/fetch', payload: values, }); }); @@ -471,7 +470,7 @@ class TableList extends PureComponent { handleAdd = fields => { const { dispatch } = this.props; dispatch({ - type: 'rule/add', + type: 'BLOCK_NAME_CAMEL_CASE/add', payload: { desc: fields.desc, }, @@ -483,16 +482,12 @@ class TableList extends PureComponent { handleUpdate = fields => { const { dispatch } = this.props; - const { formValues } = this.state; dispatch({ - type: 'rule/update', + type: 'BLOCK_NAME_CAMEL_CASE/update', payload: { - query: formValues, - body: { - name: fields.name, - desc: fields.desc, - key: fields.key, - }, + name: fields.name, + desc: fields.desc, + key: fields.key, }, }); @@ -621,7 +616,7 @@ class TableList extends PureComponent { render() { const { - rule: { data }, + BLOCK_NAME_CAMEL_CASE: { data }, loading, } = this.props; const { selectedRows, modalVisible, updateModalVisible, stepFormValues } = this.state; @@ -641,7 +636,7 @@ class TableList extends PureComponent { handleUpdate: this.handleUpdate, }; return ( - + {this.renderForm()} @@ -678,7 +673,7 @@ class TableList extends PureComponent { values={stepFormValues} /> ) : null} - + ); } } diff --git a/TableList/src/locales/en-US.js b/TableList/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..ff8b4c56321a3362fc00224b01800f62466f9a1f --- /dev/null +++ b/TableList/src/locales/en-US.js @@ -0,0 +1 @@ +export default {}; diff --git a/TableList/src/locales/pt-BR.js b/TableList/src/locales/pt-BR.js new file mode 100644 index 0000000000000000000000000000000000000000..ff8b4c56321a3362fc00224b01800f62466f9a1f --- /dev/null +++ b/TableList/src/locales/pt-BR.js @@ -0,0 +1 @@ +export default {}; diff --git a/TableList/src/locales/zh-CN.js b/TableList/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..ff8b4c56321a3362fc00224b01800f62466f9a1f --- /dev/null +++ b/TableList/src/locales/zh-CN.js @@ -0,0 +1 @@ +export default {}; diff --git a/TableList/src/locales/zh-TW.js b/TableList/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..ff8b4c56321a3362fc00224b01800f62466f9a1f --- /dev/null +++ b/TableList/src/locales/zh-TW.js @@ -0,0 +1 @@ +export default {}; diff --git a/src/pages/List/models/rule.js b/TableList/src/model.js similarity index 90% rename from src/pages/List/models/rule.js rename to TableList/src/model.js index b318dbe3649b8957b29bad438d42baecec269d4a..60e945d7accd0987fd81cf5543bdce4bf7891906 100644 --- a/src/pages/List/models/rule.js +++ b/TableList/src/model.js @@ -1,7 +1,7 @@ -import { queryRule, removeRule, addRule, updateRule } from '@/services/api'; +import { queryRule, removeRule, addRule, updateRule } from './service'; export default { - namespace: 'rule', + namespace: 'BLOCK_NAME_CAMEL_CASE', state: { data: { diff --git a/TableList/src/service.js b/TableList/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..45e88ff49950d38a28b97f08547b4147c0354fd9 --- /dev/null +++ b/TableList/src/service.js @@ -0,0 +1,37 @@ +import request from 'umi-request'; + +export async function queryRule(params) { + return request(`/api/BLOCK_NAME`, { + params, + }); +} + +export async function removeRule(params) { + return request('/api/BLOCK_NAME', { + method: 'POST', + data: { + ...params, + method: 'delete', + }, + }); +} + +export async function addRule(params) { + return request('/api/BLOCK_NAME', { + method: 'POST', + data: { + ...params, + method: 'post', + }, + }); +} + +export async function updateRule(params) { + return request('/api/BLOCK_NAME', { + method: 'POST', + data: { + ...params, + method: 'update', + }, + }); +} diff --git a/src/pages/List/TableList.less b/TableList/src/style.less similarity index 96% rename from src/pages/List/TableList.less rename to TableList/src/style.less index 792757dfa5888c5bb934ada39842d467f407d10c..0140a75704530c6ce49c3714e4bdcb928c3de940 100644 --- a/src/pages/List/TableList.less +++ b/TableList/src/style.less @@ -1,5 +1,5 @@ @import '~antd/lib/style/themes/default.less'; -@import '~@/utils/utils.less'; +@import './utils/utils.less'; .tableList { .tableListOperator { diff --git a/TableList/src/utils/utils.less b/TableList/src/utils/utils.less new file mode 100644 index 0000000000000000000000000000000000000000..725792252787f49efba4f4e887301195a9818f3f --- /dev/null +++ b/TableList/src/utils/utils.less @@ -0,0 +1,50 @@ +.textOverflow() { + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + white-space: nowrap; +} + +.textOverflowMulti(@line: 3, @bg: #fff) { + overflow: hidden; + position: relative; + line-height: 1.5em; + max-height: @line * 1.5em; + text-align: justify; + margin-right: -1em; + padding-right: 1em; + &:before { + background: @bg; + content: '...'; + padding: 0 1px; + position: absolute; + right: 14px; + bottom: 0; + } + &:after { + background: white; + content: ''; + margin-top: 0.2em; + position: absolute; + right: 14px; + width: 1em; + height: 1em; + } +} + +// mixins for clearfix +// ------------------------ +.clearfix() { + zoom: 1; + &:before, + &:after { + content: ' '; + display: table; + } + &:after { + clear: both; + visibility: hidden; + font-size: 0; + height: 0; + } +} diff --git a/UserLogin/.gitignore b/UserLogin/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/UserLogin/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/UserLogin/.umirc.js b/UserLogin/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..ed8db9a149035779b8d35bb8f32ce6b8b0052aad --- /dev/null +++ b/UserLogin/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro-user', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }] + ], +} diff --git a/UserLogin/README.md b/UserLogin/README.md new file mode 100644 index 0000000000000000000000000000000000000000..38fe9e25ec1c1697d84c025404361bcbebec587e --- /dev/null +++ b/UserLogin/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/userlogin + +UserLogin + +## Usage + +```sh +umi block add ant-design-pro/UserLogin +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/UserLogin/package.json b/UserLogin/package.json new file mode 100644 index 0000000000000000000000000000000000000000..837153b608abe63aae7d655b46a37be802a9daa0 --- /dev/null +++ b/UserLogin/package.json @@ -0,0 +1,28 @@ +{ + "name": "@umi-block/user-login", + "version": "0.0.1", + "description": "UserLogin", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/userlogin" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "dva": "^2.4.0", + "moment": "^2.22.2", + "query-string": "^6.0.0", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0", + "umi-plugin-react": "^1.3.0-beta.1" + }, + "license": "MIT" +} diff --git a/UserLogin/snapshot.png b/UserLogin/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..7017051bee3e2fabceabfd6e0f6b619200599bda Binary files /dev/null and b/UserLogin/snapshot.png differ diff --git a/UserLogin/src/_mock.js b/UserLogin/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..362b027c6a9a0c47cc7808c1e75b46619b4a2f74 --- /dev/null +++ b/UserLogin/src/_mock.js @@ -0,0 +1,31 @@ +function getFakeCaptcha(req, res) { + return res.json('captcha-xxx'); +} + +export default { + 'POST /api/BLOCK_NAME/account': (req, res) => { + const { password, userName, type } = req.body; + if (password === 'ant.design' && userName === 'admin') { + res.send({ + status: 'ok', + type, + currentAuthority: 'admin', + }); + return; + } + if (password === 'ant.design' && userName === 'user') { + res.send({ + status: 'ok', + type, + currentAuthority: 'user', + }); + return; + } + res.send({ + status: 'error', + type, + currentAuthority: 'guest', + }); + }, + 'GET /api/BLOCK_NAME/captcha': getFakeCaptcha, +}; diff --git a/src/pages/User/Login.js b/UserLogin/src/index.js similarity index 61% rename from src/pages/User/Login.js rename to UserLogin/src/index.js index 54dd5c40d9282b50ff7003d709bbfbf3758a4d41..33ba5e1b8d29b6377c910fd5c15d294a28718354 100644 --- a/src/pages/User/Login.js +++ b/UserLogin/src/index.js @@ -3,14 +3,14 @@ import { connect } from 'dva'; import { formatMessage, FormattedMessage } from 'umi/locale'; import Link from 'umi/link'; import { Checkbox, Alert, Icon } from 'antd'; -import Login from '@/components/Login'; -import styles from './Login.less'; +import { Login } from 'ant-design-pro'; +import styles from './style.less'; const { Tab, UserName, Password, Mobile, Captcha, Submit } = Login; -@connect(({ login, loading }) => ({ - login, - submitting: loading.effects['login/login'], +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ + BLOCK_NAME_CAMEL_CASE, + submitting: loading.effects['BLOCK_NAME_CAMEL_CASE/login'], })) class LoginPage extends Component { state = { @@ -30,7 +30,7 @@ class LoginPage extends Component { } else { const { dispatch } = this.props; dispatch({ - type: 'login/getCaptcha', + type: 'BLOCK_NAME_CAMEL_CASE/getCaptcha', payload: values.mobile, }) .then(resolve) @@ -44,7 +44,7 @@ class LoginPage extends Component { if (!err) { const { dispatch } = this.props; dispatch({ - type: 'login/login', + type: 'BLOCK_NAME_CAMEL_CASE/login', payload: { ...values, type, @@ -64,7 +64,8 @@ class LoginPage extends Component { ); render() { - const { login, submitting } = this.props; + const { BLOCK_NAME_CAMEL_CASE, submitting } = this.props; + const { status, type: loginType } = BLOCK_NAME_CAMEL_CASE; const { type, autoLogin } = this.state; return ( @@ -76,87 +77,87 @@ class LoginPage extends Component { this.loginForm = form; }} > - - {login.status === 'error' && - login.type === 'account' && + + {status === 'error' && + loginType === 'account' && !submitting && - this.renderMessage(formatMessage({ id: 'app.login.message-invalid-credentials' }))} + this.renderMessage(formatMessage({ id: 'BLOCK_NAME.login.message-invalid-credentials' }))} this.loginForm.validateFields(this.handleSubmit)} /> - - {login.status === 'error' && - login.type === 'mobile' && + + {status === 'error' && + loginType === 'mobile' && !submitting && this.renderMessage( - formatMessage({ id: 'app.login.message-invalid-verification-code' }) + formatMessage({ id: 'BLOCK_NAME.login.message-invalid-verification-code' }) )} - + - + - + - + - + diff --git a/UserLogin/src/locales/en-US.js b/UserLogin/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..f58ec412c7a23fbc16cbc2ad5ba3c2cb3041dd4c --- /dev/null +++ b/UserLogin/src/locales/en-US.js @@ -0,0 +1,76 @@ +export default { + 'BLOCK_NAME.login.userName': 'userName', + 'BLOCK_NAME.login.password': 'password', + 'BLOCK_NAME.login.message-invalid-credentials': 'Invalid username or password(admin/ant.design)', + 'BLOCK_NAME.login.message-invalid-verification-code': 'Invalid verification code', + 'BLOCK_NAME.login.tab-login-credentials': 'Credentials', + 'BLOCK_NAME.login.tab-login-mobile': 'Mobile number', + 'BLOCK_NAME.login.remember-me': 'Remember me', + 'BLOCK_NAME.login.forgot-password': 'Forgot your password?', + 'BLOCK_NAME.login.sign-in-with': 'Sign in with', + 'BLOCK_NAME.login.signup': 'Sign up', + 'BLOCK_NAME.login.login': 'Login', + 'BLOCK_NAME.register.register': 'Register', + 'BLOCK_NAME.register.get-verification-code': 'Get code', + 'BLOCK_NAME.register.sign-in': 'Already have an account?', + 'BLOCK_NAME.register-result.msg': 'Account:registered at {email}', + 'BLOCK_NAME.register-result.activation-email': + 'The activation email has been sent to your email address and is valid for 24 hours. Please log in to the email in time and click on the link in the email to activate the account.', + 'BLOCK_NAME.register-result.back-home': 'Back to home', + 'BLOCK_NAME.register-result.view-mailbox': 'View mailbox', + 'BLOCK_NAME.email.required': 'Please enter your email!', + 'BLOCK_NAME.email.wrong-format': 'The email address is in the wrong format!', + 'BLOCK_NAME.userName.required': 'Please enter your userName!', + 'BLOCK_NAME.password.required': 'Please enter your password!', + 'BLOCK_NAME.password.twice': 'The passwords entered twice do not match!', + 'BLOCK_NAME.strength.msg': + "Please enter at least 6 characters and don't use passwords that are easy to guess.", + 'BLOCK_NAME.strength.strong': 'Strength: strong', + 'BLOCK_NAME.strength.medium': 'Strength: medium', + 'BLOCK_NAME.strength.short': 'Strength: too short', + 'BLOCK_NAME.confirm-password.required': 'Please confirm your password!', + 'BLOCK_NAME.phone-number.required': 'Please enter your phone number!', + 'BLOCK_NAME.phone-number.wrong-format': 'Malformed phone number!', + 'BLOCK_NAME.verification-code.required': 'Please enter the verification code!', + 'BLOCK_NAME.title.required': 'Please enter a title', + 'BLOCK_NAME.date.required': 'Please select the start and end date', + 'BLOCK_NAME.goal.required': 'Please enter a description of the goal', + 'BLOCK_NAME.standard.required': 'Please enter a metric', + 'BLOCK_NAME.form.get-captcha': 'Get Captcha', + 'BLOCK_NAME.captcha.second': 'sec', + 'BLOCK_NAME.form.optional': ' (optional) ', + 'BLOCK_NAME.form.submit': 'Submit', + 'BLOCK_NAME.form.save': 'Save', + 'BLOCK_NAME.email.placeholder': 'Email', + 'BLOCK_NAME.password.placeholder': 'Password', + 'BLOCK_NAME.confirm-password.placeholder': 'Confirm password', + 'BLOCK_NAME.phone-number.placeholder': 'Phone number', + 'BLOCK_NAME.verification-code.placeholder': 'Verification code', + 'BLOCK_NAME.title.label': 'Title', + 'BLOCK_NAME.title.placeholder': 'Give the target a name', + 'BLOCK_NAME.date.label': 'Start and end date', + 'BLOCK_NAME.placeholder.start': 'Start date', + 'BLOCK_NAME.placeholder.end': 'End date', + 'BLOCK_NAME.goal.label': 'Goal description', + 'BLOCK_NAME.goal.placeholder': 'Please enter your work goals', + 'BLOCK_NAME.standard.label': 'Metrics', + 'BLOCK_NAME.standard.placeholder': 'Please enter a metric', + 'BLOCK_NAME.client.label': 'Client', + 'BLOCK_NAME.label.tooltip': 'Target service object', + 'BLOCK_NAME.client.placeholder': + 'Please describe your customer service, internal customers directly @ Name / job number', + 'BLOCK_NAME.invites.label': 'Inviting critics', + 'BLOCK_NAME.invites.placeholder': 'Please direct @ Name / job number, you can invite up to 5 people', + 'BLOCK_NAME.weight.label': 'Weight', + 'BLOCK_NAME.weight.placeholder': 'Please enter weight', + 'BLOCK_NAME.public.label': 'Target disclosure', + 'BLOCK_NAME.label.help': 'Customers and invitees are shared by default', + 'BLOCK_NAME.radio.public': 'Public', + 'BLOCK_NAME.radio.partially-public': 'Partially public', + 'BLOCK_NAME.radio.private': 'Private', + 'BLOCK_NAME.publicUsers.placeholder': 'Open to', + 'BLOCK_NAME.option.A': 'Colleague A', + 'BLOCK_NAME.option.B': 'Colleague B', + 'BLOCK_NAME.option.C': 'Colleague C', + 'BLOCK_NAME.navBar.lang': 'Languages', +}; diff --git a/UserLogin/src/locales/zh-CN.js b/UserLogin/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..9018096f9d714fab461b743be6238b963a65b676 --- /dev/null +++ b/UserLogin/src/locales/zh-CN.js @@ -0,0 +1,74 @@ +export default { + 'BLOCK_NAME.login.userName': '用户名', + 'BLOCK_NAME.login.password': '密码', + 'BLOCK_NAME.login.message-invalid-credentials': '账户或密码错误(admin/ant.design)', + 'BLOCK_NAME.login.message-invalid-verification-code': '验证码错误', + 'BLOCK_NAME.login.tab-login-credentials': '账户密码登录', + 'BLOCK_NAME.login.tab-login-mobile': '手机号登录', + 'BLOCK_NAME.login.remember-me': '自动登录', + 'BLOCK_NAME.login.forgot-password': '忘记密码', + 'BLOCK_NAME.login.sign-in-with': '其他登录方式', + 'BLOCK_NAME.login.signup': '注册账户', + 'BLOCK_NAME.login.login': '登录', + 'BLOCK_NAME.register.register': '注册', + 'BLOCK_NAME.register.get-verification-code': '获取验证码', + 'BLOCK_NAME.register.sign-in': '使用已有账户登录', + 'BLOCK_NAME.register-result.msg': '你的账户:{email} 注册成功', + 'BLOCK_NAME.register-result.activation-email': + '激活邮件已发送到你的邮箱中,邮件有效期为24小时。请及时登录邮箱,点击邮件中的链接激活帐户。', + 'BLOCK_NAME.register-result.back-home': '返回首页', + 'BLOCK_NAME.register-result.view-mailbox': '查看邮箱', + 'BLOCK_NAME.email.required': '请输入邮箱地址!', + 'BLOCK_NAME.email.wrong-format': '邮箱地址格式错误!', + 'BLOCK_NAME.userName.required': '请输入用户名!', + 'BLOCK_NAME.password.required': '请输入密码!', + 'BLOCK_NAME.password.twice': '两次输入的密码不匹配!', + 'BLOCK_NAME.strength.msg': '请至少输入 6 个字符。请不要使用容易被猜到的密码。', + 'BLOCK_NAME.strength.strong': '强度:强', + 'BLOCK_NAME.strength.medium': '强度:中', + 'BLOCK_NAME.strength.short': '强度:太短', + 'BLOCK_NAME.confirm-password.required': '请确认密码!', + 'BLOCK_NAME.phone-number.required': '请输入手机号!', + 'BLOCK_NAME.phone-number.wrong-format': '手机号格式错误!', + 'BLOCK_NAME.verification-code.required': '请输入验证码!', + 'BLOCK_NAME.title.required': '请输入标题', + 'BLOCK_NAME.date.required': '请选择起止日期', + 'BLOCK_NAME.goal.required': '请输入目标描述', + 'BLOCK_NAME.standard.required': '请输入衡量标准', + 'BLOCK_NAME.form.get-captcha': '获取验证码', + 'BLOCK_NAME.captcha.second': '秒', + 'BLOCK_NAME.form.optional': '(选填)', + 'BLOCK_NAME.form.submit': '提交', + 'BLOCK_NAME.form.save': '保存', + 'BLOCK_NAME.email.placeholder': '邮箱', + 'BLOCK_NAME.password.placeholder': '至少6位密码,区分大小写', + 'BLOCK_NAME.confirm-password.placeholder': '确认密码', + 'BLOCK_NAME.phone-number.placeholder': '手机号', + 'BLOCK_NAME.verification-code.placeholder': '验证码', + 'BLOCK_NAME.title.label': '标题', + 'BLOCK_NAME.title.placeholder': '给目标起个名字', + 'BLOCK_NAME.date.label': '起止日期', + 'BLOCK_NAME.placeholder.start': '开始日期', + 'BLOCK_NAME.placeholder.end': '结束日期', + 'BLOCK_NAME.goal.label': '目标描述', + 'BLOCK_NAME.goal.placeholder': '请输入你的阶段性工作目标', + 'BLOCK_NAME.standard.label': '衡量标准', + 'BLOCK_NAME.standard.placeholder': '请输入衡量标准', + 'BLOCK_NAME.client.label': '客户', + 'BLOCK_NAME.label.tooltip': '目标的服务对象', + 'BLOCK_NAME.client.placeholder': '请描述你服务的客户,内部客户直接 @姓名/工号', + 'BLOCK_NAME.invites.label': '邀评人', + 'BLOCK_NAME.invites.placeholder': '请直接 @姓名/工号,最多可邀请 5 人', + 'BLOCK_NAME.weight.label': '权重', + 'BLOCK_NAME.weight.placeholder': '请输入', + 'BLOCK_NAME.public.label': '目标公开', + 'BLOCK_NAME.label.help': '客户、邀评人默认被分享', + 'BLOCK_NAME.radio.public': '公开', + 'BLOCK_NAME.radio.partially-public': '部分公开', + 'BLOCK_NAME.radio.private': '不公开', + 'BLOCK_NAME.publicUsers.placeholder': '公开给', + 'BLOCK_NAME.option.A': '同事甲', + 'BLOCK_NAME.option.B': '同事乙', + 'BLOCK_NAME.option.C': '同事丙', + 'BLOCK_NAME.navBar.lang': '语言', +}; diff --git a/UserLogin/src/locales/zh-TW.js b/UserLogin/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..f673d58c2d0336fcc37f6ba02d765048b96b9c1b --- /dev/null +++ b/UserLogin/src/locales/zh-TW.js @@ -0,0 +1,74 @@ +export default { + 'BLOCK_NAME.login.userName': '賬戶', + 'BLOCK_NAME.login.password': '密碼', + 'BLOCK_NAME.login.message-invalid-credentials': '賬戶或密碼錯誤(admin/ant.design)', + 'BLOCK_NAME.login.message-invalid-verification-code': '驗證碼錯誤', + 'BLOCK_NAME.login.tab-login-credentials': '賬戶密碼登錄', + 'BLOCK_NAME.login.tab-login-mobile': '手機號登錄', + 'BLOCK_NAME.login.remember-me': '自動登錄', + 'BLOCK_NAME.login.forgot-password': '忘記密碼', + 'BLOCK_NAME.login.sign-in-with': '其他登錄方式', + 'BLOCK_NAME.login.signup': '註冊賬戶', + 'BLOCK_NAME.login.login': '登錄', + 'BLOCK_NAME.register.register': '註冊', + 'BLOCK_NAME.register.get-verification-code': '獲取驗證碼', + 'BLOCK_NAME.register.sign-in': '使用已有賬戶登錄', + 'BLOCK_NAME.register-result.msg': '妳的賬戶:{email} 註冊成功', + 'BLOCK_NAME.register-result.activation-email': + '激活郵件已發送到妳的郵箱中,郵件有效期為24小時。請及時登錄郵箱,點擊郵件中的鏈接激活帳戶。', + 'BLOCK_NAME.register-result.back-home': '返回首頁', + 'BLOCK_NAME.register-result.view-mailbox': '查看郵箱', + 'BLOCK_NAME.email.required': '請輸入郵箱地址!', + 'BLOCK_NAME.email.wrong-format': '郵箱地址格式錯誤!', + 'BLOCK_NAME.userName.required': '請輸入賬戶!', + 'BLOCK_NAME.password.required': '請輸入密碼!', + 'BLOCK_NAME.password.twice': '兩次輸入的密碼不匹配!', + 'BLOCK_NAME.strength.msg': '請至少輸入 6 個字符。請不要使用容易被猜到的密碼。', + 'BLOCK_NAME.strength.strong': '強度:強', + 'BLOCK_NAME.strength.medium': '強度:中', + 'BLOCK_NAME.strength.short': '強度:太短', + 'BLOCK_NAME.confirm-password.required': '請確認密碼!', + 'BLOCK_NAME.phone-number.required': '請輸入手機號!', + 'BLOCK_NAME.phone-number.wrong-format': '手機號格式錯誤!', + 'BLOCK_NAME.verification-code.required': '請輸入驗證碼!', + 'BLOCK_NAME.title.required': '請輸入標題', + 'BLOCK_NAME.date.required': '請選擇起止日期', + 'BLOCK_NAME.goal.required': '請輸入目標描述', + 'BLOCK_NAME.standard.required': '請輸入衡量標淮', + 'BLOCK_NAME.form.get-captcha': '獲取驗證碼', + 'BLOCK_NAME.captcha.second': '秒', + 'BLOCK_NAME.form.optional': '(選填)', + 'BLOCK_NAME.form.submit': '提交', + 'BLOCK_NAME.form.save': '保存', + 'BLOCK_NAME.email.placeholder': '郵箱', + 'BLOCK_NAME.password.placeholder': '至少6位密碼,區分大小寫', + 'BLOCK_NAME.confirm-password.placeholder': '確認密碼', + 'BLOCK_NAME.phone-number.placeholder': '手機號', + 'BLOCK_NAME.verification-code.placeholder': '驗證碼', + 'BLOCK_NAME.title.label': '標題', + 'BLOCK_NAME.title.placeholder': '給目標起個名字', + 'BLOCK_NAME.date.label': '起止日期', + 'BLOCK_NAME.placeholder.start': '開始日期', + 'BLOCK_NAME.placeholder.end': '結束日期', + 'BLOCK_NAME.goal.label': '目標描述', + 'BLOCK_NAME.goal.placeholder': '請輸入妳的階段性工作目標', + 'BLOCK_NAME.standard.label': '衡量標淮', + 'BLOCK_NAME.standard.placeholder': '請輸入衡量標淮', + 'BLOCK_NAME.client.label': '客戶', + 'BLOCK_NAME.label.tooltip': '目標的服務對象', + 'BLOCK_NAME.client.placeholder': '請描述妳服務的客戶,內部客戶直接 @姓名/工號', + 'BLOCK_NAME.invites.label': '邀評人', + 'BLOCK_NAME.invites.placeholder': '請直接 @姓名/工號,最多可邀請 5 人', + 'BLOCK_NAME.weight.label': '權重', + 'BLOCK_NAME.weight.placeholder': '請輸入', + 'BLOCK_NAME.public.label': '目標公開', + 'BLOCK_NAME.label.help': '客戶、邀評人默認被分享', + 'BLOCK_NAME.radio.public': '公開', + 'BLOCK_NAME.radio.partially-public': '部分公開', + 'BLOCK_NAME.radio.private': '不公開', + 'BLOCK_NAME.publicUsers.placeholder': '公開給', + 'BLOCK_NAME.option.A': '同事甲', + 'BLOCK_NAME.option.B': '同事乙', + 'BLOCK_NAME.option.C': '同事丙', + 'BLOCK_NAME.navBar.lang': '語言', +}; diff --git a/src/models/login.js b/UserLogin/src/model.js similarity index 66% rename from src/models/login.js rename to UserLogin/src/model.js index 82fc4249a57c96a9f6387cd34c3b152387f2b320..12af13ab1f22b8aa28102b6503ce688b96c614a4 100644 --- a/src/models/login.js +++ b/UserLogin/src/model.js @@ -1,12 +1,11 @@ import { routerRedux } from 'dva/router'; -import { stringify } from 'qs'; -import { fakeAccountLogin, getFakeCaptcha } from '@/services/api'; -import { setAuthority } from '@/utils/authority'; -import { getPageQuery } from '@/utils/utils'; -import { reloadAuthorized } from '@/utils/Authorized'; +import { getPageQuery } from './utils/utils'; +import { setAuthority } from './utils/authority'; +import { reloadAuthorized } from './utils/Authorized'; +import { fakeAccountLogin, getFakeCaptcha } from './service'; export default { - namespace: 'login', + namespace: 'BLOCK_NAME_CAMEL_CASE', state: { status: undefined, @@ -44,25 +43,6 @@ export default { *getCaptcha({ payload }, { call }) { yield call(getFakeCaptcha, payload); }, - - *logout(_, { put }) { - yield put({ - type: 'changeLoginStatus', - payload: { - status: false, - currentAuthority: 'guest', - }, - }); - reloadAuthorized(); - yield put( - routerRedux.push({ - pathname: '/user/login', - search: stringify({ - redirect: window.location.href, - }), - }) - ); - }, }, reducers: { diff --git a/UserLogin/src/service.js b/UserLogin/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..9e99a1b848fa0c325be864d4e02db2093c32cd93 --- /dev/null +++ b/UserLogin/src/service.js @@ -0,0 +1,12 @@ +import request from 'umi-request'; + +export async function fakeAccountLogin(params) { + return request('/api/BLOCK_NAME/account', { + method: 'POST', + data: params, + }); +} + +export async function getFakeCaptcha(mobile) { + return request(`/api/BLOCK_NAME/captcha?mobile=${mobile}`); +} diff --git a/src/pages/User/Login.less b/UserLogin/src/style.less similarity index 84% rename from src/pages/User/Login.less rename to UserLogin/src/style.less index 14a99ff11664d32aec1411154ec735ead61aae04..eb5da08a64d52cbc0dcca2977cd30ace3b0607ce 100644 --- a/src/pages/User/Login.less +++ b/UserLogin/src/style.less @@ -29,4 +29,11 @@ float: right; } } + + :global { + .antd-pro-login-submit { + width: 100%; + margin-top: 24px; + } + } } diff --git a/src/utils/Authorized.js b/UserLogin/src/utils/Authorized.js similarity index 82% rename from src/utils/Authorized.js rename to UserLogin/src/utils/Authorized.js index 8c420cbaa1441f2fa4f52e4c97b8aa327cddce26..25948912b62f33f71f2ccbec1cea3668cefe827f 100644 --- a/src/utils/Authorized.js +++ b/UserLogin/src/utils/Authorized.js @@ -1,4 +1,4 @@ -import RenderAuthorized from '@/components/Authorized'; +import RenderAuthorized from 'ant-design-pro/lib/Authorized'; import { getAuthority } from './authority'; let Authorized = RenderAuthorized(getAuthority()); // eslint-disable-line diff --git a/src/utils/authority.js b/UserLogin/src/utils/authority.js similarity index 100% rename from src/utils/authority.js rename to UserLogin/src/utils/authority.js diff --git a/UserLogin/src/utils/utils.js b/UserLogin/src/utils/utils.js new file mode 100644 index 0000000000000000000000000000000000000000..3faa2675294651c914d7368a1a9cf14db5d4beb9 --- /dev/null +++ b/UserLogin/src/utils/utils.js @@ -0,0 +1,5 @@ +import { parse } from 'query-string' + +export function getPageQuery() { + return parse(window.location.href.split('?')[1]); +} diff --git a/UserRegister/.gitignore b/UserRegister/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/UserRegister/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/UserRegister/.umirc.js b/UserRegister/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..ccfbb4565c8302b483ff1976dbc1ffb158929bd2 --- /dev/null +++ b/UserRegister/.umirc.js @@ -0,0 +1,18 @@ +export default { + plugins: [ + [ + 'umi-plugin-block-dev', + { + layout: 'ant-design-pro-user', + }, + ], + [ + 'umi-plugin-react', + { + dva: true, + locale: true, + antd: true, + }, + ], + ], +}; diff --git a/UserRegister/README.md b/UserRegister/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9bbd2175d6a265e073bb20848780ee7d883bcccc --- /dev/null +++ b/UserRegister/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/userregister + +UserRegister + +## Usage + +```sh +umi block add ant-design-pro/UserRegister +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/UserRegister/package.json b/UserRegister/package.json new file mode 100644 index 0000000000000000000000000000000000000000..6fd41843da450e5117b114541a7402bc323d5fb4 --- /dev/null +++ b/UserRegister/package.json @@ -0,0 +1,29 @@ +{ + "name": "@umi-block/user-register", + "version": "0.0.1", + "description": "UserRegister", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/userregister" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "dva": "^2.4.0", + "hash.js": "^1.1.5", + "moment": "^2.22.2", + "nzh": "^1.0.3", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "MIT" +} diff --git a/UserRegister/snapshot.png b/UserRegister/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..252430d2436c1798d961fce683bbe27c67a7120e Binary files /dev/null and b/UserRegister/snapshot.png differ diff --git a/UserRegister/src/_mock.js b/UserRegister/src/_mock.js new file mode 100644 index 0000000000000000000000000000000000000000..d5f84befa22ce585866f22d56c1dcf339dc59294 --- /dev/null +++ b/UserRegister/src/_mock.js @@ -0,0 +1,5 @@ +export default { + 'POST /api/BLOCK_NAME/register': (req, res) => { + res.send({ status: 'ok', currentAuthority: 'user' }); + }, +}; diff --git a/src/pages/User/Register.js b/UserRegister/src/index.js similarity index 80% rename from src/pages/User/Register.js rename to UserRegister/src/index.js index ea4565c28bac77692a0f520ef372b7f4b8e5dc0a..505999cba0cec2ed3311e6ec77f0215c5db18098 100644 --- a/src/pages/User/Register.js +++ b/UserRegister/src/index.js @@ -4,7 +4,7 @@ import { formatMessage, FormattedMessage } from 'umi/locale'; import Link from 'umi/link'; import router from 'umi/router'; import { Form, Input, Button, Select, Row, Col, Popover, Progress } from 'antd'; -import styles from './Register.less'; +import styles from './style.less'; const FormItem = Form.Item; const { Option } = Select; @@ -13,17 +13,17 @@ const InputGroup = Input.Group; const passwordStatusMap = { ok: ( - + ), pass: ( - + ), poor: ( - + ), }; @@ -34,12 +34,12 @@ const passwordProgressMap = { poor: 'exception', }; -@connect(({ register, loading }) => ({ - register, - submitting: loading.effects['register/submit'], +@connect(({ BLOCK_NAME_CAMEL_CASE, loading }) => ({ + BLOCK_NAME_CAMEL_CASE, + submitting: loading.effects['BLOCK_NAME_CAMEL_CASE/submit'], })) @Form.create() -class Register extends Component { +class PAGE_NAME_UPPER_CAMEL_CASE extends Component { state = { count: 0, confirmDirty: false, @@ -49,9 +49,9 @@ class Register extends Component { }; componentDidUpdate() { - const { form, register } = this.props; + const { form, BLOCK_NAME_CAMEL_CASE } = this.props; const account = form.getFieldValue('mail'); - if (register.status === 'ok') { + if (BLOCK_NAME_CAMEL_CASE.status === 'ok') { router.push({ pathname: '/user/register-result', state: { @@ -96,7 +96,7 @@ class Register extends Component { if (!err) { const { prefix } = this.state; dispatch({ - type: 'register/submit', + type: 'BLOCK_NAME_CAMEL_CASE/submit', payload: { ...values, prefix, @@ -115,7 +115,7 @@ class Register extends Component { checkConfirm = (rule, value, callback) => { const { form } = this.props; if (value && value !== form.getFieldValue('password')) { - callback(formatMessage({ id: 'validation.password.twice' })); + callback(formatMessage({ id: 'BLOCK_NAME.password.twice' })); } else { callback(); } @@ -125,7 +125,7 @@ class Register extends Component { const { visible, confirmDirty } = this.state; if (!value) { this.setState({ - help: formatMessage({ id: 'validation.password.required' }), + help: formatMessage({ id: 'BLOCK_NAME.password.required' }), visible: !!value, }); callback('error'); @@ -180,7 +180,7 @@ class Register extends Component { return ( - + @@ -188,15 +188,15 @@ class Register extends Component { rules: [ { required: true, - message: formatMessage({ id: 'validation.email.required' }), + message: formatMessage({ id: 'BLOCK_NAME.email.required' }), }, { type: 'email', - message: formatMessage({ id: 'validation.email.wrong-format' }), + message: formatMessage({ id: 'BLOCK_NAME.email.wrong-format' }), }, ], })( - + )} @@ -207,7 +207,7 @@ class Register extends Component { {passwordStatusMap[this.getPasswordStatus()]} {this.renderPasswordProgress()} - + } @@ -225,7 +225,7 @@ class Register extends Component { )} @@ -235,7 +235,7 @@ class Register extends Component { rules: [ { required: true, - message: formatMessage({ id: 'validation.confirm-password.required' }), + message: formatMessage({ id: 'BLOCK_NAME.confirm-password.required' }), }, { validator: this.checkConfirm, @@ -245,7 +245,7 @@ class Register extends Component { )} @@ -264,18 +264,18 @@ class Register extends Component { rules: [ { required: true, - message: formatMessage({ id: 'validation.phone-number.required' }), + message: formatMessage({ id: 'BLOCK_NAME.phone-number.required' }), }, { pattern: /^\d{11}$/, - message: formatMessage({ id: 'validation.phone-number.wrong-format' }), + message: formatMessage({ id: 'BLOCK_NAME.phone-number.wrong-format' }), }, ], })( )} @@ -287,13 +287,13 @@ class Register extends Component { rules: [ { required: true, - message: formatMessage({ id: 'validation.verification-code.required' }), + message: formatMessage({ id: 'BLOCK_NAME.verification-code.required' }), }, ], })( )} @@ -306,7 +306,7 @@ class Register extends Component { > {count ? `${count} s` - : formatMessage({ id: 'app.register.get-verification-code' })} + : formatMessage({ id: 'BLOCK_NAME.register.get-verification-code' })} @@ -319,10 +319,10 @@ class Register extends Component { type="primary" htmlType="submit" > - + - + @@ -331,4 +331,4 @@ class Register extends Component { } } -export default Register; +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/UserRegister/src/locales/en-US.js b/UserRegister/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..f58ec412c7a23fbc16cbc2ad5ba3c2cb3041dd4c --- /dev/null +++ b/UserRegister/src/locales/en-US.js @@ -0,0 +1,76 @@ +export default { + 'BLOCK_NAME.login.userName': 'userName', + 'BLOCK_NAME.login.password': 'password', + 'BLOCK_NAME.login.message-invalid-credentials': 'Invalid username or password(admin/ant.design)', + 'BLOCK_NAME.login.message-invalid-verification-code': 'Invalid verification code', + 'BLOCK_NAME.login.tab-login-credentials': 'Credentials', + 'BLOCK_NAME.login.tab-login-mobile': 'Mobile number', + 'BLOCK_NAME.login.remember-me': 'Remember me', + 'BLOCK_NAME.login.forgot-password': 'Forgot your password?', + 'BLOCK_NAME.login.sign-in-with': 'Sign in with', + 'BLOCK_NAME.login.signup': 'Sign up', + 'BLOCK_NAME.login.login': 'Login', + 'BLOCK_NAME.register.register': 'Register', + 'BLOCK_NAME.register.get-verification-code': 'Get code', + 'BLOCK_NAME.register.sign-in': 'Already have an account?', + 'BLOCK_NAME.register-result.msg': 'Account:registered at {email}', + 'BLOCK_NAME.register-result.activation-email': + 'The activation email has been sent to your email address and is valid for 24 hours. Please log in to the email in time and click on the link in the email to activate the account.', + 'BLOCK_NAME.register-result.back-home': 'Back to home', + 'BLOCK_NAME.register-result.view-mailbox': 'View mailbox', + 'BLOCK_NAME.email.required': 'Please enter your email!', + 'BLOCK_NAME.email.wrong-format': 'The email address is in the wrong format!', + 'BLOCK_NAME.userName.required': 'Please enter your userName!', + 'BLOCK_NAME.password.required': 'Please enter your password!', + 'BLOCK_NAME.password.twice': 'The passwords entered twice do not match!', + 'BLOCK_NAME.strength.msg': + "Please enter at least 6 characters and don't use passwords that are easy to guess.", + 'BLOCK_NAME.strength.strong': 'Strength: strong', + 'BLOCK_NAME.strength.medium': 'Strength: medium', + 'BLOCK_NAME.strength.short': 'Strength: too short', + 'BLOCK_NAME.confirm-password.required': 'Please confirm your password!', + 'BLOCK_NAME.phone-number.required': 'Please enter your phone number!', + 'BLOCK_NAME.phone-number.wrong-format': 'Malformed phone number!', + 'BLOCK_NAME.verification-code.required': 'Please enter the verification code!', + 'BLOCK_NAME.title.required': 'Please enter a title', + 'BLOCK_NAME.date.required': 'Please select the start and end date', + 'BLOCK_NAME.goal.required': 'Please enter a description of the goal', + 'BLOCK_NAME.standard.required': 'Please enter a metric', + 'BLOCK_NAME.form.get-captcha': 'Get Captcha', + 'BLOCK_NAME.captcha.second': 'sec', + 'BLOCK_NAME.form.optional': ' (optional) ', + 'BLOCK_NAME.form.submit': 'Submit', + 'BLOCK_NAME.form.save': 'Save', + 'BLOCK_NAME.email.placeholder': 'Email', + 'BLOCK_NAME.password.placeholder': 'Password', + 'BLOCK_NAME.confirm-password.placeholder': 'Confirm password', + 'BLOCK_NAME.phone-number.placeholder': 'Phone number', + 'BLOCK_NAME.verification-code.placeholder': 'Verification code', + 'BLOCK_NAME.title.label': 'Title', + 'BLOCK_NAME.title.placeholder': 'Give the target a name', + 'BLOCK_NAME.date.label': 'Start and end date', + 'BLOCK_NAME.placeholder.start': 'Start date', + 'BLOCK_NAME.placeholder.end': 'End date', + 'BLOCK_NAME.goal.label': 'Goal description', + 'BLOCK_NAME.goal.placeholder': 'Please enter your work goals', + 'BLOCK_NAME.standard.label': 'Metrics', + 'BLOCK_NAME.standard.placeholder': 'Please enter a metric', + 'BLOCK_NAME.client.label': 'Client', + 'BLOCK_NAME.label.tooltip': 'Target service object', + 'BLOCK_NAME.client.placeholder': + 'Please describe your customer service, internal customers directly @ Name / job number', + 'BLOCK_NAME.invites.label': 'Inviting critics', + 'BLOCK_NAME.invites.placeholder': 'Please direct @ Name / job number, you can invite up to 5 people', + 'BLOCK_NAME.weight.label': 'Weight', + 'BLOCK_NAME.weight.placeholder': 'Please enter weight', + 'BLOCK_NAME.public.label': 'Target disclosure', + 'BLOCK_NAME.label.help': 'Customers and invitees are shared by default', + 'BLOCK_NAME.radio.public': 'Public', + 'BLOCK_NAME.radio.partially-public': 'Partially public', + 'BLOCK_NAME.radio.private': 'Private', + 'BLOCK_NAME.publicUsers.placeholder': 'Open to', + 'BLOCK_NAME.option.A': 'Colleague A', + 'BLOCK_NAME.option.B': 'Colleague B', + 'BLOCK_NAME.option.C': 'Colleague C', + 'BLOCK_NAME.navBar.lang': 'Languages', +}; diff --git a/UserRegister/src/locales/zh-CN.js b/UserRegister/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..9018096f9d714fab461b743be6238b963a65b676 --- /dev/null +++ b/UserRegister/src/locales/zh-CN.js @@ -0,0 +1,74 @@ +export default { + 'BLOCK_NAME.login.userName': '用户名', + 'BLOCK_NAME.login.password': '密码', + 'BLOCK_NAME.login.message-invalid-credentials': '账户或密码错误(admin/ant.design)', + 'BLOCK_NAME.login.message-invalid-verification-code': '验证码错误', + 'BLOCK_NAME.login.tab-login-credentials': '账户密码登录', + 'BLOCK_NAME.login.tab-login-mobile': '手机号登录', + 'BLOCK_NAME.login.remember-me': '自动登录', + 'BLOCK_NAME.login.forgot-password': '忘记密码', + 'BLOCK_NAME.login.sign-in-with': '其他登录方式', + 'BLOCK_NAME.login.signup': '注册账户', + 'BLOCK_NAME.login.login': '登录', + 'BLOCK_NAME.register.register': '注册', + 'BLOCK_NAME.register.get-verification-code': '获取验证码', + 'BLOCK_NAME.register.sign-in': '使用已有账户登录', + 'BLOCK_NAME.register-result.msg': '你的账户:{email} 注册成功', + 'BLOCK_NAME.register-result.activation-email': + '激活邮件已发送到你的邮箱中,邮件有效期为24小时。请及时登录邮箱,点击邮件中的链接激活帐户。', + 'BLOCK_NAME.register-result.back-home': '返回首页', + 'BLOCK_NAME.register-result.view-mailbox': '查看邮箱', + 'BLOCK_NAME.email.required': '请输入邮箱地址!', + 'BLOCK_NAME.email.wrong-format': '邮箱地址格式错误!', + 'BLOCK_NAME.userName.required': '请输入用户名!', + 'BLOCK_NAME.password.required': '请输入密码!', + 'BLOCK_NAME.password.twice': '两次输入的密码不匹配!', + 'BLOCK_NAME.strength.msg': '请至少输入 6 个字符。请不要使用容易被猜到的密码。', + 'BLOCK_NAME.strength.strong': '强度:强', + 'BLOCK_NAME.strength.medium': '强度:中', + 'BLOCK_NAME.strength.short': '强度:太短', + 'BLOCK_NAME.confirm-password.required': '请确认密码!', + 'BLOCK_NAME.phone-number.required': '请输入手机号!', + 'BLOCK_NAME.phone-number.wrong-format': '手机号格式错误!', + 'BLOCK_NAME.verification-code.required': '请输入验证码!', + 'BLOCK_NAME.title.required': '请输入标题', + 'BLOCK_NAME.date.required': '请选择起止日期', + 'BLOCK_NAME.goal.required': '请输入目标描述', + 'BLOCK_NAME.standard.required': '请输入衡量标准', + 'BLOCK_NAME.form.get-captcha': '获取验证码', + 'BLOCK_NAME.captcha.second': '秒', + 'BLOCK_NAME.form.optional': '(选填)', + 'BLOCK_NAME.form.submit': '提交', + 'BLOCK_NAME.form.save': '保存', + 'BLOCK_NAME.email.placeholder': '邮箱', + 'BLOCK_NAME.password.placeholder': '至少6位密码,区分大小写', + 'BLOCK_NAME.confirm-password.placeholder': '确认密码', + 'BLOCK_NAME.phone-number.placeholder': '手机号', + 'BLOCK_NAME.verification-code.placeholder': '验证码', + 'BLOCK_NAME.title.label': '标题', + 'BLOCK_NAME.title.placeholder': '给目标起个名字', + 'BLOCK_NAME.date.label': '起止日期', + 'BLOCK_NAME.placeholder.start': '开始日期', + 'BLOCK_NAME.placeholder.end': '结束日期', + 'BLOCK_NAME.goal.label': '目标描述', + 'BLOCK_NAME.goal.placeholder': '请输入你的阶段性工作目标', + 'BLOCK_NAME.standard.label': '衡量标准', + 'BLOCK_NAME.standard.placeholder': '请输入衡量标准', + 'BLOCK_NAME.client.label': '客户', + 'BLOCK_NAME.label.tooltip': '目标的服务对象', + 'BLOCK_NAME.client.placeholder': '请描述你服务的客户,内部客户直接 @姓名/工号', + 'BLOCK_NAME.invites.label': '邀评人', + 'BLOCK_NAME.invites.placeholder': '请直接 @姓名/工号,最多可邀请 5 人', + 'BLOCK_NAME.weight.label': '权重', + 'BLOCK_NAME.weight.placeholder': '请输入', + 'BLOCK_NAME.public.label': '目标公开', + 'BLOCK_NAME.label.help': '客户、邀评人默认被分享', + 'BLOCK_NAME.radio.public': '公开', + 'BLOCK_NAME.radio.partially-public': '部分公开', + 'BLOCK_NAME.radio.private': '不公开', + 'BLOCK_NAME.publicUsers.placeholder': '公开给', + 'BLOCK_NAME.option.A': '同事甲', + 'BLOCK_NAME.option.B': '同事乙', + 'BLOCK_NAME.option.C': '同事丙', + 'BLOCK_NAME.navBar.lang': '语言', +}; diff --git a/UserRegister/src/locales/zh-TW.js b/UserRegister/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..f673d58c2d0336fcc37f6ba02d765048b96b9c1b --- /dev/null +++ b/UserRegister/src/locales/zh-TW.js @@ -0,0 +1,74 @@ +export default { + 'BLOCK_NAME.login.userName': '賬戶', + 'BLOCK_NAME.login.password': '密碼', + 'BLOCK_NAME.login.message-invalid-credentials': '賬戶或密碼錯誤(admin/ant.design)', + 'BLOCK_NAME.login.message-invalid-verification-code': '驗證碼錯誤', + 'BLOCK_NAME.login.tab-login-credentials': '賬戶密碼登錄', + 'BLOCK_NAME.login.tab-login-mobile': '手機號登錄', + 'BLOCK_NAME.login.remember-me': '自動登錄', + 'BLOCK_NAME.login.forgot-password': '忘記密碼', + 'BLOCK_NAME.login.sign-in-with': '其他登錄方式', + 'BLOCK_NAME.login.signup': '註冊賬戶', + 'BLOCK_NAME.login.login': '登錄', + 'BLOCK_NAME.register.register': '註冊', + 'BLOCK_NAME.register.get-verification-code': '獲取驗證碼', + 'BLOCK_NAME.register.sign-in': '使用已有賬戶登錄', + 'BLOCK_NAME.register-result.msg': '妳的賬戶:{email} 註冊成功', + 'BLOCK_NAME.register-result.activation-email': + '激活郵件已發送到妳的郵箱中,郵件有效期為24小時。請及時登錄郵箱,點擊郵件中的鏈接激活帳戶。', + 'BLOCK_NAME.register-result.back-home': '返回首頁', + 'BLOCK_NAME.register-result.view-mailbox': '查看郵箱', + 'BLOCK_NAME.email.required': '請輸入郵箱地址!', + 'BLOCK_NAME.email.wrong-format': '郵箱地址格式錯誤!', + 'BLOCK_NAME.userName.required': '請輸入賬戶!', + 'BLOCK_NAME.password.required': '請輸入密碼!', + 'BLOCK_NAME.password.twice': '兩次輸入的密碼不匹配!', + 'BLOCK_NAME.strength.msg': '請至少輸入 6 個字符。請不要使用容易被猜到的密碼。', + 'BLOCK_NAME.strength.strong': '強度:強', + 'BLOCK_NAME.strength.medium': '強度:中', + 'BLOCK_NAME.strength.short': '強度:太短', + 'BLOCK_NAME.confirm-password.required': '請確認密碼!', + 'BLOCK_NAME.phone-number.required': '請輸入手機號!', + 'BLOCK_NAME.phone-number.wrong-format': '手機號格式錯誤!', + 'BLOCK_NAME.verification-code.required': '請輸入驗證碼!', + 'BLOCK_NAME.title.required': '請輸入標題', + 'BLOCK_NAME.date.required': '請選擇起止日期', + 'BLOCK_NAME.goal.required': '請輸入目標描述', + 'BLOCK_NAME.standard.required': '請輸入衡量標淮', + 'BLOCK_NAME.form.get-captcha': '獲取驗證碼', + 'BLOCK_NAME.captcha.second': '秒', + 'BLOCK_NAME.form.optional': '(選填)', + 'BLOCK_NAME.form.submit': '提交', + 'BLOCK_NAME.form.save': '保存', + 'BLOCK_NAME.email.placeholder': '郵箱', + 'BLOCK_NAME.password.placeholder': '至少6位密碼,區分大小寫', + 'BLOCK_NAME.confirm-password.placeholder': '確認密碼', + 'BLOCK_NAME.phone-number.placeholder': '手機號', + 'BLOCK_NAME.verification-code.placeholder': '驗證碼', + 'BLOCK_NAME.title.label': '標題', + 'BLOCK_NAME.title.placeholder': '給目標起個名字', + 'BLOCK_NAME.date.label': '起止日期', + 'BLOCK_NAME.placeholder.start': '開始日期', + 'BLOCK_NAME.placeholder.end': '結束日期', + 'BLOCK_NAME.goal.label': '目標描述', + 'BLOCK_NAME.goal.placeholder': '請輸入妳的階段性工作目標', + 'BLOCK_NAME.standard.label': '衡量標淮', + 'BLOCK_NAME.standard.placeholder': '請輸入衡量標淮', + 'BLOCK_NAME.client.label': '客戶', + 'BLOCK_NAME.label.tooltip': '目標的服務對象', + 'BLOCK_NAME.client.placeholder': '請描述妳服務的客戶,內部客戶直接 @姓名/工號', + 'BLOCK_NAME.invites.label': '邀評人', + 'BLOCK_NAME.invites.placeholder': '請直接 @姓名/工號,最多可邀請 5 人', + 'BLOCK_NAME.weight.label': '權重', + 'BLOCK_NAME.weight.placeholder': '請輸入', + 'BLOCK_NAME.public.label': '目標公開', + 'BLOCK_NAME.label.help': '客戶、邀評人默認被分享', + 'BLOCK_NAME.radio.public': '公開', + 'BLOCK_NAME.radio.partially-public': '部分公開', + 'BLOCK_NAME.radio.private': '不公開', + 'BLOCK_NAME.publicUsers.placeholder': '公開給', + 'BLOCK_NAME.option.A': '同事甲', + 'BLOCK_NAME.option.B': '同事乙', + 'BLOCK_NAME.option.C': '同事丙', + 'BLOCK_NAME.navBar.lang': '語言', +}; diff --git a/src/pages/User/models/register.js b/UserRegister/src/model.js similarity index 64% rename from src/pages/User/models/register.js rename to UserRegister/src/model.js index a2901bbd5c1393503bc0663eeee50b073ef33a08..f65071ae09b12174d8e21b8ff882cefbd0e3fab9 100644 --- a/src/pages/User/models/register.js +++ b/UserRegister/src/model.js @@ -1,9 +1,7 @@ -import { fakeRegister } from '@/services/api'; -import { setAuthority } from '@/utils/authority'; -import { reloadAuthorized } from '@/utils/Authorized'; +import { fakeRegister } from './service'; export default { - namespace: 'register', + namespace: 'BLOCK_NAME_CAMEL_CASE', state: { status: undefined, @@ -21,8 +19,6 @@ export default { reducers: { registerHandle(state, { payload }) { - setAuthority('user'); - reloadAuthorized(); return { ...state, status: payload.status, diff --git a/UserRegister/src/service.js b/UserRegister/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..3a47fd11a5368cda67d9faf93f971de3bc3c8ede --- /dev/null +++ b/UserRegister/src/service.js @@ -0,0 +1,8 @@ +import request from 'umi-request'; + +export async function fakeRegister(params) { + return request('/api/BLOCK_NAME/register', { + method: 'POST', + data: params, + }); +} diff --git a/src/pages/User/Register.less b/UserRegister/src/style.less similarity index 100% rename from src/pages/User/Register.less rename to UserRegister/src/style.less diff --git a/UserRegisterResult/.gitignore b/UserRegisterResult/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/UserRegisterResult/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/UserRegisterResult/.umirc.js b/UserRegisterResult/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..ccfbb4565c8302b483ff1976dbc1ffb158929bd2 --- /dev/null +++ b/UserRegisterResult/.umirc.js @@ -0,0 +1,18 @@ +export default { + plugins: [ + [ + 'umi-plugin-block-dev', + { + layout: 'ant-design-pro-user', + }, + ], + [ + 'umi-plugin-react', + { + dva: true, + locale: true, + antd: true, + }, + ], + ], +}; diff --git a/UserRegisterResult/README.md b/UserRegisterResult/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f10f3eb6df4de1b9f1a55e80654ef04e01237976 --- /dev/null +++ b/UserRegisterResult/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/userregisterresult + +UserRegisterResult + +## Usage + +```sh +umi block add ant-design-pro/UserRegisterResult +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/UserRegisterResult/package.json b/UserRegisterResult/package.json new file mode 100644 index 0000000000000000000000000000000000000000..afdefc4fae8ad383f272007bbd1f91811bb58f1a --- /dev/null +++ b/UserRegisterResult/package.json @@ -0,0 +1,24 @@ +{ + "name": "@umi-block/user-register-result", + "version": "0.0.1", + "description": "UserRegisterResult", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/userregisterresult" + }, + "dependencies": { + "react": "^16.6.3", + "antd": "^3.10.9", + "ant-design-pro": "^2.1.1" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-react": "^1.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0" + }, + "license": "MIT" +} diff --git a/UserRegisterResult/snapshot.png b/UserRegisterResult/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..0115bbb36fb921dae156e3fa3b4bf9f25828b9d4 Binary files /dev/null and b/UserRegisterResult/snapshot.png differ diff --git a/src/pages/User/RegisterResult.js b/UserRegisterResult/src/index.js similarity index 60% rename from src/pages/User/RegisterResult.js rename to UserRegisterResult/src/index.js index 6e338b277b917cd3d23c3b883f7c710ec306018c..3a3425323619a8e717b44138446b50bf26326103 100644 --- a/src/pages/User/RegisterResult.js +++ b/UserRegisterResult/src/index.js @@ -2,40 +2,40 @@ import React from 'react'; import { formatMessage, FormattedMessage } from 'umi/locale'; import { Button } from 'antd'; import Link from 'umi/link'; -import Result from '@/components/Result'; -import styles from './RegisterResult.less'; +import { Result } from 'ant-design-pro'; +import styles from './style.less'; const actions = ( - + - + ); -const RegisterResult = ({ location }) => ( +const PAGE_NAME_UPPER_CAMEL_CASE = ({ location }) => ( } - description={formatMessage({ id: 'app.register-result.activation-email' })} + description={formatMessage({ id: 'BLOCK_NAME.register-result.activation-email' })} actions={actions} style={{ marginTop: 56 }} /> ); -export default RegisterResult; +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/UserRegisterResult/src/locales/en-US.js b/UserRegisterResult/src/locales/en-US.js new file mode 100644 index 0000000000000000000000000000000000000000..471776cabd4973d06ed5abae3db1de8b8ec0a015 --- /dev/null +++ b/UserRegisterResult/src/locales/en-US.js @@ -0,0 +1,22 @@ +export default { + 'BLOCK_NAME.login.userName': 'userName', + 'BLOCK_NAME.login.password': 'password', + 'BLOCK_NAME.login.message-invalid-credentials': 'Invalid username or password(admin/ant.design)', + 'BLOCK_NAME.login.message-invalid-verification-code': 'Invalid verification code', + 'BLOCK_NAME.login.tab-login-credentials': 'Credentials', + 'BLOCK_NAME.login.tab-login-mobile': 'Mobile number', + 'BLOCK_NAME.login.remember-me': 'Remember me', + 'BLOCK_NAME.login.forgot-password': 'Forgot your password?', + 'BLOCK_NAME.login.sign-in-with': 'Sign in with', + 'BLOCK_NAME.login.signup': 'Sign up', + 'BLOCK_NAME.login.login': 'Login', + 'BLOCK_NAME.register.register': 'Register', + 'BLOCK_NAME.register.get-verification-code': 'Get code', + 'BLOCK_NAME.register.sign-in': 'Already have an account?', + 'BLOCK_NAME.register-result.msg': 'Account:registered at {email}', + 'BLOCK_NAME.register-result.activation-email': + 'The activation email has been sent to your email address and is valid for 24 hours. Please log in to the email in time and click on the link in the email to activate the account.', + 'BLOCK_NAME.register-result.back-home': 'Back to home', + 'BLOCK_NAME.register-result.view-mailbox': 'View mailbox', + 'BLOCK_NAME.navBar.lang': 'Languages', +}; diff --git a/UserRegisterResult/src/locales/zh-CN.js b/UserRegisterResult/src/locales/zh-CN.js new file mode 100644 index 0000000000000000000000000000000000000000..2dc5753ecfc2b8157826bf0c30d2b90156c8fc3d --- /dev/null +++ b/UserRegisterResult/src/locales/zh-CN.js @@ -0,0 +1,22 @@ +export default { + 'BLOCK_NAME.login.userName': '用户名', + 'BLOCK_NAME.login.password': '密码', + 'BLOCK_NAME.login.message-invalid-credentials': '账户或密码错误(admin/ant.design)', + 'BLOCK_NAME.login.message-invalid-verification-code': '验证码错误', + 'BLOCK_NAME.login.tab-login-credentials': '账户密码登录', + 'BLOCK_NAME.login.tab-login-mobile': '手机号登录', + 'BLOCK_NAME.login.remember-me': '自动登录', + 'BLOCK_NAME.login.forgot-password': '忘记密码', + 'BLOCK_NAME.login.sign-in-with': '其他登录方式', + 'BLOCK_NAME.login.signup': '注册账户', + 'BLOCK_NAME.login.login': '登录', + 'BLOCK_NAME.register.register': '注册', + 'BLOCK_NAME.register.get-verification-code': '获取验证码', + 'BLOCK_NAME.register.sign-in': '使用已有账户登录', + 'BLOCK_NAME.register-result.msg': '你的账户:{email} 注册成功', + 'BLOCK_NAME.register-result.activation-email': + '激活邮件已发送到你的邮箱中,邮件有效期为24小时。请及时登录邮箱,点击邮件中的链接激活帐户。', + 'BLOCK_NAME.register-result.back-home': '返回首页', + 'BLOCK_NAME.register-result.view-mailbox': '查看邮箱', + 'BLOCK_NAME.navBar.lang': '语言', +}; diff --git a/UserRegisterResult/src/locales/zh-TW.js b/UserRegisterResult/src/locales/zh-TW.js new file mode 100644 index 0000000000000000000000000000000000000000..945ade4aa20f7bdf1d50d3db3587a5b1118bf60b --- /dev/null +++ b/UserRegisterResult/src/locales/zh-TW.js @@ -0,0 +1,22 @@ +export default { + 'BLOCK_NAME.login.userName': '賬戶', + 'BLOCK_NAME.login.password': '密碼', + 'BLOCK_NAME.login.message-invalid-credentials': '賬戶或密碼錯誤(admin/ant.design)', + 'BLOCK_NAME.login.message-invalid-verification-code': '驗證碼錯誤', + 'BLOCK_NAME.login.tab-login-credentials': '賬戶密碼登錄', + 'BLOCK_NAME.login.tab-login-mobile': '手機號登錄', + 'BLOCK_NAME.login.remember-me': '自動登錄', + 'BLOCK_NAME.login.forgot-password': '忘記密碼', + 'BLOCK_NAME.login.sign-in-with': '其他登錄方式', + 'BLOCK_NAME.login.signup': '註冊賬戶', + 'BLOCK_NAME.login.login': '登錄', + 'BLOCK_NAME.register.register': '註冊', + 'BLOCK_NAME.register.get-verification-code': '獲取驗證碼', + 'BLOCK_NAME.register.sign-in': '使用已有賬戶登錄', + 'BLOCK_NAME.register-result.msg': '妳的賬戶:{email} 註冊成功', + 'BLOCK_NAME.register-result.activation-email': + '激活郵件已發送到妳的郵箱中,郵件有效期為24小時。請及時登錄郵箱,點擊郵件中的鏈接激活帳戶。', + 'BLOCK_NAME.register-result.back-home': '返回首頁', + 'BLOCK_NAME.register-result.view-mailbox': '查看郵箱', + 'BLOCK_NAME.navBar.lang': '語言', +}; diff --git a/src/pages/User/RegisterResult.less b/UserRegisterResult/src/style.less similarity index 100% rename from src/pages/User/RegisterResult.less rename to UserRegisterResult/src/style.less diff --git a/Workplace/.gitignore b/Workplace/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8ce76bc425533aa85835a516e25a0d7218a6e15b --- /dev/null +++ b/Workplace/.gitignore @@ -0,0 +1,7 @@ +/yarn.lock +/package-lock.json +/dist +/node_modules + +.umi +.umi-production diff --git a/Workplace/.umirc.js b/Workplace/.umirc.js new file mode 100644 index 0000000000000000000000000000000000000000..d85d9819c2767f6c90c44aa787703a23475c4b01 --- /dev/null +++ b/Workplace/.umirc.js @@ -0,0 +1,12 @@ +export default { + plugins: [ + ['umi-plugin-block-dev', { + layout: 'ant-design-pro', + }], + ['umi-plugin-react', { + dva: true, + locale: true, + antd: true, + }], + ], +}; diff --git a/Workplace/README.md b/Workplace/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d2f6e5857a27d75efb334666e2ce4dd8e50ceebd --- /dev/null +++ b/Workplace/README.md @@ -0,0 +1,17 @@ +# @umi-blocks/ant-design-pro/workplace + +Workplace + +## Usage + +```sh +umi block add ant-design-pro/Workplace +``` + +## SNAPSHOT + + + +## LICENSE + +MIT diff --git a/Workplace/package.json b/Workplace/package.json new file mode 100644 index 0000000000000000000000000000000000000000..e44affb11638eb102f6ceca2eed0b27cfb98cde7 --- /dev/null +++ b/Workplace/package.json @@ -0,0 +1,28 @@ +{ + "name": "@umi-block/workplace", + "version": "0.0.1", + "description": "Workplace", + "main": "src/index.js", + "scripts": { + "dev": "umi dev" + }, + "repository": { + "type": "git", + "url": "https://github.com/umijs/umi-blocks/ant-design-pro/workplace" + }, + "dependencies": { + "ant-design-pro": "^2.1.1", + "antd": "^3.10.9", + "dva": "^2.4.0", + "moment": "^2.22.2", + "prop-types": "^15.5.10", + "react": "^16.6.3", + "umi-request": "^1.0.0" + }, + "devDependencies": { + "umi": "^2.3.0-beta.1", + "umi-plugin-block-dev": "^1.0.0", + "umi-plugin-react": "^1.3.0-beta.1" + }, + "license": "MIT" +} diff --git a/Workplace/snapshot.png b/Workplace/snapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..9e870a3a150b7d4774dcd5785f3aa2d4f99c7a94 Binary files /dev/null and b/Workplace/snapshot.png differ diff --git a/mock/api.js b/Workplace/src/_mock.js similarity index 54% rename from mock/api.js rename to Workplace/src/_mock.js index f1173bba91a8194731444a05d015f3bfdf00ee23..16c0597f10f07531f5a801dc6f818282dd05b4cf 100644 --- a/mock/api.js +++ b/Workplace/src/_mock.js @@ -1,5 +1,3 @@ -import mockjs from 'mockjs'; - const titles = [ 'Alipay', 'Angular', @@ -34,125 +32,6 @@ const avatars2 = [ 'https://gw.alipayobjects.com/zos/rmsportal/UrQsqscbKEpNuJcvBZBu.png', ]; -const covers = [ - 'https://gw.alipayobjects.com/zos/rmsportal/uMfMFlvUuceEyPpotzlq.png', - 'https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png', - 'https://gw.alipayobjects.com/zos/rmsportal/iXjVmWVHbCJAyqvDxdtx.png', - 'https://gw.alipayobjects.com/zos/rmsportal/gLaIAoVWTtLbBWZNYEMg.png', -]; -const desc = [ - '那是一种内在的东西, 他们到达不了,也无法触及的', - '希望是一个好东西,也许是最好的,好东西是不会消亡的', - '生命就像一盒巧克力,结果往往出人意料', - '城镇中有那么多的酒馆,她却偏偏走进了我的酒馆', - '那时候我只会想自己想要什么,从不想自己拥有什么', -]; - -const user = [ - '付小小', - '曲丽丽', - '林东东', - '周星星', - '吴加好', - '朱偏右', - '鱼酱', - '乐哥', - '谭小仪', - '仲尼', -]; - -function fakeList(count) { - const list = []; - for (let i = 0; i < count; i += 1) { - list.push({ - id: `fake-list-${i}`, - owner: user[i % 10], - title: titles[i % 8], - avatar: avatars[i % 8], - cover: parseInt(i / 4, 10) % 2 === 0 ? covers[i % 4] : covers[3 - (i % 4)], - status: ['active', 'exception', 'normal'][i % 3], - percent: Math.ceil(Math.random() * 50) + 50, - logo: avatars[i % 8], - href: 'https://ant.design', - updatedAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i), - createdAt: new Date(new Date().getTime() - 1000 * 60 * 60 * 2 * i), - subDescription: desc[i % 5], - description: - '在中台产品的研发过程中,会出现不同的设计规范和实现方式,但其中往往存在很多类似的页面和组件,这些类似的组件会被抽离成一套标准规范。', - activeUser: Math.ceil(Math.random() * 100000) + 100000, - newUser: Math.ceil(Math.random() * 1000) + 1000, - star: Math.ceil(Math.random() * 100) + 100, - like: Math.ceil(Math.random() * 100) + 100, - message: Math.ceil(Math.random() * 10) + 10, - content: - '段落示意:蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。', - members: [ - { - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png', - name: '曲丽丽', - id: 'member1', - }, - { - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png', - name: '王昭君', - id: 'member2', - }, - { - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png', - name: '董娜娜', - id: 'member3', - }, - ], - }); - } - - return list; -} - -let sourceData; - -function getFakeList(req, res) { - const params = req.query; - - const count = params.count * 1 || 20; - - const result = fakeList(count); - sourceData = result; - return res.json(result); -} - -function postFakeList(req, res) { - const { /* url = '', */ body } = req; - // const params = getUrlParams(url); - const { method, id } = body; - // const count = (params.count * 1) || 20; - let result = sourceData; - - switch (method) { - case 'delete': - result = result.filter(item => item.id !== id); - break; - case 'update': - result.forEach((item, i) => { - if (item.id === id) { - result[i] = Object.assign(item, body); - } - }); - break; - case 'post': - result.unshift({ - body, - id: `fake-list-${result.length}`, - createdAt: new Date().getTime(), - }); - break; - default: - break; - } - - return res.json(result); -} - const getNotice = [ { id: 'xxx1', @@ -317,20 +196,108 @@ const getActivities = [ }, ]; -function getFakeCaptcha(req, res) { - return res.json('captcha-xxx'); -} +const radarOriginData = [ + { + name: '个人', + ref: 10, + koubei: 8, + output: 4, + contribute: 5, + hot: 7, + }, + { + name: '团队', + ref: 3, + koubei: 9, + output: 6, + contribute: 3, + hot: 1, + }, + { + name: '部门', + ref: 4, + koubei: 1, + output: 6, + contribute: 5, + hot: 7, + }, +]; + +const radarData = []; +const radarTitleMap = { + ref: '引用', + koubei: '口碑', + output: '产量', + contribute: '贡献', + hot: '热度', +}; +radarOriginData.forEach(item => { + Object.keys(item).forEach(key => { + if (key !== 'name') { + radarData.push({ + name: item.name, + label: radarTitleMap[key], + value: item[key], + }); + } + }); +}); export default { - 'GET /api/project/notice': getNotice, - 'GET /api/activities': getActivities, - 'POST /api/forms': (req, res) => { - res.send({ message: 'Ok' }); + 'GET /api/BLOCK_NAME/project/notice': getNotice, + 'GET /api/BLOCK_NAME/activities': getActivities, + 'GET /api/BLOCK_NAME/fake_chart_data': { + radarData, + }, + + 'GET /api/BLOCK_NAME/currentUser': { + name: 'Serati Ma', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png', + userid: '00000001', + email: 'antdesign@alipay.com', + signature: '海纳百川,有容乃大', + title: '交互专家', + group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED', + tags: [ + { + key: '0', + label: '很有想法的', + }, + { + key: '1', + label: '专注设计', + }, + { + key: '2', + label: '辣~', + }, + { + key: '3', + label: '大长腿', + }, + { + key: '4', + label: '川妹子', + }, + { + key: '5', + label: '海纳百川', + }, + ], + notifyCount: 12, + unreadCount: 11, + country: 'China', + geographic: { + province: { + label: '浙江省', + key: '330000', + }, + city: { + label: '杭州市', + key: '330100', + }, + }, + address: '西湖区工专路 77 号', + phone: '0752-268888888', }, - 'GET /api/tags': mockjs.mock({ - 'list|100': [{ name: '@city', 'value|1-100': 150, 'type|0-2': 1 }], - }), - 'GET /api/fake_list': getFakeList, - 'POST /api/fake_list': postFakeList, - 'GET /api/captcha': getFakeCaptcha, }; diff --git a/src/components/EditableLinkGroup/index.js b/Workplace/src/components/EditableLinkGroup/index.js similarity index 100% rename from src/components/EditableLinkGroup/index.js rename to Workplace/src/components/EditableLinkGroup/index.js diff --git a/src/components/EditableLinkGroup/index.less b/Workplace/src/components/EditableLinkGroup/index.less similarity index 100% rename from src/components/EditableLinkGroup/index.less rename to Workplace/src/components/EditableLinkGroup/index.less diff --git a/Workplace/src/components/PageHeaderWrapper/index.js b/Workplace/src/components/PageHeaderWrapper/index.js new file mode 100644 index 0000000000000000000000000000000000000000..db0daf4548eba34c349391fb3f099aea3646e841 --- /dev/null +++ b/Workplace/src/components/PageHeaderWrapper/index.js @@ -0,0 +1,26 @@ +import React from 'react'; +import { FormattedMessage } from 'umi/locale'; +import Link from 'umi/link'; +import { PageHeader } from 'ant-design-pro'; +import styles from './index.less'; + +const PageHeaderWrapper = ({ children, contentWidth, wrapperClassName, ...restProps }) => ( + + } + key="pageheader" + {...restProps} + linkElement={Link} + itemRender={item => { + if (item.locale) { + return ; + } + return item.title; + }} + /> + {children ? {children} : null} + +); + +export default PageHeaderWrapper; diff --git a/Workplace/src/components/PageHeaderWrapper/index.less b/Workplace/src/components/PageHeaderWrapper/index.less new file mode 100644 index 0000000000000000000000000000000000000000..39a449657a98b039c29e6654fd117267cbb5283a --- /dev/null +++ b/Workplace/src/components/PageHeaderWrapper/index.less @@ -0,0 +1,11 @@ +@import '~antd/lib/style/themes/default.less'; + +.content { + margin: 24px 24px 0; +} + +@media screen and (max-width: @screen-sm) { + .content { + margin: 24px 0 0; + } +} diff --git a/src/pages/Dashboard/Workplace.js b/Workplace/src/index.js similarity index 89% rename from src/pages/Dashboard/Workplace.js rename to Workplace/src/index.js index e9e44d4583c317615af21dbe623530a5f029f340..91cd597c79a3b117bf3c9c8e481dd70745b7eb27 100644 --- a/src/pages/Dashboard/Workplace.js +++ b/Workplace/src/index.js @@ -4,11 +4,13 @@ import { connect } from 'dva'; import Link from 'umi/link'; import { Row, Col, Card, List, Avatar } from 'antd'; -import { Radar } from '@/components/Charts'; -import EditableLinkGroup from '@/components/EditableLinkGroup'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; +import { Charts } from 'ant-design-pro'; +import EditableLinkGroup from './components/EditableLinkGroup'; +import PageHeaderWrapper from './components/PageHeaderWrapper'; -import styles from './Workplace.less'; +import styles from './style.less'; + +const { Radar } = Charts; const links = [ { @@ -37,36 +39,27 @@ const links = [ }, ]; -@connect(({ user, project, activities, chart, loading }) => ({ +@connect(({ BLOCK_NAME_CAMEL_CASE: { user, project, activities, chart }, loading }) => ({ currentUser: user.currentUser, project, activities, chart, - currentUserLoading: loading.effects['user/fetchCurrent'], - projectLoading: loading.effects['project/fetchNotice'], - activitiesLoading: loading.effects['activities/fetchList'], + currentUserLoading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchUserCurrent'], + projectLoading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchProjectNotice'], + activitiesLoading: loading.effects['BLOCK_NAME_CAMEL_CASE/fetchActivitiesList'], })) -class Workplace extends PureComponent { +class PAGE_NAME_UPPER_CAMEL_CASE extends PureComponent { componentDidMount() { const { dispatch } = this.props; dispatch({ - type: 'user/fetchCurrent', - }); - dispatch({ - type: 'project/fetchNotice', - }); - dispatch({ - type: 'activities/fetchList', - }); - dispatch({ - type: 'chart/fetch', + type: 'BLOCK_NAME_CAMEL_CASE/init', }); } componentWillUnmount() { const { dispatch } = this.props; dispatch({ - type: 'chart/clear', + type: 'BLOCK_NAME_CAMEL_CASE/clear', }); } @@ -253,4 +246,4 @@ class Workplace extends PureComponent { } } -export default Workplace; +export default PAGE_NAME_UPPER_CAMEL_CASE; diff --git a/Workplace/src/model.js b/Workplace/src/model.js new file mode 100644 index 0000000000000000000000000000000000000000..0d19862f7f74bed3115b92e6413ff2ad2825aec9 --- /dev/null +++ b/Workplace/src/model.js @@ -0,0 +1,116 @@ +import { queryCurrent, queryProjectNotice, queryActivities, fakeChartData } from './service'; + +export default { + namespace: 'BLOCK_NAME_CAMEL_CASE', + state: { + user: { + currentUser: {}, + }, + project: { + notice: [], + }, + activities: { + list: [], + }, + chart: { + visitData: [], + visitData2: [], + salesData: [], + searchData: [], + offlineData: [], + offlineChartData: [], + salesTypeData: [], + salesTypeDataOnline: [], + salesTypeDataOffline: [], + radarData: [], + loading: false, + }, + }, + reducers: { + saveCurrentUser(state, action) { + return { + ...state, + user: { + currentUser: action.payload || {}, + }, + }; + }, + saveNotice(state, action) { + return { + ...state, + project: { + notice: action.payload, + }, + }; + }, + saveList(state, action) { + return { + ...state, + activities: { + list: action.payload, + }, + }; + }, + saveChart(state, { payload }) { + return { + ...state, + chart: { + ...payload, + }, + }; + }, + clear(state) { + return { + ...state, + chart: { + visitData: [], + visitData2: [], + salesData: [], + searchData: [], + offlineData: [], + offlineChartData: [], + salesTypeData: [], + salesTypeDataOnline: [], + salesTypeDataOffline: [], + radarData: [], + }, + }; + }, + }, + effects: { + *init(_, { put }) { + yield put({ type: 'fetchUserCurrent' }); + yield put({ type: 'fetchProjectNotice' }); + yield put({ type: 'fetchActivitiesList' }); + yield put({ type: 'fetchChart' }); + }, + *fetchUserCurrent(_, { call, put }) { + const response = yield call(queryCurrent); + yield put({ + type: 'saveCurrentUser', + payload: response, + }); + }, + *fetchProjectNotice(_, { call, put }) { + const response = yield call(queryProjectNotice); + yield put({ + type: 'saveNotice', + payload: Array.isArray(response) ? response : [], + }); + }, + *fetchActivitiesList(_, { call, put }) { + const response = yield call(queryActivities); + yield put({ + type: 'saveList', + payload: Array.isArray(response) ? response : [], + }); + }, + *fetchChart(_, { call, put }) { + const response = yield call(fakeChartData); + yield put({ + type: 'saveChart', + payload: response, + }); + }, + }, +}; diff --git a/Workplace/src/service.js b/Workplace/src/service.js new file mode 100644 index 0000000000000000000000000000000000000000..a27f7b6ed55b8c35d33acda43599cf28e96cc3a7 --- /dev/null +++ b/Workplace/src/service.js @@ -0,0 +1,17 @@ +import request from 'umi-request'; + +export async function queryProjectNotice() { + return request('/api/BLOCK_NAME/project/notice'); +} + +export async function queryActivities() { + return request('/api/BLOCK_NAME/activities'); +} + +export async function fakeChartData() { + return request('/api/BLOCK_NAME/fake_chart_data'); +} + +export async function queryCurrent() { + return request('/api/BLOCK_NAME/currentUser'); +} diff --git a/src/pages/Dashboard/Workplace.less b/Workplace/src/style.less similarity index 99% rename from src/pages/Dashboard/Workplace.less rename to Workplace/src/style.less index 038017112f79467c737c87da0f83f203caffb63f..3a33d47650db953c642af44e4b387a6649ec88be 100644 --- a/src/pages/Dashboard/Workplace.less +++ b/Workplace/src/style.less @@ -1,5 +1,5 @@ @import '~antd/lib/style/themes/default.less'; -@import '~@/utils/utils.less'; +@import './utils.less'; .activitiesList { padding: 0 24px 8px 24px; diff --git a/Workplace/src/utils.less b/Workplace/src/utils.less new file mode 100644 index 0000000000000000000000000000000000000000..725792252787f49efba4f4e887301195a9818f3f --- /dev/null +++ b/Workplace/src/utils.less @@ -0,0 +1,50 @@ +.textOverflow() { + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + white-space: nowrap; +} + +.textOverflowMulti(@line: 3, @bg: #fff) { + overflow: hidden; + position: relative; + line-height: 1.5em; + max-height: @line * 1.5em; + text-align: justify; + margin-right: -1em; + padding-right: 1em; + &:before { + background: @bg; + content: '...'; + padding: 0 1px; + position: absolute; + right: 14px; + bottom: 0; + } + &:after { + background: white; + content: ''; + margin-top: 0.2em; + position: absolute; + right: 14px; + width: 1em; + height: 1em; + } +} + +// mixins for clearfix +// ------------------------ +.clearfix() { + zoom: 1; + &:before, + &:after { + content: ' '; + display: table; + } + &:after { + clear: both; + visibility: hidden; + font-size: 0; + height: 0; + } +} diff --git a/_scripts/lint-prettier.js b/_scripts/lint-prettier.js new file mode 100644 index 0000000000000000000000000000000000000000..c64db7575a0bdc5ee6b27c1595950c13617d87ff --- /dev/null +++ b/_scripts/lint-prettier.js @@ -0,0 +1,46 @@ +/** + * copy to https://github.com/facebook/react/blob/master/scripts/prettier/index.js + * prettier api doc https://prettier.io/docs/en/api.html + *----------*****-------------- + * lint file is prettier + *----------*****-------------- + */ + +const prettier = require('prettier'); +const fs = require('fs'); + +const prettierConfigPath = require.resolve('../.prettierrc'); + +const files = process.argv.slice(2); + +let didError = false; +let didWarn = false; + +files.forEach(file => { + const options = prettier.resolveConfig.sync(file, { + config: prettierConfigPath, + }); + try { + const fileInfo = prettier.getFileInfo.sync(file); + if (fileInfo.ignored) { + return; + } + const input = fs.readFileSync(file, 'utf8'); + const withParserOptions = { + ...options, + parser: fileInfo.inferredParser, + }; + const isPrettier = prettier.check(input, withParserOptions); + if (!isPrettier) { + console.log(`\x1b[31m ${file} is no prettier, please use npm run prettier and git add !\x1b[0m`); + didWarn = true; + } + } catch (e) { + didError = true; + } +}); + +if (didWarn || didError) { + process.exit(1); +} +console.log('\x1b[32m lint prettier success!\x1b[0m'); diff --git a/scripts/prettier.js b/_scripts/prettier.js similarity index 68% rename from scripts/prettier.js rename to _scripts/prettier.js index 17ded6c500f4233ae5e998d0535992617f82e666..d42fa0edb4e2cfe522d72fec77d85817065b2ae6 100644 --- a/scripts/prettier.js +++ b/_scripts/prettier.js @@ -6,15 +6,26 @@ *----------*****-------------- */ +const glob = require('glob'); const prettier = require('prettier'); const fs = require('fs'); -const getPrettierFiles = require('./getPrettierFiles'); + const prettierConfigPath = require.resolve('../.prettierrc'); -const chalk = require('chalk'); let didError = false; -const files = getPrettierFiles(); +let files = []; +const jsFiles = glob.sync('ant-design-pro/**/*.js*', { + ignore: ['**/node_modules/**', 'build/**'], +}); +const tsFiles = glob.sync('ant-design-pro/**/*.ts*', { + ignore: ['**/node_modules/**', 'build/**'], +}); +files = files.concat(jsFiles); +files = files.concat(tsFiles); +if (!files.length) { + return; +} files.forEach(file => { const options = prettier.resolveConfig.sync(file, { @@ -33,7 +44,7 @@ files.forEach(file => { const output = prettier.format(input, withParserOptions); if (output !== input) { fs.writeFileSync(file, output, 'utf8'); - console.log(chalk.green(`${file} is prettier`)); + console.log(`\x1b[34m ${file} is prettier`); } } catch (e) { didError = true; @@ -43,4 +54,4 @@ files.forEach(file => { if (didError) { process.exit(1); } -console.log(chalk.hex('#1890FF')('prettier success!')); +console.log('\x1b[32m prettier success!'); diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index f2ffbbd45be5d8715f1d7d67d1100e8702557d93..0000000000000000000000000000000000000000 --- a/appveyor.yml +++ /dev/null @@ -1,26 +0,0 @@ -# Test against the latest version of this Node.js version -environment: - nodejs_version: '10' - -# this is how to allow failing jobs in the matrix -matrix: - fast_finish: true # set this flag to immediately finish build once one of the jobs fails. - -# Install scripts. (runs after repo cloning) -install: - # Get the latest stable version of Node.js or io.js - - ps: Install-Product node $env:nodejs_version - # install modules - - npm install - # Output useful info for debugging. - - node --version - - npm --version - -# Post-install test scripts. -test_script: - - npm run lint - - npm run test:all - - npm run build - -# Don't actually build. -build: off diff --git a/config/config.js b/config/config.js deleted file mode 100644 index 887b06141eb5c952335a583a8821b351f5112aee..0000000000000000000000000000000000000000 --- a/config/config.js +++ /dev/null @@ -1,114 +0,0 @@ -// https://umijs.org/config/ -import os from 'os'; -import pageRoutes from './router.config'; -import webpackPlugin from './plugin.config'; -import defaultSettings from '../src/defaultSettings'; -import slash from 'slash2'; - -const plugins = [ - [ - 'umi-plugin-react', - { - antd: true, - dva: { - hmr: true, - }, - locale: { - enable: true, // default false - default: 'zh-CN', // default zh-CN - baseNavigator: true, // default true, when it is true, will use `navigator.language` overwrite default - }, - dynamicImport: { - loadingComponent: './components/PageLoading/index', - webpackChunkName: true, - }, - pwa: { - workboxPluginMode: 'InjectManifest', - workboxOptions: { - importWorkboxFrom: 'local', - }, - }, - ...(!process.env.TEST && os.platform() === 'darwin' - ? { - dll: { - include: ['dva', 'dva/router', 'dva/saga', 'dva/fetch'], - exclude: ['@babel/runtime'], - }, - hardSource: false, - } - : {}), - }, - ], -]; - -// 针对 preview.pro.ant.design 的 GA 统计代码 -// 业务上不需要这个 -if (process.env.APP_TYPE === 'site') { - plugins.push([ - 'umi-plugin-ga', - { - code: 'UA-72788897-6', - }, - ]); -} - -export default { - // add for transfer to umi - plugins, - define: { - APP_TYPE: process.env.APP_TYPE || '', - }, - treeShaking: true, - targets: { - ie: 11, - }, - // 路由配置 - routes: pageRoutes, - // Theme for antd - // https://ant.design/docs/react/customize-theme-cn - theme: { - 'primary-color': defaultSettings.primaryColor, - }, - externals: { - '@antv/data-set': 'DataSet', - }, - // proxy: { - // '/server/api/': { - // target: 'https://preview.pro.ant.design/', - // changeOrigin: true, - // pathRewrite: { '^/server': '' }, - // }, - // }, - ignoreMomentLocale: true, - lessLoaderOptions: { - javascriptEnabled: true, - }, - disableRedirectHoist: true, - cssLoaderOptions: { - modules: true, - getLocalIdent: (context, localIdentName, localName) => { - if ( - context.resourcePath.includes('node_modules') || - context.resourcePath.includes('ant.design.pro.less') || - context.resourcePath.includes('global.less') - ) { - return localName; - } - const match = context.resourcePath.match(/src(.*)/); - if (match && match[1]) { - const antdProPath = match[1].replace('.less', ''); - const arr = slash(antdProPath) - .split('/') - .map(a => a.replace(/([A-Z])/g, '-$1')) - .map(a => a.toLowerCase()); - return `antd-pro${arr.join('-')}-${localName}`.replace(/--/g, '-'); - } - return localName; - }, - }, - manifest: { - basePath: '/', - }, - - chainWebpack: webpackPlugin, -}; diff --git a/config/plugin.config.js b/config/plugin.config.js deleted file mode 100644 index b9e842d26a900cceb0880b75c3e5c7489cb0c81f..0000000000000000000000000000000000000000 --- a/config/plugin.config.js +++ /dev/null @@ -1,33 +0,0 @@ -// Change theme plugin - -import MergeLessPlugin from 'antd-pro-merge-less'; -import AntDesignThemePlugin from 'antd-theme-webpack-plugin'; -import path from 'path'; - -export default config => { - // pro 和 开发环境再添加这个插件 - if (process.env.APP_TYPE === 'site' || process.env.NODE_ENV !== 'production') { - // 将所有 less 合并为一个供 themePlugin使用 - const outFile = path.join(__dirname, '../.temp/ant-design-pro.less'); - const stylesDir = path.join(__dirname, '../src/'); - - config.plugin('merge-less').use(MergeLessPlugin, [ - { - stylesDir, - outFile, - }, - ]); - - config.plugin('ant-design-theme').use(AntDesignThemePlugin, [ - { - antDir: path.join(__dirname, '../node_modules/antd'), - stylesDir, - varFile: path.join(__dirname, '../node_modules/antd/lib/style/themes/default.less'), - mainLessFile: outFile, // themeVariables: ['@primary-color'], - indexFileName: 'index.html', - generateOne: true, - lessUrl: 'https://gw.alipayobjects.com/os/lib/less.js/3.8.1/less.min.js', - }, - ]); - } -}; diff --git a/config/router.config.js b/config/router.config.js deleted file mode 100644 index 656027d2371af19355c63eb2e989c8cefe306ffe..0000000000000000000000000000000000000000 --- a/config/router.config.js +++ /dev/null @@ -1,263 +0,0 @@ -export default [ - // user - { - path: '/user', - component: '../layouts/UserLayout', - routes: [ - { path: '/user', redirect: '/user/login' }, - { path: '/user/login', component: './User/Login' }, - { path: '/user/register', component: './User/Register' }, - { path: '/user/register-result', component: './User/RegisterResult' }, - ], - }, - // app - { - path: '/', - component: '../layouts/BasicLayout', - Routes: ['src/pages/Authorized'], - authority: ['admin', 'user'], - routes: [ - // dashboard - { path: '/', redirect: '/dashboard/analysis' }, - { - path: '/dashboard', - name: 'dashboard', - icon: 'dashboard', - routes: [ - { - path: '/dashboard/analysis', - name: 'analysis', - component: './Dashboard/Analysis', - }, - { - path: '/dashboard/monitor', - name: 'monitor', - component: './Dashboard/Monitor', - }, - { - path: '/dashboard/workplace', - name: 'workplace', - component: './Dashboard/Workplace', - }, - ], - }, - // forms - { - path: '/form', - icon: 'form', - name: 'form', - routes: [ - { - path: '/form/basic-form', - name: 'basicform', - component: './Forms/BasicForm', - }, - { - path: '/form/step-form', - name: 'stepform', - component: './Forms/StepForm', - hideChildrenInMenu: true, - routes: [ - { - path: '/form/step-form', - redirect: '/form/step-form/info', - }, - { - path: '/form/step-form/info', - name: 'info', - component: './Forms/StepForm/Step1', - }, - { - path: '/form/step-form/confirm', - name: 'confirm', - component: './Forms/StepForm/Step2', - }, - { - path: '/form/step-form/result', - name: 'result', - component: './Forms/StepForm/Step3', - }, - ], - }, - { - path: '/form/advanced-form', - name: 'advancedform', - authority: ['admin'], - component: './Forms/AdvancedForm', - }, - ], - }, - // list - { - path: '/list', - icon: 'table', - name: 'list', - routes: [ - { - path: '/list/table-list', - name: 'searchtable', - component: './List/TableList', - }, - { - path: '/list/basic-list', - name: 'basiclist', - component: './List/BasicList', - }, - { - path: '/list/card-list', - name: 'cardlist', - component: './List/CardList', - }, - { - path: '/list/search', - name: 'searchlist', - component: './List/List', - routes: [ - { - path: '/list/search', - redirect: '/list/search/articles', - }, - { - path: '/list/search/articles', - name: 'articles', - component: './List/Articles', - }, - { - path: '/list/search/projects', - name: 'projects', - component: './List/Projects', - }, - { - path: '/list/search/applications', - name: 'applications', - component: './List/Applications', - }, - ], - }, - ], - }, - { - path: '/profile', - name: 'profile', - icon: 'profile', - routes: [ - // profile - { - path: '/profile/basic', - name: 'basic', - component: './Profile/BasicProfile', - }, - { - path: '/profile/advanced', - name: 'advanced', - authority: ['admin'], - component: './Profile/AdvancedProfile', - }, - ], - }, - { - name: 'result', - icon: 'check-circle-o', - path: '/result', - routes: [ - // result - { - path: '/result/success', - name: 'success', - component: './Result/Success', - }, - { path: '/result/fail', name: 'fail', component: './Result/Error' }, - ], - }, - { - name: 'exception', - icon: 'warning', - path: '/exception', - routes: [ - // exception - { - path: '/exception/403', - name: 'not-permission', - component: './Exception/403', - }, - { - path: '/exception/404', - name: 'not-find', - component: './Exception/404', - }, - { - path: '/exception/500', - name: 'server-error', - component: './Exception/500', - }, - { - path: '/exception/trigger', - name: 'trigger', - hideInMenu: true, - component: './Exception/TriggerException', - }, - ], - }, - { - name: 'account', - icon: 'user', - path: '/account', - routes: [ - { - path: '/account/center', - name: 'center', - component: './Account/Center/Center', - routes: [ - { - path: '/account/center', - redirect: '/account/center/articles', - }, - { - path: '/account/center/articles', - component: './Account/Center/Articles', - }, - { - path: '/account/center/applications', - component: './Account/Center/Applications', - }, - { - path: '/account/center/projects', - component: './Account/Center/Projects', - }, - ], - }, - { - path: '/account/settings', - name: 'settings', - component: './Account/Settings/Info', - routes: [ - { - path: '/account/settings', - redirect: '/account/settings/base', - }, - { - path: '/account/settings/base', - component: './Account/Settings/BaseView', - }, - { - path: '/account/settings/security', - component: './Account/Settings/SecurityView', - }, - { - path: '/account/settings/binding', - component: './Account/Settings/BindingView', - }, - { - path: '/account/settings/notification', - component: './Account/Settings/NotificationView', - }, - ], - }, - ], - }, - { - component: '404', - }, - ], - }, -]; diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml deleted file mode 100644 index d7ab2138339a456e9c46e830b8692545c712fbc2..0000000000000000000000000000000000000000 --- a/docker/docker-compose.dev.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: "3.5" - -services: - ant-design-pro_dev: - ports: - - 8000:8000 - build: - context: ../ - dockerfile: Dockerfile.dev - container_name: "ant-design-pro_dev" - volumes: - - ../src:/usr/src/app/src - - ../config:/usr/src/app/config - - ../mock:/usr/src/app/mock diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml deleted file mode 100644 index d055600644912e1af5010c0461808caa7b756b96..0000000000000000000000000000000000000000 --- a/docker/docker-compose.yml +++ /dev/null @@ -1,21 +0,0 @@ -version: "3.5" - -services: - ant-design-pro_build: - build: ../ - container_name: "ant-design-pro_build" - volumes: - - dist:/usr/src/app/dist - - ant-design-pro_web: - image: nginx - ports: - - 80:80 - container_name: "ant-design-pro_web" - restart: unless-stopped - volumes: - - dist:/usr/share/nginx/html:ro - - ./nginx.conf:/etc/nginx/conf.d/default.conf - -volumes: - dist: diff --git a/docker/nginx.conf b/docker/nginx.conf deleted file mode 100644 index 5f86992c8fbb8accbb878e6c9c93366d1ab8eb26..0000000000000000000000000000000000000000 --- a/docker/nginx.conf +++ /dev/null @@ -1,22 +0,0 @@ -server { - listen 80; - # gzip config - gzip on; - gzip_min_length 1k; - gzip_comp_level 9; - gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml; - gzip_vary on; - gzip_disable "MSIE [1-6]\."; - - root /usr/share/nginx/html; - - location / { - try_files $uri $uri/ /index.html; - } - location /api { - proxy_pass https://preview.pro.ant.design; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - } -} diff --git a/firebase.json b/firebase.json deleted file mode 100644 index a00223d4ddce6ed47ef14af8e3b78f86294c0706..0000000000000000000000000000000000000000 --- a/firebase.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "hosting": { - "public": "dist", - "rewrites": [ - { "source": "/api/**", "function": "api" }, - { - "source": "**", - "destination": "/index.html" - } - ], - "ignore": ["firebase.json", "**/.*", "**/node_modules/**"] - } -} diff --git a/functions/index.js b/functions/index.js deleted file mode 100644 index 609b51ca4df69bf827cac9ba7e600bd6685eec89..0000000000000000000000000000000000000000 --- a/functions/index.js +++ /dev/null @@ -1,10 +0,0 @@ -// [START functionsimport] -const functions = require('firebase-functions'); -const express = require('express'); - -const matchMock = require('./matchMock'); - -const app = express(); - -app.use(matchMock); -exports.api = functions.https.onRequest(app); diff --git a/functions/matchMock.js b/functions/matchMock.js deleted file mode 100644 index 924573a53a6c1cf5b58a45f43487b06b96516929..0000000000000000000000000000000000000000 --- a/functions/matchMock.js +++ /dev/null @@ -1,115 +0,0 @@ -const pathToRegexp = require('path-to-regexp'); -const bodyParser = require('body-parser'); - -const mockFile = require('./mock/index'); - -const BODY_PARSED_METHODS = ['post', 'put', 'patch']; - -const debug = console.log; -function parseKey(key) { - let method = 'get'; - let path = key; - if (key.indexOf(' ') > -1) { - const splited = key.split(' '); - method = splited[0].toLowerCase(); - path = splited[1]; // eslint-disable-line - } - return { - method, - path, - }; -} - -function createHandler(method, path, handler) { - return (req, res, next) => { - function sendData() { - if (typeof handler === 'function') { - handler(req, res, next); - } else { - res.json(handler); - } - } - if (BODY_PARSED_METHODS.includes(method)) { - bodyParser.json({ limit: '5mb', strict: false })(req, res, () => { - bodyParser.urlencoded({ limit: '5mb', extended: true })(req, res, () => { - sendData(); - }); - }); - } else { - sendData(); - } - }; -} - -function normalizeConfig(config) { - return Object.keys(config).reduce((memo, key) => { - const handler = config[key]; - const { method, path } = parseKey(key); - const keys = []; - const re = pathToRegexp(path, keys); - memo.push({ - method, - path, - re, - keys, - handler: createHandler(method, path, handler), - }); - return memo; - }, []); -} - -const mockData = normalizeConfig(mockFile); - -function matchMock(req) { - const { path: exceptPath } = req; - const exceptMethod = req.method.toLowerCase(); - function decodeParam(val) { - if (typeof val !== 'string' || val.length === 0) { - return val; - } - - try { - return decodeURIComponent(val); - } catch (err) { - if (err instanceof URIError) { - err.message = `Failed to decode param ' ${val} '`; - err.statusCode = 400; - err.status = 400; - } - - throw err; - } - } - // eslint-disable-next-line no-restricted-syntax - for (const mock of mockData) { - const { method, re, keys } = mock; - if (method === exceptMethod) { - const match = re.exec(req.path); - if (match) { - const params = {}; - - for (let i = 1; i < match.length; i += 1) { - const key = keys[i - 1]; - const prop = key.name; - const val = decodeParam(match[i]); - - if (val !== undefined || !hasOwnProperty.call(params, prop)) { - params[prop] = val; - } - } - req.params = params; - return mock; - } - } - } - - return mockData.filter(({ method, re }) => method === exceptMethod && re.test(exceptPath))[0]; -} -module.exports = (req, res, next) => { - const match = matchMock(req); - if (match) { - debug(`mock matched: [${match.method}] ${match.path}`); - return match.handler(req, res, next); - } - return next(); -}; diff --git a/functions/package.json b/functions/package.json deleted file mode 100644 index dd7281977e6816559ab0d5142b98a57358248d96..0000000000000000000000000000000000000000 --- a/functions/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "functions", - "description": "Cloud Functions for Firebase", - "scripts": { - "serve": "firebase serve --only functions", - "shell": "firebase functions:shell", - "start": "npm run shell", - "deploy": "npm run mock && firebase deploy --only functions", - "logs": "firebase functions:log", - "mock": "node ../scripts/generateMock.js" - }, - "dependencies": { - "@babel/runtime": "^7.0.0", - "body-parser": "^1.18.3", - "express": "^4.16.4", - "firebase-admin": "^6.4.0", - "firebase-functions": "^2.1.0", - "mockjs": "^1.0.1-beta3", - "moment": "^2.22.2", - "path-to-regexp": "^2.2.1" - }, - "private": true -} diff --git a/jest-puppeteer.config.js b/jest-puppeteer.config.js deleted file mode 100644 index d720fc2bf05ea1918ce0708be1ce18ebf4be5ff4..0000000000000000000000000000000000000000 --- a/jest-puppeteer.config.js +++ /dev/null @@ -1,15 +0,0 @@ -// ps https://github.com/GoogleChrome/puppeteer/issues/3120 -module.exports = { - launch: { - headless: true, - args: [ - '--disable-gpu', - '--disable-dev-shm-usage', - '--disable-setuid-sandbox', - '--no-first-run', - '--no-sandbox', - '--no-zygote', - '--single-process', - ], - }, -}; diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index 68a1144bcb17feb585b3725e5d323b0414dd91cc..0000000000000000000000000000000000000000 --- a/jest.config.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - testURL: 'http://localhost:8000', - preset: 'jest-puppeteer', -}; diff --git a/mock/geographic.js b/mock/geographic.js deleted file mode 100644 index e7772e8d32d5a580a696889de9c769a1a336a4e8..0000000000000000000000000000000000000000 --- a/mock/geographic.js +++ /dev/null @@ -1,15 +0,0 @@ -import city from './geographic/city.json'; -import province from './geographic/province.json'; - -function getProvince(req, res) { - return res.json(province); -} - -function getCity(req, res) { - return res.json(city[req.params.province]); -} - -export default { - 'GET /api/geographic/province': getProvince, - 'GET /api/geographic/city/:province': getCity, -}; diff --git a/mock/notices.js b/mock/notices.js deleted file mode 100644 index e07565dfe603c73b348c908a201d20422da3bf52..0000000000000000000000000000000000000000 --- a/mock/notices.js +++ /dev/null @@ -1,115 +0,0 @@ -const fakeNotices = [ - { - id: '000000001', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', - title: '你收到了 14 份新周报', - datetime: '2017-08-09', - type: 'notification', - }, - { - id: '000000002', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png', - title: '你推荐的 曲妮妮 已通过第三轮面试', - datetime: '2017-08-08', - type: 'notification', - }, - { - id: '000000003', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png', - title: '这种模板可以区分多种通知类型', - datetime: '2017-08-07', - read: true, - type: 'notification', - }, - { - id: '000000004', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', - title: '左侧图标用于区分不同的类型', - datetime: '2017-08-07', - type: 'notification', - }, - { - id: '000000005', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', - title: '内容不要超过两行字,超出时自动截断', - datetime: '2017-08-07', - type: 'notification', - }, - { - id: '000000006', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', - title: '曲丽丽 评论了你', - description: '描述信息描述信息描述信息', - datetime: '2017-08-07', - type: 'message', - clickClose: true, - }, - { - id: '000000007', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', - title: '朱偏右 回复了你', - description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', - datetime: '2017-08-07', - type: 'message', - clickClose: true, - }, - { - id: '000000008', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', - title: '标题', - description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', - datetime: '2017-08-07', - type: 'message', - clickClose: true, - }, - { - id: '000000009', - title: '任务名称', - description: '任务需要在 2017-01-12 20:00 前启动', - extra: '未开始', - status: 'todo', - type: 'event', - }, - { - id: '000000010', - title: '第三方紧急代码变更', - description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', - extra: '马上到期', - status: 'urgent', - type: 'event', - }, - { - id: '000000011', - title: '信息安全考试', - description: '指派竹尔于 2017-01-09 前完成更新并发布', - extra: '已耗时 8 天', - status: 'doing', - type: 'event', - }, - { - id: '000000012', - title: 'ABCD 版本发布', - description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', - extra: '进行中', - status: 'processing', - type: 'event', - }, -]; - -const getNotices = (req, res) => { - if (req.query && req.query.type) { - const startFrom = parseInt(req.query.lastItemId, 10) + 1; - const result = fakeNotices - .filter(({ type }) => type === req.query.type) - .map((notice, index) => ({ - ...notice, - id: `0000000${startFrom + index}`, - })); - return res.json(startFrom > 24 ? result.concat(null) : result); - } - return res.json(fakeNotices); -}; - -export default { - 'GET /api/notices': getNotices, -}; diff --git a/mock/route.js b/mock/route.js deleted file mode 100644 index 418d10f1ab333d66dfed05220d8da9a11110a9e8..0000000000000000000000000000000000000000 --- a/mock/route.js +++ /dev/null @@ -1,5 +0,0 @@ -export default { - '/api/auth_routes': { - '/form/advanced-form': { authority: ['admin', 'user'] }, - }, -}; diff --git a/mock/user.js b/mock/user.js deleted file mode 100644 index dd3f240282f8cb93e2ae3da04960124c6e81182e..0000000000000000000000000000000000000000 --- a/mock/user.js +++ /dev/null @@ -1,138 +0,0 @@ -// 代码中会兼容本地 service mock 以及部署站点的静态数据 -export default { - // 支持值为 Object 和 Array - 'GET /api/currentUser': { - name: 'Serati Ma', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png', - userid: '00000001', - email: 'antdesign@alipay.com', - signature: '海纳百川,有容乃大', - title: '交互专家', - group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED', - tags: [ - { - key: '0', - label: '很有想法的', - }, - { - key: '1', - label: '专注设计', - }, - { - key: '2', - label: '辣~', - }, - { - key: '3', - label: '大长腿', - }, - { - key: '4', - label: '川妹子', - }, - { - key: '5', - label: '海纳百川', - }, - ], - notifyCount: 12, - unreadCount: 11, - country: 'China', - geographic: { - province: { - label: '浙江省', - key: '330000', - }, - city: { - label: '杭州市', - key: '330100', - }, - }, - address: '西湖区工专路 77 号', - phone: '0752-268888888', - }, - // GET POST 可省略 - 'GET /api/users': [ - { - key: '1', - name: 'John Brown', - age: 32, - address: 'New York No. 1 Lake Park', - }, - { - key: '2', - name: 'Jim Green', - age: 42, - address: 'London No. 1 Lake Park', - }, - { - key: '3', - name: 'Joe Black', - age: 32, - address: 'Sidney No. 1 Lake Park', - }, - ], - 'POST /api/login/account': (req, res) => { - const { password, userName, type } = req.body; - if (password === 'ant.design' && userName === 'admin') { - res.send({ - status: 'ok', - type, - currentAuthority: 'admin', - }); - return; - } - if (password === 'ant.design' && userName === 'user') { - res.send({ - status: 'ok', - type, - currentAuthority: 'user', - }); - return; - } - res.send({ - status: 'error', - type, - currentAuthority: 'guest', - }); - }, - 'POST /api/register': (req, res) => { - res.send({ status: 'ok', currentAuthority: 'user' }); - }, - 'GET /api/500': (req, res) => { - res.status(500).send({ - timestamp: 1513932555104, - status: 500, - error: 'error', - message: 'error', - path: '/base/category/list', - }); - }, - 'GET /api/404': (req, res) => { - res.status(404).send({ - timestamp: 1513932643431, - status: 404, - error: 'Not Found', - message: 'No message available', - path: '/base/category/list/2121212', - }); - }, - 'GET /api/403': (req, res) => { - res.status(403).send({ - timestamp: 1513932555104, - status: 403, - error: 'Unauthorized', - message: 'Unauthorized', - path: '/base/category/list', - }); - }, - 'GET /api/401': (req, res) => { - res.status(401).send({ - timestamp: 1513932555104, - status: 401, - error: 'Unauthorized', - message: 'Unauthorized', - path: '/base/category/list', - }); - }, -}; diff --git a/netlify.toml b/netlify.toml deleted file mode 100644 index 18b22e9d58b17ae991caaa6f96317b1aeac87f93..0000000000000000000000000000000000000000 --- a/netlify.toml +++ /dev/null @@ -1,13 +0,0 @@ -[[redirects]] - from = "/api/*" - to = "https://us-central1-antd-pro.cloudfunctions.net/api/api/:splat" - status = 200 - force = true - [redirects.headers] - X-From = "Netlify" - X-Api-Key = "some-api-key-string" - -[[redirects]] - from = "/*" - to = "/index.html" - status = 200 \ No newline at end of file diff --git a/package.json b/package.json index f2b4fe0e6f5a575dd0a705db4a6b97a144b95e10..8af2d3bdaeae7230a475a26bb854cc38be4c8f4a 100644 --- a/package.json +++ b/package.json @@ -1,76 +1,15 @@ { - "name": "ant-design-pro", - "version": "2.2.0", - "description": "An out-of-box UI solution for enterprise applications", "private": true, "scripts": { - "presite": "cd functions && npm install", - "start": "cross-env APP_TYPE=site umi dev", - "start:no-mock": "cross-env MOCK=none umi dev", - "build": "umi build", - "site": "npm run presite && cross-env APP_TYPE=site npm run build && firebase deploy && npm run docker:push", - "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": "eslint --ext .js src mock tests && npm run lint:style", "lint:fix": "eslint --fix --ext .js src mock tests && npm run lint:style", "lint-staged": "lint-staged", "lint-staged:js": "eslint --ext .js", - "tslint": "npm run tslint:fix", - "tslint:fix": "tslint --fix 'src/**/*.ts*'", - "test": "umi test", - "test:component": "umi test ./src/components", - "test:all": "node ./tests/run-tests.js", - "prettier": "node ./scripts/prettier.js", - "docker:dev": "docker-compose -f ./docker/docker-compose.dev.yml up", - "docker:build": "docker-compose -f ./docker/docker-compose.dev.yml build", - "docker-prod:dev": "docker-compose -f ./docker/docker-compose.yml up", - "docker-prod:build": "docker-compose -f ./docker/docker-compose.yml build", - "docker-hub:build": "docker build -f Dockerfile.hub -t ant-design-pro ./", - "docker:tag": "docker tag ant-design-pro antdesign/ant-design-pro", - "docker:push": "npm run docker-hub:build && npm run docker:tag && docker push antdesign/ant-design-pro" - }, - "dependencies": { - "@antv/data-set": "^0.10.0", - "@babel/runtime": "^7.2.0", - "antd": "^3.11.6", - "bizcharts": "^3.4.2", - "bizcharts-plugin-slider": "^2.1.1-beta.1", - "chalk": "^2.4.2", - "classnames": "^2.2.6", - "dva": "^2.4.0", - "enquire-js": "^0.2.1", - "hash.js": "^1.1.5", - "lodash": "^4.17.10", - "lodash-decorators": "^6.0.0", - "memoize-one": "^5.0.0", - "moment": "^2.22.2", - "numeral": "^2.0.6", - "nzh": "^1.0.3", - "omit.js": "^1.0.0", - "path-to-regexp": "^2.4.0", - "prop-types": "^15.5.10", - "qs": "^6.6.0", - "rc-animate": "^2.4.4", - "react": "^16.6.3", - "react-container-query": "^0.11.0", - "react-copy-to-clipboard": "^5.0.1", - "react-document-title": "^2.0.3", - "react-dom": "^16.6.3", - "react-fittext": "^1.0.0", - "react-media": "^1.8.0", - "react-router-dom": "^4.3.1" + "prettier": "node ./_scripts/prettier.js" }, "devDependencies": { - "@types/react": "^16.7.7", - "@types/react-dom": "^16.0.10", - "antd-pro-merge-less": "^1.0.0", - "antd-theme-webpack-plugin": "^1.1.8", "babel-eslint": "^10.0.1", - "check-prettier": "^1.0.1", - "cross-env": "^5.1.1", - "cross-port-killer": "^1.0.1", - "enzyme": "3.7.0", "eslint": "^5.4.0", "eslint-config-airbnb": "^17.0.0", "eslint-config-prettier": "^3.0.1", @@ -80,52 +19,25 @@ "eslint-plugin-jsx-a11y": "^6.1.2", "eslint-plugin-markdown": "^1.0.0-beta.6", "eslint-plugin-react": "^7.11.1", - "gh-pages": "^2.0.1", + "glob": "^7.1.3", "husky": "^1.2.0", - "jest-puppeteer": "^3.5.1", - "less": "^3.9.0", "lint-staged": "^8.1.0", - "merge-umi-mock-data": "^1.0.4", - "mockjs": "^1.0.1-beta3", "prettier": "1.15.2", - "pro-download": "^1.0.1", - "slash2": "^2.0.0", "stylelint": "^9.8.0", "stylelint-config-prettier": "^4.0.0", "stylelint-config-standard": "^18.0.0", - "tslint": "^5.10.0", - "tslint-config-prettier": "^1.10.0", - "tslint-react": "^3.6.0", - "umi": "^2.4.2", - "umi-plugin-ga": "^1.1.3", - "umi-plugin-react": "^1.3.4" - }, - "optionalDependencies": { - "puppeteer": "^1.10.0" + "umi": "^2.3.0-0", + "umi-plugin-block-dev": "^1.0.0", + "umi-plugin-react": "^1.3.0-0" }, "lint-staged": { - "**/*.{js,ts,tsx,json,jsx,less}": [ - "node ./scripts/lint-prettier.js", + "x/**/*.{js,ts,tsx,json,jsx,less}": [ + "node ./_scripts/lint-prettier.js", "git add" ], - "**/*.{js,jsx}": "npm run lint-staged:js", + "x/**/*.{js,jsx}": "npm run lint-staged:js", "**/*.less": "stylelint --syntax less" }, - "engines": { - "node": ">=8.0.0" - }, - "browserslist": [ - "> 1%", - "last 2 versions", - "not ie <= 10" - ], - "checkFiles": [ - "src/**/*.js*", - "src/**/*.ts*", - "src/**/*.less", - "config/**/*.js*", - "scripts/**/*.js" - ], "husky": { "hooks": { "pre-commit": "npm run lint-staged" diff --git a/public/favicon.png b/public/favicon.png deleted file mode 100644 index ece59ce54690c0e1c1e6984ec9dd815645ab4cb8..0000000000000000000000000000000000000000 Binary files a/public/favicon.png and /dev/null differ diff --git a/public/icons/icon-128x128.png b/public/icons/icon-128x128.png deleted file mode 100644 index 48d0e2339a60a637b94319c65e8654289b4f4b6c..0000000000000000000000000000000000000000 Binary files a/public/icons/icon-128x128.png and /dev/null differ diff --git a/public/icons/icon-192x192.png b/public/icons/icon-192x192.png deleted file mode 100644 index 938e9b53f6850d97c693b3e3107968fbced5050c..0000000000000000000000000000000000000000 Binary files a/public/icons/icon-192x192.png and /dev/null differ diff --git a/public/icons/icon-512x512.png b/public/icons/icon-512x512.png deleted file mode 100644 index 21fc108f00294d66855a6c10af022b9d6d0f23b9..0000000000000000000000000000000000000000 Binary files a/public/icons/icon-512x512.png and /dev/null differ diff --git a/scripts/generateMock.js b/scripts/generateMock.js deleted file mode 100644 index 54c7d6d624fcefd98cec3600538284a5056910a7..0000000000000000000000000000000000000000 --- a/scripts/generateMock.js +++ /dev/null @@ -1,3 +0,0 @@ -const generateMock = require('merge-umi-mock-data'); -const path = require('path'); -generateMock(path.join(__dirname, '../mock'), path.join(__dirname, '../functions/mock/index.js')); diff --git a/scripts/getPrettierFiles.js b/scripts/getPrettierFiles.js deleted file mode 100644 index 2b01a8ef4828ec14503fabdd0ddf1779209d3cea..0000000000000000000000000000000000000000 --- a/scripts/getPrettierFiles.js +++ /dev/null @@ -1,21 +0,0 @@ -const glob = require('glob'); - -const getPrettierFiles = () => { - let files = []; - const jsFiles = glob.sync('src/**/*.js*', { ignore: ['**/node_modules/**', 'build/**'] }); - const tsFiles = glob.sync('src/**/*.ts*', { ignore: ['**/node_modules/**', 'build/**'] }); - const configFiles = glob.sync('config/**/*.js*', { ignore: ['**/node_modules/**', 'build/**'] }); - const scriptFiles = glob.sync('scripts/**/*.js'); - const lessFiles = glob.sync('src/**/*.less*', { ignore: ['**/node_modules/**', 'build/**'] }); - files = files.concat(jsFiles); - files = files.concat(tsFiles); - files = files.concat(configFiles); - files = files.concat(scriptFiles); - files = files.concat(lessFiles); - if (!files.length) { - return; - } - return files; -}; - -module.exports = getPrettierFiles; diff --git a/scripts/lint-prettier.js b/scripts/lint-prettier.js deleted file mode 100644 index 677f793bee1ee17eda4d41b2b0d05ba7c10336bf..0000000000000000000000000000000000000000 --- a/scripts/lint-prettier.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * copy to https://github.com/facebook/react/blob/master/scripts/prettier/index.js - * prettier api doc https://prettier.io/docs/en/api.html - *----------*****-------------- - * lint file is prettier - *----------*****-------------- - */ - -const prettier = require('prettier'); -const fs = require('fs'); -const chalk = require('chalk'); -const prettierConfigPath = require.resolve('../.prettierrc'); - -const files = process.argv.slice(2); - -let didError = false; - -files.forEach(file => { - Promise.all([ - prettier.resolveConfig(file, { - config: prettierConfigPath, - }), - prettier.getFileInfo(file), - ]) - .then(resolves => { - const [options, fileInfo] = resolves; - if (fileInfo.ignored) { - return; - } - const input = fs.readFileSync(file, 'utf8'); - const withParserOptions = { - ...options, - parser: fileInfo.inferredParser, - }; - const output = prettier.format(input, withParserOptions); - if (output !== input) { - fs.writeFileSync(file, output, 'utf8'); - console.log(chalk.green(`${file} is prettier`)); - } - }) - .catch(e => { - didError = true; - }) - .finally(() => { - if (didError) { - process.exit(1); - } - console.log(chalk.hex('#1890FF')('prettier success!')); - }); -}); diff --git a/src/app.js b/src/app.js deleted file mode 100644 index 7de5a69e1330e9ff0738ddd1ce378cc661e04619..0000000000000000000000000000000000000000 --- a/src/app.js +++ /dev/null @@ -1,38 +0,0 @@ -import fetch from 'dva/fetch'; - -export const dva = { - config: { - onError(err) { - err.preventDefault(); - }, - }, -}; - -let authRoutes = null; - -function ergodicRoutes(routes, authKey, authority) { - routes.forEach(element => { - if (element.path === authKey) { - Object.assign(element.authority, authority || []); - } else if (element.routes) { - ergodicRoutes(element.routes, authKey, authority); - } - return element; - }); -} - -export function patchRoutes(routes) { - Object.keys(authRoutes).map(authKey => - ergodicRoutes(routes, authKey, authRoutes[authKey].authority) - ); - window.g_routes = routes; -} - -export function render(oldRender) { - fetch('/api/auth_routes') - .then(res => res.json()) - .then(ret => { - authRoutes = ret; - oldRender(); - }); -} diff --git a/src/assets/logo.svg b/src/assets/logo.svg deleted file mode 100644 index e9f8c2a9d78f344a4b020d3b4e972c393b0a1079..0000000000000000000000000000000000000000 --- a/src/assets/logo.svg +++ /dev/null @@ -1,43 +0,0 @@ - - - - Group 28 Copy 5 - Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/components/Authorized/Authorized.js b/src/components/Authorized/Authorized.js deleted file mode 100644 index 75d57b88c20c285a188f5a9ef35adcd55146877e..0000000000000000000000000000000000000000 --- a/src/components/Authorized/Authorized.js +++ /dev/null @@ -1,8 +0,0 @@ -import CheckPermissions from './CheckPermissions'; - -const Authorized = ({ children, authority, noMatch = null }) => { - const childrenRender = typeof children === 'undefined' ? null : children; - return CheckPermissions(authority, childrenRender, noMatch); -}; - -export default Authorized; diff --git a/src/components/Authorized/AuthorizedRoute.d.ts b/src/components/Authorized/AuthorizedRoute.d.ts deleted file mode 100644 index 912b283ab81ecddb89f05d4228095c5b05a64803..0000000000000000000000000000000000000000 --- a/src/components/Authorized/AuthorizedRoute.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import * as React from 'react'; -import { RouteProps } from 'react-router'; - -type authorityFN = (currentAuthority?: string) => boolean; - -type authority = string | string[] | authorityFN | Promise; - -export interface IAuthorizedRouteProps extends RouteProps { - authority: authority; -} -export { authority }; - -export class AuthorizedRoute extends React.Component {} diff --git a/src/components/Authorized/AuthorizedRoute.js b/src/components/Authorized/AuthorizedRoute.js deleted file mode 100644 index 39c6a665f1bf522622ac73e2333f0739c587b1a2..0000000000000000000000000000000000000000 --- a/src/components/Authorized/AuthorizedRoute.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; -import { Route, Redirect } from 'react-router-dom'; -import Authorized from './Authorized'; - -// TODO: umi只会返回render和rest -const AuthorizedRoute = ({ component: Component, render, authority, redirectPath, ...rest }) => ( - } />} - > - (Component ? : render(props))} /> - -); - -export default AuthorizedRoute; diff --git a/src/components/Authorized/CheckPermissions.js b/src/components/Authorized/CheckPermissions.js deleted file mode 100644 index ba83f5b9a14ea01db4824df72db79eb91c19506b..0000000000000000000000000000000000000000 --- a/src/components/Authorized/CheckPermissions.js +++ /dev/null @@ -1,88 +0,0 @@ -import React from 'react'; -import PromiseRender from './PromiseRender'; -import { CURRENT } from './renderAuthorize'; - -function isPromise(obj) { - return ( - !!obj && - (typeof obj === 'object' || typeof obj === 'function') && - typeof obj.then === 'function' - ); -} - -/** - * 通用权限检查方法 - * Common check permissions method - * @param { 权限判定 Permission judgment type string |array | Promise | Function } authority - * @param { 你的权限 Your permission description type:string} currentAuthority - * @param { 通过的组件 Passing components } target - * @param { 未通过的组件 no pass components } Exception - */ -const checkPermissions = (authority, currentAuthority, target, Exception) => { - // 没有判定权限.默认查看所有 - // Retirement authority, return target; - if (!authority) { - return target; - } - // 数组处理 - if (Array.isArray(authority)) { - if (authority.indexOf(currentAuthority) >= 0) { - return target; - } - if (Array.isArray(currentAuthority)) { - for (let i = 0; i < currentAuthority.length; i += 1) { - const element = currentAuthority[i]; - if (authority.indexOf(element) >= 0) { - return target; - } - } - } - return Exception; - } - - // string 处理 - if (typeof authority === 'string') { - if (authority === currentAuthority) { - return target; - } - if (Array.isArray(currentAuthority)) { - for (let i = 0; i < currentAuthority.length; i += 1) { - const element = currentAuthority[i]; - if (authority === element) { - return target; - } - } - } - return Exception; - } - - // Promise 处理 - if (isPromise(authority)) { - return ; - } - - // Function 处理 - if (typeof authority === 'function') { - try { - const bool = authority(currentAuthority); - // 函数执行后返回值是 Promise - if (isPromise(bool)) { - return ; - } - if (bool) { - return target; - } - return Exception; - } catch (error) { - throw error; - } - } - throw new Error('unsupported parameters'); -}; - -export { checkPermissions }; - -const check = (authority, target, Exception) => - checkPermissions(authority, CURRENT, target, Exception); - -export default check; diff --git a/src/components/Authorized/CheckPermissions.test.js b/src/components/Authorized/CheckPermissions.test.js deleted file mode 100644 index 3988d85a18fcfe7412bb72f672ffdf7c2501d8c2..0000000000000000000000000000000000000000 --- a/src/components/Authorized/CheckPermissions.test.js +++ /dev/null @@ -1,55 +0,0 @@ -import { checkPermissions } from './CheckPermissions'; - -const target = 'ok'; -const error = 'error'; - -describe('test CheckPermissions', () => { - it('Correct string permission authentication', () => { - expect(checkPermissions('user', 'user', target, error)).toEqual('ok'); - }); - it('Correct string permission authentication', () => { - expect(checkPermissions('user', 'NULL', target, error)).toEqual('error'); - }); - it('authority is undefined , return ok', () => { - expect(checkPermissions(null, 'NULL', target, error)).toEqual('ok'); - }); - it('currentAuthority is undefined , return error', () => { - expect(checkPermissions('admin', null, target, error)).toEqual('error'); - }); - it('Wrong string permission authentication', () => { - expect(checkPermissions('admin', 'user', target, error)).toEqual('error'); - }); - it('Correct Array permission authentication', () => { - expect(checkPermissions(['user', 'admin'], 'user', target, error)).toEqual('ok'); - }); - it('Wrong Array permission authentication,currentAuthority error', () => { - expect(checkPermissions(['user', 'admin'], 'user,admin', target, error)).toEqual('error'); - }); - it('Wrong Array permission authentication', () => { - expect(checkPermissions(['user', 'admin'], 'guest', target, error)).toEqual('error'); - }); - it('Wrong Function permission authentication', () => { - expect(checkPermissions(() => false, 'guest', target, error)).toEqual('error'); - }); - it('Correct Function permission authentication', () => { - expect(checkPermissions(() => true, 'guest', target, error)).toEqual('ok'); - }); - it('authority is string, currentAuthority is array, return ok', () => { - expect(checkPermissions('user', ['user'], target, error)).toEqual('ok'); - }); - it('authority is string, currentAuthority is array, return ok', () => { - expect(checkPermissions('user', ['user', 'admin'], target, error)).toEqual('ok'); - }); - it('authority is array, currentAuthority is array, return ok', () => { - expect(checkPermissions(['user', 'admin'], ['user', 'admin'], target, error)).toEqual('ok'); - }); - it('Wrong Function permission authentication', () => { - expect(checkPermissions(() => false, ['user'], target, error)).toEqual('error'); - }); - it('Correct Function permission authentication', () => { - expect(checkPermissions(() => true, ['user'], target, error)).toEqual('ok'); - }); - it('authority is undefined , return ok', () => { - expect(checkPermissions(null, ['user'], target, error)).toEqual('ok'); - }); -}); diff --git a/src/components/Authorized/PromiseRender.js b/src/components/Authorized/PromiseRender.js deleted file mode 100644 index 8e2a4059d8689ca1e0be623aedd14cc9a2d75134..0000000000000000000000000000000000000000 --- a/src/components/Authorized/PromiseRender.js +++ /dev/null @@ -1,65 +0,0 @@ -import React from 'react'; -import { Spin } from 'antd'; - -export default class PromiseRender extends React.PureComponent { - state = { - component: null, - }; - - componentDidMount() { - this.setRenderComponent(this.props); - } - - componentDidUpdate(nextProps) { - // new Props enter - this.setRenderComponent(nextProps); - } - - // set render Component : ok or error - setRenderComponent(props) { - const ok = this.checkIsInstantiation(props.ok); - const error = this.checkIsInstantiation(props.error); - props.promise - .then(() => { - this.setState({ - component: ok, - }); - }) - .catch(() => { - this.setState({ - component: error, - }); - }); - } - - // Determine whether the incoming component has been instantiated - // AuthorizedRoute is already instantiated - // Authorized render is already instantiated, children is no instantiated - // Secured is not instantiated - checkIsInstantiation = target => { - if (!React.isValidElement(target)) { - return target; - } - return () => target; - }; - - render() { - const { component: Component } = this.state; - const { ok, error, promise, ...rest } = this.props; - return Component ? ( - - ) : ( - - - - ); - } -} diff --git a/src/components/Authorized/Secured.js b/src/components/Authorized/Secured.js deleted file mode 100644 index c935183dac25c82786336cef97cc905220153271..0000000000000000000000000000000000000000 --- a/src/components/Authorized/Secured.js +++ /dev/null @@ -1,55 +0,0 @@ -import React from 'react'; -import Exception from '../Exception'; -import CheckPermissions from './CheckPermissions'; -/** - * 默认不能访问任何页面 - * default is "NULL" - */ -const Exception403 = () => ; - -// Determine whether the incoming component has been instantiated -// AuthorizedRoute is already instantiated -// Authorized render is already instantiated, children is no instantiated -// Secured is not instantiated -const checkIsInstantiation = target => { - if (!React.isValidElement(target)) { - return target; - } - return () => target; -}; - -/** - * 用于判断是否拥有权限访问此view权限 - * authority 支持传入 string, function:()=>boolean|Promise - * e.g. 'user' 只有user用户能访问 - * e.g. 'user,admin' user和 admin 都能访问 - * e.g. ()=>boolean 返回true能访问,返回false不能访问 - * e.g. Promise then 能访问 catch不能访问 - * e.g. authority support incoming string, function: () => boolean | Promise - * e.g. 'user' only user user can access - * e.g. 'user, admin' user and admin can access - * e.g. () => boolean true to be able to visit, return false can not be accessed - * e.g. Promise then can not access the visit to catch - * @param {string | function | Promise} authority - * @param {ReactNode} error 非必需参数 - */ -const authorize = (authority, error) => { - /** - * conversion into a class - * 防止传入字符串时找不到staticContext造成报错 - * String parameters can cause staticContext not found error - */ - let classError = false; - if (error) { - classError = () => error; - } - if (!authority) { - throw new Error('authority is required'); - } - return function decideAuthority(target) { - const component = CheckPermissions(authority, target, classError || Exception403); - return checkIsInstantiation(component); - }; -}; - -export default authorize; diff --git a/src/components/Authorized/demo/AuthorizedArray.md b/src/components/Authorized/demo/AuthorizedArray.md deleted file mode 100644 index 46eaf761ca62cb9fe8cb4a3daa78739213a5fa09..0000000000000000000000000000000000000000 --- a/src/components/Authorized/demo/AuthorizedArray.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -order: 1 -title: - zh-CN: 使用数组作为参数 - en-US: Use Array as a parameter ---- - -Use Array as a parameter - -```jsx -import RenderAuthorized from 'ant-design-pro/lib/Authorized'; -import { Alert } from 'antd'; - -const Authorized = RenderAuthorized('user'); -const noMatch = ; - -ReactDOM.render( - - - , - mountNode, -); -``` diff --git a/src/components/Authorized/demo/AuthorizedFunction.md b/src/components/Authorized/demo/AuthorizedFunction.md deleted file mode 100644 index 8ad8b91e1bd656f5372e06ddadecb9d6e3eb1fb5..0000000000000000000000000000000000000000 --- a/src/components/Authorized/demo/AuthorizedFunction.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -order: 2 -title: - zh-CN: 使用方法作为参数 - en-US: Use function as a parameter ---- - -Use Function as a parameter - -```jsx -import RenderAuthorized from 'ant-design-pro/lib/Authorized'; -import { Alert } from 'antd'; - -const Authorized = RenderAuthorized('user'); -const noMatch = ; - -const havePermission = () => { - return false; -}; - -ReactDOM.render( - - - , - mountNode, -); -``` diff --git a/src/components/Authorized/demo/basic.md b/src/components/Authorized/demo/basic.md deleted file mode 100644 index a5f12f29e23c4a10ca1163efa6635aafafa5ffbd..0000000000000000000000000000000000000000 --- a/src/components/Authorized/demo/basic.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -order: 0 -title: - zh-CN: 基本使用 - en-US: Basic use ---- - -Basic use - -```jsx -import RenderAuthorized from 'ant-design-pro/lib/Authorized'; -import { Alert } from 'antd'; - -const Authorized = RenderAuthorized('user'); -const noMatch = ; - -ReactDOM.render( - - - - - , - mountNode, -); -``` diff --git a/src/components/Authorized/demo/secured.md b/src/components/Authorized/demo/secured.md deleted file mode 100644 index 1e9537af19d3613b9ea6684f8933afa283ba1415..0000000000000000000000000000000000000000 --- a/src/components/Authorized/demo/secured.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -order: 3 -title: - zh-CN: 注解基本使用 - en-US: Basic use secured ---- - -secured demo used - -```jsx -import RenderAuthorized from 'ant-design-pro/lib/Authorized'; -import { Alert } from 'antd'; - -const { Secured } = RenderAuthorized('user'); - -@Secured('admin') -class TestSecuredString extends React.Component { - render() { - ; - } -} -ReactDOM.render( - - - , - mountNode, -); -``` diff --git a/src/components/Authorized/index.d.ts b/src/components/Authorized/index.d.ts deleted file mode 100644 index b3e2f56c6c3784daa62e908286566c954db1675f..0000000000000000000000000000000000000000 --- a/src/components/Authorized/index.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -import * as React from 'react'; -import AuthorizedRoute, { authority } from './AuthorizedRoute'; -export type IReactComponent = - | React.StatelessComponent - | React.ComponentClass - | React.ClassicComponentClass; - -type Secured = ( - authority: authority, - error?: React.ReactNode -) => (target: T) => T; - -type check = ( - authority: authority, - target: T, - Exception: S -) => T | S; - -export interface IAuthorizedProps { - authority: authority; - noMatch?: React.ReactNode; -} - -export class Authorized extends React.Component { - public static Secured: Secured; - public static AuthorizedRoute: typeof AuthorizedRoute; - public static check: check; -} - -declare function renderAuthorize(currentAuthority: string): typeof Authorized; - -export default renderAuthorize; diff --git a/src/components/Authorized/index.js b/src/components/Authorized/index.js deleted file mode 100644 index 22ac664d002844304b316e8c4f1acc79ede572d8..0000000000000000000000000000000000000000 --- a/src/components/Authorized/index.js +++ /dev/null @@ -1,11 +0,0 @@ -import Authorized from './Authorized'; -import AuthorizedRoute from './AuthorizedRoute'; -import Secured from './Secured'; -import check from './CheckPermissions'; -import renderAuthorize from './renderAuthorize'; - -Authorized.Secured = Secured; -Authorized.AuthorizedRoute = AuthorizedRoute; -Authorized.check = check; - -export default renderAuthorize(Authorized); diff --git a/src/components/Authorized/index.md b/src/components/Authorized/index.md deleted file mode 100644 index f3b2f80af5ffa27ecb310b6932dc7dfa7c7945c8..0000000000000000000000000000000000000000 --- a/src/components/Authorized/index.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: - en-US: Authorized - zh-CN: Authorized -subtitle: 权限 -cols: 1 -order: 15 ---- - -权限组件,通过比对现有权限与准入权限,决定相关元素的展示。 - -## API - -### RenderAuthorized - -`RenderAuthorized: (currentAuthority: string | () => string) => Authorized` - -权限组件默认 export RenderAuthorized 函数,它接收当前权限作为参数,返回一个权限对象,该对象提供以下几种使用方式。 - - -### Authorized - -最基础的权限控制。 - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| children | 正常渲染的元素,权限判断通过时展示 | ReactNode | - | -| authority | 准入权限/权限判断 | `string | array | Promise | (currentAuthority) => boolean | Promise` | - | -| noMatch | 权限异常渲染元素,权限判断不通过时展示 | ReactNode | - | - -### Authorized.AuthorizedRoute - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| authority | 准入权限/权限判断 | `string | array | Promise | (currentAuthority) => boolean | Promise` | - | -| redirectPath | 权限异常时重定向的页面路由 | string | - | - -其余参数与 `Route` 相同。 - -### Authorized.Secured - -注解方式,`@Authorized.Secured(authority, error)` - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| authority | 准入权限/权限判断 | `string | Promise | (currentAuthority) => boolean | Promise` | - | -| error | 权限异常时渲染元素 | ReactNode | | - -### Authorized.check - -函数形式的 Authorized,用于某些不能被 HOC 包裹的组件。 `Authorized.check(authority, target, Exception)` -注意:传入一个 Promise 时,无论正确还是错误返回的都是一个 ReactClass。 - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| authority | 准入权限/权限判断 | `string | Promise | (currentAuthority) => boolean | Promise` | - | -| target | 权限判断通过时渲染的元素 | ReactNode | - | -| Exception | 权限异常时渲染元素 | ReactNode | - | diff --git a/src/components/Authorized/renderAuthorize.js b/src/components/Authorized/renderAuthorize.js deleted file mode 100644 index be373d996bb38445af1c6e912bdac32ad594747d..0000000000000000000000000000000000000000 --- a/src/components/Authorized/renderAuthorize.js +++ /dev/null @@ -1,25 +0,0 @@ -/* eslint-disable import/no-mutable-exports */ -let CURRENT = 'NULL'; -/** - * use authority or getAuthority - * @param {string|()=>String} currentAuthority - */ -const renderAuthorize = Authorized => currentAuthority => { - if (currentAuthority) { - if (typeof currentAuthority === 'function') { - CURRENT = currentAuthority(); - } - if ( - Object.prototype.toString.call(currentAuthority) === '[object String]' || - Array.isArray(currentAuthority) - ) { - CURRENT = currentAuthority; - } - } else { - CURRENT = 'NULL'; - } - return Authorized; -}; - -export { CURRENT }; -export default Authorized => renderAuthorize(Authorized); diff --git a/src/components/AvatarList/AvatarItem.d.ts b/src/components/AvatarList/AvatarItem.d.ts deleted file mode 100644 index 5681de77c2b3634ee8a54487fe15d07044fa8ca4..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/AvatarItem.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as React from 'react'; -export interface IAvatarItemProps { - tips: React.ReactNode; - src: string; - style?: React.CSSProperties; -} - -export default class AvatarItem extends React.Component { - constructor(props: IAvatarItemProps); -} diff --git a/src/components/AvatarList/demo/maxLength.md b/src/components/AvatarList/demo/maxLength.md deleted file mode 100644 index 76c6b421cb0b976e2b0752a61522fca1f9a747b6..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/demo/maxLength.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -order: 0 -title: - zh-CN: 要显示的最大项目 - en-US: Max Items to Show ---- - -`maxLength` attribute specifies the maximum number of items to show while `excessItemsStyle` style the excess -item component. - -````jsx -import AvatarList from 'ant-design-pro/lib/AvatarList'; - -ReactDOM.render( - - - - - - - - -, mountNode); -```` diff --git a/src/components/AvatarList/demo/simple.md b/src/components/AvatarList/demo/simple.md deleted file mode 100644 index e941aea9b5d9614c11edb84cc9f7975a6087e455..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/demo/simple.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -order: 0 -title: - zh-CN: 基础样例 - en-US: Basic Usage ---- - -Simplest of usage. - -````jsx -import AvatarList from 'ant-design-pro/lib/AvatarList'; - -ReactDOM.render( - - - - - -, mountNode); -```` diff --git a/src/components/AvatarList/index.d.ts b/src/components/AvatarList/index.d.ts deleted file mode 100644 index f49ca010d9fe19febd4eaed391278012109dd444..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/index.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import * as React from 'react'; -import AvatarItem from './AvatarItem'; - -export interface IAvatarListProps { - size?: 'large' | 'small' | 'mini' | 'default'; - maxLength?: number; - excessItemsStyle?: React.CSSProperties; - style?: React.CSSProperties; - children: React.ReactElement | Array>; -} - -export default class AvatarList extends React.Component { - public static Item: typeof AvatarItem; -} diff --git a/src/components/AvatarList/index.en-US.md b/src/components/AvatarList/index.en-US.md deleted file mode 100644 index 7fc39cc2b72efe91689637bca3603eeb3f2634cf..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/index.en-US.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: AvatarList -order: 1 -cols: 1 ---- - -A list of user's avatar for project or group member list frequently. If a large or small AvatarList is desired, set the `size` property to either `large` or `small` and `mini` respectively. Omit the `size` property for a AvatarList with the default size. - -## API - -### AvatarList - -| Property | Description | Type | Default | -| ---------------- | --------------------- | ---------------------------------- | --------- | -| size | size of list | `large`、`small` 、`mini`, `default` | `default` | -| maxLength | max items to show | number | - | -| excessItemsStyle | the excess item style | CSSProperties | - | - -### AvatarList.Item - -| Property | Description | Type | Default | -| -------- | -------------------------------------------- | --------- | ------- | -| tips | title tips for avatar item | ReactNode | - | -| src | the address of the image for an image avatar | string | - | diff --git a/src/components/AvatarList/index.js b/src/components/AvatarList/index.js deleted file mode 100644 index 9af32bcfdaea12c35cdaabda302be4b57622aafd..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/index.js +++ /dev/null @@ -1,61 +0,0 @@ -import React from 'react'; -import { Tooltip, Avatar } from 'antd'; -import classNames from 'classnames'; - -import styles from './index.less'; - -const avatarSizeToClassName = size => - classNames(styles.avatarItem, { - [styles.avatarItemLarge]: size === 'large', - [styles.avatarItemSmall]: size === 'small', - [styles.avatarItemMini]: size === 'mini', - }); - -const AvatarList = ({ children, size, maxLength, excessItemsStyle, ...other }) => { - const numOfChildren = React.Children.count(children); - const numToShow = maxLength >= numOfChildren ? numOfChildren : maxLength; - - const childrenWithProps = React.Children.toArray(children) - .slice(0, numToShow) - .map(child => - React.cloneElement(child, { - size, - }) - ); - - if (numToShow < numOfChildren) { - const cls = avatarSizeToClassName(size); - - childrenWithProps.push( - - {`+${numOfChildren - maxLength}`} - - ); - } - - return ( - - {childrenWithProps} - - ); -}; - -const Item = ({ src, size, tips, onClick = () => {} }) => { - const cls = avatarSizeToClassName(size); - - return ( - - {tips ? ( - - - - ) : ( - - )} - - ); -}; - -AvatarList.Item = Item; - -export default AvatarList; diff --git a/src/components/AvatarList/index.less b/src/components/AvatarList/index.less deleted file mode 100644 index 31d670565bd82fe8b08138d5dfa1d8082682aaa8..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/index.less +++ /dev/null @@ -1,50 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.avatarList { - display: inline-block; - ul { - display: inline-block; - margin-left: 8px; - font-size: 0; - } -} - -.avatarItem { - display: inline-block; - font-size: @font-size-base; - margin-left: -8px; - width: @avatar-size-base; - height: @avatar-size-base; - :global { - .ant-avatar { - border: 1px solid #fff; - } - } -} - -.avatarItemLarge { - width: @avatar-size-lg; - height: @avatar-size-lg; -} - -.avatarItemSmall { - width: @avatar-size-sm; - height: @avatar-size-sm; -} - -.avatarItemMini { - width: 20px; - height: 20px; - :global { - .ant-avatar { - width: 20px; - height: 20px; - line-height: 20px; - - .ant-avatar-string { - font-size: 12px; - line-height: 18px; - } - } - } -} diff --git a/src/components/AvatarList/index.test.js b/src/components/AvatarList/index.test.js deleted file mode 100644 index 2b5bc438d882fc608a1e25869118e01c38a4484c..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/index.test.js +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; -import range from 'lodash/range'; -import { mount } from 'enzyme'; -import AvatarList from './index'; - -const renderItems = numItems => - range(numItems).map(i => ( - - )); - -describe('AvatarList', () => { - it('renders all items', () => { - const wrapper = mount({renderItems(4)}); - expect(wrapper.find('AvatarList').length).toBe(1); - expect(wrapper.find('Item').length).toBe(4); - expect(wrapper.findWhere(node => node.key() === 'exceed').length).toBe(0); - }); - - it('renders max of 3 items', () => { - const wrapper = mount({renderItems(4)}); - expect(wrapper.find('AvatarList').length).toBe(1); - expect(wrapper.find('Item').length).toBe(3); - expect(wrapper.findWhere(node => node.key() === 'exceed').length).toBe(1); - }); -}); diff --git a/src/components/AvatarList/index.zh-CN.md b/src/components/AvatarList/index.zh-CN.md deleted file mode 100644 index bdab181ce0ed6f1ff8d07422672085410033a815..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/index.zh-CN.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: AvatarList -subtitle: 用户头像列表 -order: 1 -cols: 1 ---- - -一组用户头像,常用在项目/团队成员列表。可通过设置 `size` 属性来指定头像大小。 - -## API - -### AvatarList - -| 参数 | 说明 | 类型 | 默认值 | -| ---------------- | -------- | ---------------------------------- | --------- | -| size | 头像大小 | `large`、`small` 、`mini`, `default` | `default` | -| maxLength | 要显示的最大项目 | number | - | -| excessItemsStyle | 多余的项目风格 | CSSProperties | - | - -### AvatarList.Item - -| 参数 | 说明 | 类型 | 默认值 | -| ---- | ------ | --------- | --- | -| tips | 头像展示文案 | ReactNode | - | -| src | 头像图片连接 | string | - | diff --git a/src/components/Charts/Bar/index.d.ts b/src/components/Charts/Bar/index.d.ts deleted file mode 100644 index 4899082509dacb84701bb2e02fbe69ba1d06e149..0000000000000000000000000000000000000000 --- a/src/components/Charts/Bar/index.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from 'react'; -export interface IBarProps { - title: React.ReactNode; - color?: string; - padding?: [number, number, number, number]; - height: number; - data: Array<{ - x: string; - y: number; - }>; - autoLabel?: boolean; - style?: React.CSSProperties; -} - -export default class Bar extends React.Component {} diff --git a/src/components/Charts/Bar/index.js b/src/components/Charts/Bar/index.js deleted file mode 100644 index f0cb65ffee74014dafdb286d2dcc42043ec13c08..0000000000000000000000000000000000000000 --- a/src/components/Charts/Bar/index.js +++ /dev/null @@ -1,113 +0,0 @@ -import React, { Component } from 'react'; -import { Chart, Axis, Tooltip, Geom } from 'bizcharts'; -import Debounce from 'lodash-decorators/debounce'; -import Bind from 'lodash-decorators/bind'; -import autoHeight from '../autoHeight'; -import styles from '../index.less'; - -@autoHeight() -class Bar extends Component { - state = { - autoHideXLabels: false, - }; - - componentDidMount() { - window.addEventListener('resize', this.resize, { passive: true }); - } - - componentWillUnmount() { - window.removeEventListener('resize', this.resize); - } - - handleRoot = n => { - this.root = n; - }; - - handleRef = n => { - this.node = n; - }; - - @Bind() - @Debounce(400) - resize() { - if (!this.node) { - return; - } - const canvasWidth = this.node.parentNode.clientWidth; - const { data = [], autoLabel = true } = this.props; - if (!autoLabel) { - return; - } - const minWidth = data.length * 30; - const { autoHideXLabels } = this.state; - - if (canvasWidth <= minWidth) { - if (!autoHideXLabels) { - this.setState({ - autoHideXLabels: true, - }); - } - } else if (autoHideXLabels) { - this.setState({ - autoHideXLabels: false, - }); - } - } - - render() { - const { - height, - title, - forceFit = true, - data, - color = 'rgba(24, 144, 255, 0.85)', - padding, - } = this.props; - - const { autoHideXLabels } = this.state; - - const scale = { - x: { - type: 'cat', - }, - y: { - min: 0, - }, - }; - - const tooltip = [ - 'x*y', - (x, y) => ({ - name: x, - value: y, - }), - ]; - - return ( - - - {title && {title}} - - - - - - - - - ); - } -} - -export default Bar; diff --git a/src/components/Charts/ChartCard/index.d.ts b/src/components/Charts/ChartCard/index.d.ts deleted file mode 100644 index 0437c0c857d7f1c63c506c5eb238583a251714d0..0000000000000000000000000000000000000000 --- a/src/components/Charts/ChartCard/index.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { CardProps } from 'antd/lib/card'; -import * as React from 'react'; - -export interface IChartCardProps extends CardProps { - title: React.ReactNode; - action?: React.ReactNode; - total?: React.ReactNode | number | (() => React.ReactNode | number); - footer?: React.ReactNode; - contentHeight?: number; - avatar?: React.ReactNode; - style?: React.CSSProperties; -} - -export default class ChartCard extends React.Component {} diff --git a/src/components/Charts/ChartCard/index.js b/src/components/Charts/ChartCard/index.js deleted file mode 100644 index ca6bcb2e6d85a657e399ea39fa31df53aaadd608..0000000000000000000000000000000000000000 --- a/src/components/Charts/ChartCard/index.js +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react'; -import { Card } from 'antd'; -import classNames from 'classnames'; - -import styles from './index.less'; - -const renderTotal = total => { - let totalDom; - switch (typeof total) { - case 'undefined': - totalDom = null; - break; - case 'function': - totalDom = {total()}; - break; - default: - totalDom = {total}; - } - return totalDom; -}; - -class ChartCard extends React.PureComponent { - renderConnet = () => { - const { contentHeight, title, avatar, action, total, footer, children, loading } = this.props; - if (loading) { - return false; - } - return ( - - - {avatar} - - - {title} - {action} - - {renderTotal(total)} - - - {children && ( - - {children} - - )} - {footer && ( - - {footer} - - )} - - ); - }; - - render() { - const { - loading = false, - contentHeight, - title, - avatar, - action, - total, - footer, - children, - ...rest - } = this.props; - return ( - - {this.renderConnet()} - - ); - } -} - -export default ChartCard; diff --git a/src/components/Charts/ChartCard/index.less b/src/components/Charts/ChartCard/index.less deleted file mode 100644 index 0ddc486b9433457b83cc8813d6f02a100ec2d58f..0000000000000000000000000000000000000000 --- a/src/components/Charts/ChartCard/index.less +++ /dev/null @@ -1,75 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.chartCard { - position: relative; - .chartTop { - position: relative; - overflow: hidden; - width: 100%; - } - .chartTopMargin { - margin-bottom: 12px; - } - .chartTopHasMargin { - margin-bottom: 20px; - } - .metaWrap { - float: left; - } - .avatar { - position: relative; - top: 4px; - float: left; - margin-right: 20px; - img { - border-radius: 100%; - } - } - .meta { - color: @text-color-secondary; - font-size: @font-size-base; - line-height: 22px; - height: 22px; - } - .action { - cursor: pointer; - position: absolute; - top: 4px; - right: 0; - line-height: 1; - } - .total { - overflow: hidden; - text-overflow: ellipsis; - word-break: break-all; - white-space: nowrap; - color: @heading-color; - margin-top: 4px; - margin-bottom: 0; - font-size: 30px; - line-height: 38px; - height: 38px; - } - .content { - margin-bottom: 12px; - position: relative; - width: 100%; - } - .contentFixed { - position: absolute; - left: 0; - bottom: 0; - width: 100%; - } - .footer { - border-top: 1px solid @border-color-split; - padding-top: 9px; - margin-top: 8px; - & > * { - position: relative; - } - } - .footerMargin { - margin-top: 20px; - } -} diff --git a/src/components/Charts/Field/index.d.ts b/src/components/Charts/Field/index.d.ts deleted file mode 100644 index 975fb667d8db178c1154162f4803e20f1c72a8e4..0000000000000000000000000000000000000000 --- a/src/components/Charts/Field/index.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import * as React from 'react'; -export interface IFieldProps { - label: React.ReactNode; - value: React.ReactNode; - style?: React.CSSProperties; -} - -export default class Field extends React.Component {} diff --git a/src/components/Charts/Field/index.js b/src/components/Charts/Field/index.js deleted file mode 100644 index 22dca86c0dd6ede80de52ca7c124afa12fda4a13..0000000000000000000000000000000000000000 --- a/src/components/Charts/Field/index.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react'; - -import styles from './index.less'; - -const Field = ({ label, value, ...rest }) => ( - - {label} - {value} - -); - -export default Field; diff --git a/src/components/Charts/Field/index.less b/src/components/Charts/Field/index.less deleted file mode 100644 index 170ddc1d85fd4f1e6dd9f909e481341408269c94..0000000000000000000000000000000000000000 --- a/src/components/Charts/Field/index.less +++ /dev/null @@ -1,17 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.field { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - margin: 0; - .label, - .number { - font-size: @font-size-base; - line-height: 22px; - } - .number { - color: @heading-color; - margin-left: 8px; - } -} diff --git a/src/components/Charts/Gauge/index.d.ts b/src/components/Charts/Gauge/index.d.ts deleted file mode 100644 index 66e3c003a957581d88a06e63b32a7a3e76c5cd3a..0000000000000000000000000000000000000000 --- a/src/components/Charts/Gauge/index.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as React from 'react'; -export interface IGaugeProps { - title: React.ReactNode; - color?: string; - height: number; - bgColor?: number; - percent: number; - style?: React.CSSProperties; -} - -export default class Gauge extends React.Component {} diff --git a/src/components/Charts/Gauge/index.js b/src/components/Charts/Gauge/index.js deleted file mode 100644 index 2249211aeaad53652d578c8dc050a60795129b68..0000000000000000000000000000000000000000 --- a/src/components/Charts/Gauge/index.js +++ /dev/null @@ -1,167 +0,0 @@ -import React from 'react'; -import { Chart, Geom, Axis, Coord, Guide, Shape } from 'bizcharts'; -import autoHeight from '../autoHeight'; - -const { Arc, Html, Line } = Guide; - -const defaultFormatter = val => { - switch (val) { - case '2': - return '差'; - case '4': - return '中'; - case '6': - return '良'; - case '8': - return '优'; - default: - return ''; - } -}; - -Shape.registerShape('point', 'pointer', { - drawShape(cfg, group) { - let point = cfg.points[0]; - point = this.parsePoint(point); - const center = this.parsePoint({ - x: 0, - y: 0, - }); - group.addShape('line', { - attrs: { - x1: center.x, - y1: center.y, - x2: point.x, - y2: point.y, - stroke: cfg.color, - lineWidth: 2, - lineCap: 'round', - }, - }); - return group.addShape('circle', { - attrs: { - x: center.x, - y: center.y, - r: 6, - stroke: cfg.color, - lineWidth: 3, - fill: '#fff', - }, - }); - }, -}); - -@autoHeight() -class Gauge extends React.Component { - render() { - const { - title, - height, - percent, - forceFit = true, - formatter = defaultFormatter, - color = '#2F9CFF', - bgColor = '#F0F2F5', - } = this.props; - const cols = { - value: { - type: 'linear', - min: 0, - max: 10, - tickCount: 6, - nice: true, - }, - }; - const data = [{ value: percent / 10 }]; - return ( - - - - - - - - - - - ` - - ${title} - - ${data[0].value * 10}% - - `} - /> - - - - ); - } -} - -export default Gauge; diff --git a/src/components/Charts/MiniArea/index.d.ts b/src/components/Charts/MiniArea/index.d.ts deleted file mode 100644 index b223b68ca097e01f1c76e4e2cb4e95e9db4dc39b..0000000000000000000000000000000000000000 --- a/src/components/Charts/MiniArea/index.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from 'react'; - -// g2已经更新到3.0 -// 不带的写了 - -export interface IAxis { - title: any; - line: any; - gridAlign: any; - labels: any; - tickLine: any; - grid: any; -} - -export interface IMiniAreaProps { - color?: string; - height: number; - borderColor?: string; - line?: boolean; - animate?: boolean; - xAxis?: IAxis; - yAxis?: IAxis; - data: Array<{ - x: number | string; - y: number; - }>; -} - -export default class MiniArea extends React.Component {} diff --git a/src/components/Charts/MiniArea/index.js b/src/components/Charts/MiniArea/index.js deleted file mode 100644 index d3209becaeed2f3069267b08c16cf9bbb3672be0..0000000000000000000000000000000000000000 --- a/src/components/Charts/MiniArea/index.js +++ /dev/null @@ -1,108 +0,0 @@ -import React from 'react'; -import { Chart, Axis, Tooltip, Geom } from 'bizcharts'; -import autoHeight from '../autoHeight'; -import styles from '../index.less'; - -@autoHeight() -class MiniArea extends React.PureComponent { - render() { - const { - height, - data = [], - forceFit = true, - color = 'rgba(24, 144, 255, 0.2)', - borderColor = '#1089ff', - scale = {}, - borderWidth = 2, - line, - xAxis, - yAxis, - animate = true, - } = this.props; - - const padding = [36, 5, 30, 5]; - - const scaleProps = { - x: { - type: 'cat', - range: [0, 1], - ...scale.x, - }, - y: { - min: 0, - ...scale.y, - }, - }; - - const tooltip = [ - 'x*y', - (x, y) => ({ - name: x, - value: y, - }), - ]; - - const chartHeight = height + 54; - - return ( - - - {height > 0 && ( - - - - - - {line ? ( - - ) : ( - - )} - - )} - - - ); - } -} - -export default MiniArea; diff --git a/src/components/Charts/MiniBar/index.d.ts b/src/components/Charts/MiniBar/index.d.ts deleted file mode 100644 index 0c4bd6cce558f4b948691c553c65d76c8c34fc6b..0000000000000000000000000000000000000000 --- a/src/components/Charts/MiniBar/index.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import * as React from 'react'; -export interface IMiniBarProps { - color?: string; - height: number; - data: Array<{ - x: number | string; - y: number; - }>; - style?: React.CSSProperties; -} - -export default class MiniBar extends React.Component {} diff --git a/src/components/Charts/MiniBar/index.js b/src/components/Charts/MiniBar/index.js deleted file mode 100644 index 18e4d8c6fba2322b9ee75a9522fa40cd8315463d..0000000000000000000000000000000000000000 --- a/src/components/Charts/MiniBar/index.js +++ /dev/null @@ -1,51 +0,0 @@ -import React from 'react'; -import { Chart, Tooltip, Geom } from 'bizcharts'; -import autoHeight from '../autoHeight'; -import styles from '../index.less'; - -@autoHeight() -class MiniBar extends React.Component { - render() { - const { height, forceFit = true, color = '#1890FF', data = [] } = this.props; - - const scale = { - x: { - type: 'cat', - }, - y: { - min: 0, - }, - }; - - const padding = [36, 5, 30, 5]; - - const tooltip = [ - 'x*y', - (x, y) => ({ - name: x, - value: y, - }), - ]; - - // for tooltip not to be hide - const chartHeight = height + 54; - - return ( - - - - - - - - - ); - } -} -export default MiniBar; diff --git a/src/components/Charts/MiniProgress/index.d.ts b/src/components/Charts/MiniProgress/index.d.ts deleted file mode 100644 index aaeb7261d7ea06dfad935faf7c00238035ea921d..0000000000000000000000000000000000000000 --- a/src/components/Charts/MiniProgress/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as React from 'react'; -export interface IMiniProgressProps { - target: number; - color?: string; - strokeWidth?: number; - percent?: number; - style?: React.CSSProperties; -} - -export default class MiniProgress extends React.Component {} diff --git a/src/components/Charts/MiniProgress/index.js b/src/components/Charts/MiniProgress/index.js deleted file mode 100644 index 795c79b15951e2bdde85c0a6fa1427ba46c8df1c..0000000000000000000000000000000000000000 --- a/src/components/Charts/MiniProgress/index.js +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; -import { Tooltip } from 'antd'; - -import styles from './index.less'; - -const MiniProgress = ({ target, color = 'rgb(19, 194, 194)', strokeWidth, percent }) => ( - - - - - - - - - - - -); - -export default MiniProgress; diff --git a/src/components/Charts/MiniProgress/index.less b/src/components/Charts/MiniProgress/index.less deleted file mode 100644 index e5f148cbf532e6a0715364009f5a2c2c085d1d43..0000000000000000000000000000000000000000 --- a/src/components/Charts/MiniProgress/index.less +++ /dev/null @@ -1,35 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.miniProgress { - padding: 5px 0; - position: relative; - width: 100%; - .progressWrap { - background-color: @background-color-base; - position: relative; - } - .progress { - transition: all 0.4s cubic-bezier(0.08, 0.82, 0.17, 1) 0s; - border-radius: 1px 0 0 1px; - background-color: @primary-color; - width: 0; - height: 100%; - } - .target { - position: absolute; - top: 0; - bottom: 0; - span { - border-radius: 100px; - position: absolute; - top: 0; - left: 0; - height: 4px; - width: 2px; - } - span:last-child { - top: auto; - bottom: 0; - } - } -} diff --git a/src/components/Charts/Pie/index.d.ts b/src/components/Charts/Pie/index.d.ts deleted file mode 100644 index 66c93eeb5d856928697335530c090c68492e81a5..0000000000000000000000000000000000000000 --- a/src/components/Charts/Pie/index.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react'; -export interface IPieProps { - animate?: boolean; - color?: string; - colors?: string[]; - height: number; - hasLegend?: boolean; - padding?: [number, number, number, number]; - percent?: number; - data?: Array<{ - x: string | string; - y: number; - }>; - total?: React.ReactNode | number | (() => React.ReactNode | number); - title?: React.ReactNode; - tooltip?: boolean; - valueFormat?: (value: string) => string | React.ReactNode; - subTitle?: React.ReactNode; -} - -export default class Pie extends React.Component {} diff --git a/src/components/Charts/Pie/index.js b/src/components/Charts/Pie/index.js deleted file mode 100644 index 7dff5123f30d1937550e0c042953aee5392ee1fe..0000000000000000000000000000000000000000 --- a/src/components/Charts/Pie/index.js +++ /dev/null @@ -1,271 +0,0 @@ -import React, { Component } from 'react'; -import { Chart, Tooltip, Geom, Coord } from 'bizcharts'; -import { DataView } from '@antv/data-set'; -import { Divider } from 'antd'; -import classNames from 'classnames'; -import ReactFitText from 'react-fittext'; -import Debounce from 'lodash-decorators/debounce'; -import Bind from 'lodash-decorators/bind'; -import autoHeight from '../autoHeight'; - -import styles from './index.less'; - -/* eslint react/no-danger:0 */ -@autoHeight() -class Pie extends Component { - state = { - legendData: [], - legendBlock: false, - }; - - componentDidMount() { - window.addEventListener( - 'resize', - () => { - this.requestRef = requestAnimationFrame(() => this.resize()); - }, - { passive: true } - ); - } - - componentDidUpdate(preProps) { - const { data } = this.props; - if (data !== preProps.data) { - // because of charts data create when rendered - // so there is a trick for get rendered time - this.getLegendData(); - } - } - - componentWillUnmount() { - window.cancelAnimationFrame(this.requestRef); - window.removeEventListener('resize', this.resize); - this.resize.cancel(); - } - - getG2Instance = chart => { - this.chart = chart; - requestAnimationFrame(() => { - this.getLegendData(); - this.resize(); - }); - }; - - // for custom lengend view - getLegendData = () => { - if (!this.chart) return; - const geom = this.chart.getAllGeoms()[0]; // 获取所有的图形 - if (!geom) return; - const items = geom.get('dataArray') || []; // 获取图形对应的 - - const legendData = items.map(item => { - /* eslint no-underscore-dangle:0 */ - const origin = item[0]._origin; - origin.color = item[0].color; - origin.checked = true; - return origin; - }); - - this.setState({ - legendData, - }); - }; - - handleRoot = n => { - this.root = n; - }; - - handleLegendClick = (item, i) => { - const newItem = item; - newItem.checked = !newItem.checked; - - const { legendData } = this.state; - legendData[i] = newItem; - - const filteredLegendData = legendData.filter(l => l.checked).map(l => l.x); - - if (this.chart) { - this.chart.filter('x', val => filteredLegendData.indexOf(val) > -1); - } - - this.setState({ - legendData, - }); - }; - - // for window resize auto responsive legend - @Bind() - @Debounce(300) - resize() { - const { hasLegend } = this.props; - const { legendBlock } = this.state; - if (!hasLegend || !this.root) { - window.removeEventListener('resize', this.resize); - return; - } - if (this.root.parentNode.clientWidth <= 380) { - if (!legendBlock) { - this.setState({ - legendBlock: true, - }); - } - } else if (legendBlock) { - this.setState({ - legendBlock: false, - }); - } - } - - render() { - const { - valueFormat, - subTitle, - total, - hasLegend = false, - className, - style, - height, - forceFit = true, - percent, - color, - inner = 0.75, - animate = true, - colors, - lineWidth = 1, - } = this.props; - - const { legendData, legendBlock } = this.state; - const pieClassName = classNames(styles.pie, className, { - [styles.hasLegend]: !!hasLegend, - [styles.legendBlock]: legendBlock, - }); - - const { - data: propsData, - selected: propsSelected = true, - tooltip: propsTooltip = true, - } = this.props; - - let data = propsData || []; - let selected = propsSelected; - let tooltip = propsTooltip; - - const defaultColors = colors; - data = data || []; - selected = selected || true; - tooltip = tooltip || true; - let formatColor; - - const scale = { - x: { - type: 'cat', - range: [0, 1], - }, - y: { - min: 0, - }, - }; - - if (percent || percent === 0) { - selected = false; - tooltip = false; - formatColor = value => { - if (value === '占比') { - return color || 'rgba(24, 144, 255, 0.85)'; - } - return '#F0F2F5'; - }; - - data = [ - { - x: '占比', - y: parseFloat(percent), - }, - { - x: '反比', - y: 100 - parseFloat(percent), - }, - ]; - } - - const tooltipFormat = [ - 'x*percent', - (x, p) => ({ - name: x, - value: `${(p * 100).toFixed(2)}%`, - }), - ]; - - const padding = [12, 0, 12, 0]; - - const dv = new DataView(); - dv.source(data).transform({ - type: 'percent', - field: 'y', - dimension: 'x', - as: 'percent', - }); - - return ( - - - - - {!!tooltip && } - - - - - {(subTitle || total) && ( - - {subTitle && {subTitle}} - {/* eslint-disable-next-line */} - {total && ( - {typeof total === 'function' ? total() : total} - )} - - )} - - - - {hasLegend && ( - - {legendData.map((item, i) => ( - this.handleLegendClick(item, i)}> - - {item.x} - - - {`${(Number.isNaN(item.percent) ? 0 : item.percent * 100).toFixed(2)}%`} - - {valueFormat ? valueFormat(item.y) : item.y} - - ))} - - )} - - ); - } -} - -export default Pie; diff --git a/src/components/Charts/Pie/index.less b/src/components/Charts/Pie/index.less deleted file mode 100644 index 7249d0930905d4bd6d15e08f5cfdd69237717cd4..0000000000000000000000000000000000000000 --- a/src/components/Charts/Pie/index.less +++ /dev/null @@ -1,94 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.pie { - position: relative; - .chart { - position: relative; - } - &.hasLegend .chart { - width: ~'calc(100% - 240px)'; - } - .legend { - position: absolute; - right: 0; - min-width: 200px; - top: 50%; - transform: translateY(-50%); - margin: 0 20px; - list-style: none; - padding: 0; - li { - cursor: pointer; - margin-bottom: 16px; - height: 22px; - line-height: 22px; - &:last-child { - margin-bottom: 0; - } - } - } - .dot { - border-radius: 8px; - display: inline-block; - margin-right: 8px; - position: relative; - top: -1px; - height: 8px; - width: 8px; - } - .line { - background-color: @border-color-split; - display: inline-block; - margin-right: 8px; - width: 1px; - height: 16px; - } - .legendTitle { - color: @text-color; - } - .percent { - color: @text-color-secondary; - } - .value { - position: absolute; - right: 0; - } - .title { - margin-bottom: 8px; - } - .total { - position: absolute; - left: 50%; - top: 50%; - text-align: center; - max-height: 62px; - transform: translate(-50%, -50%); - & > h4 { - color: @text-color-secondary; - font-size: 14px; - line-height: 22px; - height: 22px; - margin-bottom: 8px; - font-weight: normal; - } - & > p { - color: @heading-color; - display: block; - font-size: 1.2em; - height: 32px; - line-height: 32px; - white-space: nowrap; - } - } -} - -.legendBlock { - &.hasLegend .chart { - width: 100%; - margin: 0 0 32px 0; - } - .legend { - position: relative; - transform: none; - } -} diff --git a/src/components/Charts/Radar/index.d.ts b/src/components/Charts/Radar/index.d.ts deleted file mode 100644 index 963ac8c37c112c360cd399b039d790e53b83a2a3..0000000000000000000000000000000000000000 --- a/src/components/Charts/Radar/index.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from 'react'; -export interface IRadarProps { - title?: React.ReactNode; - height: number; - padding?: [number, number, number, number]; - hasLegend?: boolean; - data: Array<{ - name: string; - label: string; - value: string; - }>; - style?: React.CSSProperties; -} - -export default class Radar extends React.Component {} diff --git a/src/components/Charts/Radar/index.js b/src/components/Charts/Radar/index.js deleted file mode 100644 index a0aa7fab6ea82dde0e9202d5315d9df80e18e806..0000000000000000000000000000000000000000 --- a/src/components/Charts/Radar/index.js +++ /dev/null @@ -1,184 +0,0 @@ -import React, { Component } from 'react'; -import { Chart, Tooltip, Geom, Coord, Axis } from 'bizcharts'; -import { Row, Col } from 'antd'; -import autoHeight from '../autoHeight'; -import styles from './index.less'; - -/* eslint react/no-danger:0 */ -@autoHeight() -class Radar extends Component { - state = { - legendData: [], - }; - - componentDidMount() { - this.getLegendData(); - } - - componentDidUpdate(preProps) { - const { data } = this.props; - if (data !== preProps.data) { - this.getLegendData(); - } - } - - getG2Instance = chart => { - this.chart = chart; - }; - - // for custom lengend view - getLegendData = () => { - if (!this.chart) return; - const geom = this.chart.getAllGeoms()[0]; // 获取所有的图形 - if (!geom) return; - const items = geom.get('dataArray') || []; // 获取图形对应的 - - const legendData = items.map(item => { - // eslint-disable-next-line - const origins = item.map(t => t._origin); - const result = { - name: origins[0].name, - color: item[0].color, - checked: true, - value: origins.reduce((p, n) => p + n.value, 0), - }; - - return result; - }); - - this.setState({ - legendData, - }); - }; - - handleRef = n => { - this.node = n; - }; - - handleLegendClick = (item, i) => { - const newItem = item; - newItem.checked = !newItem.checked; - - const { legendData } = this.state; - legendData[i] = newItem; - - const filteredLegendData = legendData.filter(l => l.checked).map(l => l.name); - - if (this.chart) { - this.chart.filter('name', val => filteredLegendData.indexOf(val) > -1); - this.chart.repaint(); - } - - this.setState({ - legendData, - }); - }; - - render() { - const defaultColors = [ - '#1890FF', - '#FACC14', - '#2FC25B', - '#8543E0', - '#F04864', - '#13C2C2', - '#fa8c16', - '#a0d911', - ]; - - const { - data = [], - height = 0, - title, - hasLegend = false, - forceFit = true, - tickCount = 5, - padding = [35, 30, 16, 30], - animate = true, - colors = defaultColors, - } = this.props; - - const { legendData } = this.state; - - const scale = { - value: { - min: 0, - tickCount, - }, - }; - - const chartHeight = height - (hasLegend ? 80 : 22); - - return ( - - {title && {title}} - - - - - - - - - {hasLegend && ( - - {legendData.map((item, i) => ( - this.handleLegendClick(item, i)} - > - - - - {item.name} - - {item.value} - - - ))} - - )} - - ); - } -} - -export default Radar; diff --git a/src/components/Charts/Radar/index.less b/src/components/Charts/Radar/index.less deleted file mode 100644 index 15b8725ca7f084bb7cd662fd3cd44138fe928d81..0000000000000000000000000000000000000000 --- a/src/components/Charts/Radar/index.less +++ /dev/null @@ -1,46 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.radar { - .legend { - margin-top: 16px; - .legendItem { - position: relative; - text-align: center; - cursor: pointer; - color: @text-color-secondary; - line-height: 22px; - p { - margin: 0; - } - h6 { - color: @heading-color; - padding-left: 16px; - font-size: 24px; - line-height: 32px; - margin-top: 4px; - margin-bottom: 0; - } - &:after { - background-color: @border-color-split; - position: absolute; - top: 8px; - right: 0; - height: 40px; - width: 1px; - content: ''; - } - } - > :last-child .legendItem:after { - display: none; - } - .dot { - border-radius: 6px; - display: inline-block; - margin-right: 6px; - position: relative; - top: -1px; - height: 6px; - width: 6px; - } - } -} diff --git a/src/components/Charts/TagCloud/index.d.ts b/src/components/Charts/TagCloud/index.d.ts deleted file mode 100644 index 462650c4dbb7532670d200141f7cbebc52525808..0000000000000000000000000000000000000000 --- a/src/components/Charts/TagCloud/index.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as React from 'react'; -export interface ITagCloudProps { - data: Array<{ - name: string; - value: number; - }>; - height: number; - style?: React.CSSProperties; -} - -export default class TagCloud extends React.Component {} diff --git a/src/components/Charts/TagCloud/index.js b/src/components/Charts/TagCloud/index.js deleted file mode 100644 index d94699bd551c0c33319bd3d61eac2c4edb613bbe..0000000000000000000000000000000000000000 --- a/src/components/Charts/TagCloud/index.js +++ /dev/null @@ -1,182 +0,0 @@ -import React, { Component } from 'react'; -import { Chart, Geom, Coord, Shape, Tooltip } from 'bizcharts'; -import DataSet from '@antv/data-set'; -import Debounce from 'lodash-decorators/debounce'; -import Bind from 'lodash-decorators/bind'; -import classNames from 'classnames'; -import autoHeight from '../autoHeight'; -import styles from './index.less'; - -/* eslint no-underscore-dangle: 0 */ -/* eslint no-param-reassign: 0 */ - -const imgUrl = 'https://gw.alipayobjects.com/zos/rmsportal/gWyeGLCdFFRavBGIDzWk.png'; - -@autoHeight() -class TagCloud extends Component { - state = { - dv: null, - }; - - componentDidMount() { - requestAnimationFrame(() => { - this.initTagCloud(); - this.renderChart(); - }); - window.addEventListener('resize', this.resize, { passive: true }); - } - - componentDidUpdate(preProps) { - const { data } = this.props; - if (JSON.stringify(preProps.data) !== JSON.stringify(data)) { - this.renderChart(this.props); - } - } - - componentWillUnmount() { - this.isUnmount = true; - window.cancelAnimationFrame(this.requestRef); - window.removeEventListener('resize', this.resize); - } - - resize = () => { - this.requestRef = requestAnimationFrame(() => { - this.renderChart(); - }); - }; - - saveRootRef = node => { - this.root = node; - }; - - initTagCloud = () => { - function getTextAttrs(cfg) { - return Object.assign( - {}, - { - fillOpacity: cfg.opacity, - fontSize: cfg.origin._origin.size, - rotate: cfg.origin._origin.rotate, - text: cfg.origin._origin.text, - textAlign: 'center', - fontFamily: cfg.origin._origin.font, - fill: cfg.color, - textBaseline: 'Alphabetic', - }, - cfg.style - ); - } - - // 给point注册一个词云的shape - Shape.registerShape('point', 'cloud', { - drawShape(cfg, container) { - const attrs = getTextAttrs(cfg); - return container.addShape('text', { - attrs: Object.assign(attrs, { - x: cfg.x, - y: cfg.y, - }), - }); - }, - }); - }; - - @Bind() - @Debounce(500) - renderChart(nextProps) { - // const colors = ['#1890FF', '#41D9C7', '#2FC25B', '#FACC14', '#9AE65C']; - const { data, height } = nextProps || this.props; - - if (data.length < 1 || !this.root) { - return; - } - - const h = height; - const w = this.root.offsetWidth; - - const onload = () => { - const dv = new DataSet.View().source(data); - const range = dv.range('value'); - const [min, max] = range; - dv.transform({ - type: 'tag-cloud', - fields: ['name', 'value'], - imageMask: this.imageMask, - font: 'Verdana', - size: [w, h], // 宽高设置最好根据 imageMask 做调整 - padding: 0, - timeInterval: 5000, // max execute time - rotate() { - return 0; - }, - fontSize(d) { - // eslint-disable-next-line - return Math.pow((d.value - min) / (max - min), 2) * (17.5 - 5) + 5; - }, - }); - - if (this.isUnmount) { - return; - } - - this.setState({ - dv, - w, - h, - }); - }; - - if (!this.imageMask) { - this.imageMask = new Image(); - this.imageMask.crossOrigin = ''; - this.imageMask.src = imgUrl; - - this.imageMask.onload = onload; - } else { - onload(); - } - } - - render() { - const { className, height } = this.props; - const { dv, w, h } = this.state; - - return ( - - {dv && ( - - - - - - )} - - ); - } -} - -export default TagCloud; diff --git a/src/components/Charts/TagCloud/index.less b/src/components/Charts/TagCloud/index.less deleted file mode 100644 index db8e4dabfdd3f1fd4566ff22f55962648c369c49..0000000000000000000000000000000000000000 --- a/src/components/Charts/TagCloud/index.less +++ /dev/null @@ -1,6 +0,0 @@ -.tagCloud { - overflow: hidden; - canvas { - transform-origin: 0 0; - } -} diff --git a/src/components/Charts/TimelineChart/index.d.ts b/src/components/Charts/TimelineChart/index.d.ts deleted file mode 100644 index 40b94325a9833e9479846b323387e6515160fb7e..0000000000000000000000000000000000000000 --- a/src/components/Charts/TimelineChart/index.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import * as React from 'react'; -export interface ITimelineChartProps { - data: Array<{ - x: number; - y1: number; - y2?: number; - }>; - titleMap: { y1: string; y2?: string }; - padding?: [number, number, number, number]; - height?: number; - style?: React.CSSProperties; -} - -export default class TimelineChart extends React.Component {} diff --git a/src/components/Charts/TimelineChart/index.js b/src/components/Charts/TimelineChart/index.js deleted file mode 100644 index d82623c5805d6df526e3ab40f42ece7202ca20ff..0000000000000000000000000000000000000000 --- a/src/components/Charts/TimelineChart/index.js +++ /dev/null @@ -1,120 +0,0 @@ -import React from 'react'; -import { Chart, Tooltip, Geom, Legend, Axis } from 'bizcharts'; -import DataSet from '@antv/data-set'; -import Slider from 'bizcharts-plugin-slider'; -import autoHeight from '../autoHeight'; -import styles from './index.less'; - -@autoHeight() -class TimelineChart extends React.Component { - render() { - const { - title, - height = 400, - padding = [60, 20, 40, 40], - titleMap = { - y1: 'y1', - y2: 'y2', - }, - borderWidth = 2, - data: sourceData, - } = this.props; - - const data = Array.isArray(sourceData) ? sourceData : [{ x: 0, y1: 0, y2: 0 }]; - - data.sort((a, b) => a.x - b.x); - - let max; - if (data[0] && data[0].y1 && data[0].y2) { - max = Math.max( - [...data].sort((a, b) => b.y1 - a.y1)[0].y1, - [...data].sort((a, b) => b.y2 - a.y2)[0].y2 - ); - } - - const ds = new DataSet({ - state: { - start: data[0].x, - end: data[data.length - 1].x, - }, - }); - - const dv = ds.createView(); - dv.source(data) - .transform({ - type: 'filter', - callback: obj => { - const date = obj.x; - return date <= ds.state.end && date >= ds.state.start; - }, - }) - .transform({ - type: 'map', - callback(row) { - const newRow = { ...row }; - newRow[titleMap.y1] = row.y1; - newRow[titleMap.y2] = row.y2; - return newRow; - }, - }) - .transform({ - type: 'fold', - fields: [titleMap.y1, titleMap.y2], // 展开字段集 - key: 'key', // key字段 - value: 'value', // value字段 - }); - - const timeScale = { - type: 'time', - tickInterval: 60 * 60 * 1000, - mask: 'HH:mm', - range: [0, 1], - }; - - const cols = { - x: timeScale, - value: { - max, - min: 0, - }, - }; - - const SliderGen = () => ( - { - ds.setState('start', startValue); - ds.setState('end', endValue); - }} - /> - ); - - return ( - - - {title && {title}} - - - - - - - - - - - - ); - } -} - -export default TimelineChart; diff --git a/src/components/Charts/TimelineChart/index.less b/src/components/Charts/TimelineChart/index.less deleted file mode 100644 index 1751975692135769eebdcaf89ffafcf6b3037cb8..0000000000000000000000000000000000000000 --- a/src/components/Charts/TimelineChart/index.less +++ /dev/null @@ -1,3 +0,0 @@ -.timelineChart { - background: #fff; -} diff --git a/src/components/Charts/WaterWave/index.d.ts b/src/components/Charts/WaterWave/index.d.ts deleted file mode 100644 index 8f5588d29f29baa7a5409eded24fb2cbe82e1c53..0000000000000000000000000000000000000000 --- a/src/components/Charts/WaterWave/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as React from 'react'; -export interface IWaterWaveProps { - title: React.ReactNode; - color?: string; - height: number; - percent: number; - style?: React.CSSProperties; -} - -export default class WaterWave extends React.Component {} diff --git a/src/components/Charts/WaterWave/index.js b/src/components/Charts/WaterWave/index.js deleted file mode 100644 index 055f7c734643eee007f6c2d96fcdc5261a206426..0000000000000000000000000000000000000000 --- a/src/components/Charts/WaterWave/index.js +++ /dev/null @@ -1,213 +0,0 @@ -import React, { PureComponent } from 'react'; -import autoHeight from '../autoHeight'; -import styles from './index.less'; - -/* eslint no-return-assign: 0 */ -/* eslint no-mixed-operators: 0 */ -// riddle: https://riddle.alibaba-inc.com/riddles/2d9a4b90 - -@autoHeight() -class WaterWave extends PureComponent { - state = { - radio: 1, - }; - - componentDidMount() { - this.renderChart(); - this.resize(); - window.addEventListener( - 'resize', - () => { - requestAnimationFrame(() => this.resize()); - }, - { passive: true } - ); - } - - componentDidUpdate(props) { - const { percent } = this.props; - if (props.percent !== percent) { - // 不加这个会造成绘制缓慢 - this.renderChart('update'); - } - } - - componentWillUnmount() { - cancelAnimationFrame(this.timer); - if (this.node) { - this.node.innerHTML = ''; - } - window.removeEventListener('resize', this.resize); - } - - resize = () => { - if (this.root) { - const { height } = this.props; - const { offsetWidth } = this.root.parentNode; - this.setState({ - radio: offsetWidth < height ? offsetWidth / height : 1, - }); - } - }; - - renderChart(type) { - const { percent, color = '#1890FF' } = this.props; - const data = percent / 100; - const self = this; - cancelAnimationFrame(this.timer); - - if (!this.node || (data !== 0 && !data)) { - return; - } - - const canvas = this.node; - const ctx = canvas.getContext('2d'); - const canvasWidth = canvas.width; - const canvasHeight = canvas.height; - const radius = canvasWidth / 2; - const lineWidth = 2; - const cR = radius - lineWidth; - - ctx.beginPath(); - ctx.lineWidth = lineWidth * 2; - - const axisLength = canvasWidth - lineWidth; - const unit = axisLength / 8; - const range = 0.2; // 振幅 - let currRange = range; - const xOffset = lineWidth; - let sp = 0; // 周期偏移量 - let currData = 0; - const waveupsp = 0.005; // 水波上涨速度 - - let arcStack = []; - const bR = radius - lineWidth; - const circleOffset = -(Math.PI / 2); - let circleLock = true; - - for (let i = circleOffset; i < circleOffset + 2 * Math.PI; i += 1 / (8 * Math.PI)) { - arcStack.push([radius + bR * Math.cos(i), radius + bR * Math.sin(i)]); - } - - const cStartPoint = arcStack.shift(); - ctx.strokeStyle = color; - ctx.moveTo(cStartPoint[0], cStartPoint[1]); - - function drawSin() { - ctx.beginPath(); - ctx.save(); - - const sinStack = []; - for (let i = xOffset; i <= xOffset + axisLength; i += 20 / axisLength) { - const x = sp + (xOffset + i) / unit; - const y = Math.sin(x) * currRange; - const dx = i; - const dy = 2 * cR * (1 - currData) + (radius - cR) - unit * y; - - ctx.lineTo(dx, dy); - sinStack.push([dx, dy]); - } - - const startPoint = sinStack.shift(); - - ctx.lineTo(xOffset + axisLength, canvasHeight); - ctx.lineTo(xOffset, canvasHeight); - ctx.lineTo(startPoint[0], startPoint[1]); - - const gradient = ctx.createLinearGradient(0, 0, 0, canvasHeight); - gradient.addColorStop(0, '#ffffff'); - gradient.addColorStop(1, color); - ctx.fillStyle = gradient; - ctx.fill(); - ctx.restore(); - } - - function render() { - ctx.clearRect(0, 0, canvasWidth, canvasHeight); - if (circleLock && type !== 'update') { - if (arcStack.length) { - const temp = arcStack.shift(); - ctx.lineTo(temp[0], temp[1]); - ctx.stroke(); - } else { - circleLock = false; - ctx.lineTo(cStartPoint[0], cStartPoint[1]); - ctx.stroke(); - arcStack = null; - - ctx.globalCompositeOperation = 'destination-over'; - ctx.beginPath(); - ctx.lineWidth = lineWidth; - ctx.arc(radius, radius, bR, 0, 2 * Math.PI, 1); - - ctx.beginPath(); - ctx.save(); - ctx.arc(radius, radius, radius - 3 * lineWidth, 0, 2 * Math.PI, 1); - - ctx.restore(); - ctx.clip(); - ctx.fillStyle = color; - } - } else { - if (data >= 0.85) { - if (currRange > range / 4) { - const t = range * 0.01; - currRange -= t; - } - } else if (data <= 0.1) { - if (currRange < range * 1.5) { - const t = range * 0.01; - currRange += t; - } - } else { - if (currRange <= range) { - const t = range * 0.01; - currRange += t; - } - if (currRange >= range) { - const t = range * 0.01; - currRange -= t; - } - } - if (data - currData > 0) { - currData += waveupsp; - } - if (data - currData < 0) { - currData -= waveupsp; - } - - sp += 0.07; - drawSin(); - } - self.timer = requestAnimationFrame(render); - } - render(); - } - - render() { - const { radio } = this.state; - const { percent, title, height } = this.props; - return ( - (this.root = n)} - style={{ transform: `scale(${radio})` }} - > - - (this.node = n)} - width={height * 2} - height={height * 2} - /> - - - {title && {title}} - {percent}% - - - ); - } -} - -export default WaterWave; diff --git a/src/components/Charts/WaterWave/index.less b/src/components/Charts/WaterWave/index.less deleted file mode 100644 index 43ba05cabd9526fa5d795b8ef840dd8b58e70afc..0000000000000000000000000000000000000000 --- a/src/components/Charts/WaterWave/index.less +++ /dev/null @@ -1,28 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.waterWave { - display: inline-block; - position: relative; - transform-origin: left; - .text { - position: absolute; - left: 0; - top: 32px; - text-align: center; - width: 100%; - span { - color: @text-color-secondary; - font-size: 14px; - line-height: 22px; - } - h4 { - color: @heading-color; - line-height: 32px; - font-size: 24px; - } - } - .waterWaveCanvasWrapper { - transform: scale(0.5); - transform-origin: 0 0; - } -} diff --git a/src/components/Charts/autoHeight.js b/src/components/Charts/autoHeight.js deleted file mode 100644 index 6ee9e098d3d926650f0f4ce6bfcd0cb3483c26ed..0000000000000000000000000000000000000000 --- a/src/components/Charts/autoHeight.js +++ /dev/null @@ -1,62 +0,0 @@ -/* eslint eqeqeq: 0 */ -import React from 'react'; - -function computeHeight(node) { - const totalHeight = parseInt(getComputedStyle(node).height, 10); - const padding = - parseInt(getComputedStyle(node).paddingTop, 10) + - parseInt(getComputedStyle(node).paddingBottom, 10); - return totalHeight - padding; -} - -function getAutoHeight(n) { - if (!n) { - return 0; - } - - let node = n; - - let height = computeHeight(node); - - while (!height) { - node = node.parentNode; - if (node) { - height = computeHeight(node); - } else { - break; - } - } - - return height; -} - -const autoHeight = () => WrappedComponent => - class extends React.Component { - state = { - computedHeight: 0, - }; - - componentDidMount() { - const { height } = this.props; - if (!height) { - const h = getAutoHeight(this.root); - // eslint-disable-next-line - this.setState({ computedHeight: h }); - } - } - - handleRoot = node => { - this.root = node; - }; - - render() { - const { height } = this.props; - const { computedHeight } = this.state; - const h = height || computedHeight; - return ( - {h > 0 && } - ); - } - }; - -export default autoHeight; diff --git a/src/components/Charts/bizcharts.d.ts b/src/components/Charts/bizcharts.d.ts deleted file mode 100644 index 0815ffeeffcacd0ac9710977ab3d4419d078491c..0000000000000000000000000000000000000000 --- a/src/components/Charts/bizcharts.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import * as BizChart from 'bizcharts'; - -export = BizChart; diff --git a/src/components/Charts/bizcharts.js b/src/components/Charts/bizcharts.js deleted file mode 100644 index e08db8d6d2dca240451bdf6ab8a30be077a3fd9d..0000000000000000000000000000000000000000 --- a/src/components/Charts/bizcharts.js +++ /dev/null @@ -1,3 +0,0 @@ -import * as BizChart from 'bizcharts'; - -export default BizChart; diff --git a/src/components/Charts/demo/bar.md b/src/components/Charts/demo/bar.md deleted file mode 100644 index 955f44e076192f6b4536fbb79cfd5a7660354f66..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/bar.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -order: 4 -title: 柱状图 ---- - -通过设置 `x`,`y` 属性,可以快速的构建出一个漂亮的柱状图,各种纬度的关系则是通过自定义的数据展现。 - -````jsx -import { Bar } from 'ant-design-pro/lib/Charts'; - -const salesData = []; -for (let i = 0; i < 12; i += 1) { - salesData.push({ - x: `${i + 1}月`, - y: Math.floor(Math.random() * 1000) + 200, - }); -} - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Charts/demo/chart-card.md b/src/components/Charts/demo/chart-card.md deleted file mode 100644 index 4da852b71442785b17d0ce07b149e4bef343dd20..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/chart-card.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -order: 1 -title: 图表卡片 ---- - -用于展示图表的卡片容器,可以方便的配合其它图表套件展示丰富信息。 - -```jsx -import { ChartCard, yuan, Field } from 'ant-design-pro/lib/Charts'; -import Trend from 'ant-design-pro/lib/Trend'; -import { Row, Col, Icon, Tooltip } from 'antd'; -import numeral from 'numeral'; - -ReactDOM.render( - - - - - - } - total={() => ( - - )} - footer={ - - } - contentHeight={46} - > - - 周同比 - - 12% - - - - 日环比 - - 11% - - - - - - - } - action={ - - - - } - total={() => ( - - )} - footer={ - - } - /> - - - - } - action={ - - - - } - total={() => ( - - )} - /> - - , - mountNode, -); -``` diff --git a/src/components/Charts/demo/gauge.md b/src/components/Charts/demo/gauge.md deleted file mode 100644 index f53465d88175446a9479e0b415f1cb816a1a00b1..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/gauge.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -order: 7 -title: 仪表盘 ---- - -仪表盘是一种进度展示方式,可以更直观的展示当前的进展情况,通常也可表示占比。 - -````jsx -import { Gauge } from 'ant-design-pro/lib/Charts'; - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Charts/demo/mini-area.md b/src/components/Charts/demo/mini-area.md deleted file mode 100644 index 2b9bfb4778fdc71f0efa25d89d64ac142a0aa079..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/mini-area.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -order: 2 -col: 2 -title: 迷你区域图 ---- - -````jsx -import { MiniArea } from 'ant-design-pro/lib/Charts'; -import moment from 'moment'; - -const visitData = []; -const beginDay = new Date().getTime(); -for (let i = 0; i < 20; i += 1) { - visitData.push({ - x: moment(new Date(beginDay + (1000 * 60 * 60 * 24 * i))).format('YYYY-MM-DD'), - y: Math.floor(Math.random() * 100) + 10, - }); -} - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Charts/demo/mini-bar.md b/src/components/Charts/demo/mini-bar.md deleted file mode 100644 index fef301bcaa537d74506b87ad6d8b75eb06d391ff..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/mini-bar.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -order: 2 -col: 2 -title: 迷你柱状图 ---- - -迷你柱状图更适合展示简单的区间数据,简洁的表现方式可以很好的减少大数据量的视觉展现压力。 - -````jsx -import { MiniBar } from 'ant-design-pro/lib/Charts'; -import moment from 'moment'; - -const visitData = []; -const beginDay = new Date().getTime(); -for (let i = 0; i < 20; i += 1) { - visitData.push({ - x: moment(new Date(beginDay + (1000 * 60 * 60 * 24 * i))).format('YYYY-MM-DD'), - y: Math.floor(Math.random() * 100) + 10, - }); -} - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Charts/demo/mini-pie.md b/src/components/Charts/demo/mini-pie.md deleted file mode 100644 index 9b1abf05912171411b13c8eeae4ec17644a6ddca..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/mini-pie.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -order: 6 -title: 迷你饼状图 ---- - -通过简化 `Pie` 属性的设置,可以快速的实现极简的饼状图,可配合 `ChartCard` 组合展 -现更多业务场景。 - -```jsx -import { Pie } from 'ant-design-pro/lib/Charts'; - -ReactDOM.render( - , - mountNode -); -``` diff --git a/src/components/Charts/demo/mini-progress.md b/src/components/Charts/demo/mini-progress.md deleted file mode 100644 index 6308a8faedb90224d50a2aee0a9f97a28dabb793..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/mini-progress.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -order: 3 -title: 迷你进度条 ---- - -````jsx -import { MiniProgress } from 'ant-design-pro/lib/Charts'; - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Charts/demo/mix.md b/src/components/Charts/demo/mix.md deleted file mode 100644 index fc64110ae4b9b16126409d51d0e8ad5afc423fd2..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/mix.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -order: 0 -title: 图表套件组合展示 ---- - -利用 Ant Design Pro 提供的图表套件,可以灵活组合符合设计规范的图表来满足复杂的业务需求。 - -````jsx -import { ChartCard, Field, MiniArea, MiniBar, MiniProgress } from 'ant-design-pro/lib/Charts'; -import Trend from 'ant-design-pro/lib/Trend'; -import NumberInfo from 'ant-design-pro/lib/NumberInfo'; -import { Row, Col, Icon, Tooltip } from 'antd'; -import numeral from 'numeral'; -import moment from 'moment'; - -const visitData = []; -const beginDay = new Date().getTime(); -for (let i = 0; i < 20; i += 1) { - visitData.push({ - x: moment(new Date(beginDay + (1000 * 60 * 60 * 24 * i))).format('YYYY-MM-DD'), - y: Math.floor(Math.random() * 100) + 10, - }); -} - -ReactDOM.render( - - - - 本周访问} - total={numeral(12321).format('0,0')} - status="up" - subTotal={17.1} - /> - - - - - } - total={numeral(8846).format('0,0')} - footer={} - contentHeight={46} - > - - - - - } - total="78%" - footer={ - - - 周同比 - 12% - - - 日环比 - 11% - - - } - contentHeight={46} - > - - - - -, mountNode); -```` diff --git a/src/components/Charts/demo/pie.md b/src/components/Charts/demo/pie.md deleted file mode 100644 index 9c87161a27e1adb1adeb0ffeff38ff01f41b8230..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/pie.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -order: 5 -title: 饼状图 ---- - -```jsx -import { Pie, yuan } from 'ant-design-pro/lib/Charts'; - -const salesPieData = [ - { - x: '家用电器', - y: 4544, - }, - { - x: '食用酒水', - y: 3321, - }, - { - x: '个护健康', - y: 3113, - }, - { - x: '服饰箱包', - y: 2341, - }, - { - x: '母婴产品', - y: 1231, - }, - { - x: '其他', - y: 1231, - }, -]; - -ReactDOM.render( - ( - now.y + pre, 0)) - }} - /> - )} - data={salesPieData} - valueFormat={val => } - height={294} - />, - mountNode, -); -``` diff --git a/src/components/Charts/demo/radar.md b/src/components/Charts/demo/radar.md deleted file mode 100644 index 584344aa3ed5dbc52d796d5043e8711c21d5650d..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/radar.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -order: 7 -title: 雷达图 ---- - -````jsx -import { Radar, ChartCard } from 'ant-design-pro/lib/Charts'; - -const radarOriginData = [ - { - name: '个人', - ref: 10, - koubei: 8, - output: 4, - contribute: 5, - hot: 7, - }, - { - name: '团队', - ref: 3, - koubei: 9, - output: 6, - contribute: 3, - hot: 1, - }, - { - name: '部门', - ref: 4, - koubei: 1, - output: 6, - contribute: 5, - hot: 7, - }, -]; -const radarData = []; -const radarTitleMap = { - ref: '引用', - koubei: '口碑', - output: '产量', - contribute: '贡献', - hot: '热度', -}; -radarOriginData.forEach((item) => { - Object.keys(item).forEach((key) => { - if (key !== 'name') { - radarData.push({ - name: item.name, - label: radarTitleMap[key], - value: item[key], - }); - } - }); -}); - -ReactDOM.render( - - - -, mountNode); -```` diff --git a/src/components/Charts/demo/tag-cloud.md b/src/components/Charts/demo/tag-cloud.md deleted file mode 100644 index c66f6fe6bf8bdafb8e31d359a9cabe401568480e..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/tag-cloud.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -order: 9 -title: 标签云 ---- - -标签云是一套相关的标签以及与此相应的权重展示方式,一般典型的标签云有 30 至 150 个标签,而权重影响使用的字体大小或其他视觉效果。 - -````jsx -import { TagCloud } from 'ant-design-pro/lib/Charts'; - -const tags = []; -for (let i = 0; i < 50; i += 1) { - tags.push({ - name: `TagClout-Title-${i}`, - value: Math.floor((Math.random() * 50)) + 20, - }); -} - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Charts/demo/timeline-chart.md b/src/components/Charts/demo/timeline-chart.md deleted file mode 100644 index 60773b575f84ce50b401a599da03c93bc7fefec2..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/timeline-chart.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -order: 9 -title: 带有时间轴的图表 ---- - -使用 `TimelineChart` 组件可以实现带有时间轴的柱状图展现,而其中的 `x` 属性,则是时间值的指向,默认最多支持同时展现两个指标,分别是 `y1` 和 `y2`。 - -````jsx -import { TimelineChart } from 'ant-design-pro/lib/Charts'; - -const chartData = []; -for (let i = 0; i < 20; i += 1) { - chartData.push({ - x: (new Date().getTime()) + (1000 * 60 * 30 * i), - y1: Math.floor(Math.random() * 100) + 1000, - y2: Math.floor(Math.random() * 100) + 10, - }); -} - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Charts/demo/waterwave.md b/src/components/Charts/demo/waterwave.md deleted file mode 100644 index 74d290f5449adb8bd3f9bf7c7202826a5b9b6b97..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/waterwave.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -order: 8 -title: 水波图 ---- - -水波图是一种比例的展示方式,可以更直观的展示关键值的占比。 - -````jsx -import { WaterWave } from 'ant-design-pro/lib/Charts'; - -ReactDOM.render( - - - -, mountNode); -```` diff --git a/src/components/Charts/g2.js b/src/components/Charts/g2.js deleted file mode 100644 index 21e22c28e70c29ecc445fcd1c1f38bde7c82311e..0000000000000000000000000000000000000000 --- a/src/components/Charts/g2.js +++ /dev/null @@ -1,15 +0,0 @@ -// 全局 G2 设置 -import { track, setTheme } from 'bizcharts'; - -track(false); - -const config = { - defaultColor: '#1089ff', - shape: { - interval: { - fillOpacity: 1, - }, - }, -}; - -setTheme(config); diff --git a/src/components/Charts/index.d.ts b/src/components/Charts/index.d.ts deleted file mode 100644 index 1ff27af291472f887b334b7eeed96d3914ff4362..0000000000000000000000000000000000000000 --- a/src/components/Charts/index.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import * as numeral from 'numeral'; -export { default as ChartCard } from './ChartCard'; -export { default as Bar } from './Bar'; -export { default as Pie } from './Pie'; -export { default as Radar } from './Radar'; -export { default as Gauge } from './Gauge'; -export { default as MiniArea } from './MiniArea'; -export { default as MiniBar } from './MiniBar'; -export { default as MiniProgress } from './MiniProgress'; -export { default as Field } from './Field'; -export { default as WaterWave } from './WaterWave'; -export { default as TagCloud } from './TagCloud'; -export { default as TimelineChart } from './TimelineChart'; - -declare const yuan: (value: number | string) => string; - -export { yuan }; diff --git a/src/components/Charts/index.js b/src/components/Charts/index.js deleted file mode 100644 index 78863fabdb7615138baf2063f1c4ed13285abade..0000000000000000000000000000000000000000 --- a/src/components/Charts/index.js +++ /dev/null @@ -1,49 +0,0 @@ -import numeral from 'numeral'; -import './g2'; -import ChartCard from './ChartCard'; -import Bar from './Bar'; -import Pie from './Pie'; -import Radar from './Radar'; -import Gauge from './Gauge'; -import MiniArea from './MiniArea'; -import MiniBar from './MiniBar'; -import MiniProgress from './MiniProgress'; -import Field from './Field'; -import WaterWave from './WaterWave'; -import TagCloud from './TagCloud'; -import TimelineChart from './TimelineChart'; - -const yuan = val => `¥ ${numeral(val).format('0,0')}`; - -const Charts = { - yuan, - Bar, - Pie, - Gauge, - Radar, - MiniBar, - MiniArea, - MiniProgress, - ChartCard, - Field, - WaterWave, - TagCloud, - TimelineChart, -}; - -export { - Charts as default, - yuan, - Bar, - Pie, - Gauge, - Radar, - MiniBar, - MiniArea, - MiniProgress, - ChartCard, - Field, - WaterWave, - TagCloud, - TimelineChart, -}; diff --git a/src/components/Charts/index.less b/src/components/Charts/index.less deleted file mode 100644 index 190428bc80d7cd7f6f22d51fd48fa37b2d44eb10..0000000000000000000000000000000000000000 --- a/src/components/Charts/index.less +++ /dev/null @@ -1,19 +0,0 @@ -.miniChart { - position: relative; - width: 100%; - .chartContent { - position: absolute; - bottom: -28px; - width: 100%; - > div { - margin: 0 -5px; - overflow: hidden; - } - } - .chartLoading { - position: absolute; - top: 16px; - left: 50%; - margin-left: -7px; - } -} diff --git a/src/components/Charts/index.md b/src/components/Charts/index.md deleted file mode 100644 index cb7c9c96e191d47fe2dac084c25cb194f3c169c0..0000000000000000000000000000000000000000 --- a/src/components/Charts/index.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: - en-US: Charts - zh-CN: Charts -subtitle: 图表 -order: 2 -cols: 2 ---- - -Ant Design Pro 提供的业务中常用的图表类型,都是基于 [G2](https://antv.alipay.com/g2/doc/index.html) 按照 Ant Design 图表规范封装,需要注意的是 Ant Design Pro 的图表组件以套件形式提供,可以任意组合实现复杂的业务需求。 - -因为结合了 Ant Design 的标准设计,本着极简的设计思想以及开箱即用的理念,简化了大量 API 配置,所以如果需要灵活定制图表,可以参考 Ant Design Pro 图表实现,自行基于 [G2](https://antv.alipay.com/g2/doc/index.html) 封装图表组件使用。 - -## API - -### ChartCard - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| title | 卡片标题 | ReactNode\|string | - | -| action | 卡片操作 | ReactNode | - | -| total | 数据总量 | ReactNode \| number \| function | - | -| footer | 卡片底部 | ReactNode | - | -| contentHeight | 内容区域高度 | number | - | -| avatar | 右侧图标 | React.ReactNode | - | -### MiniBar - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| color | 图表颜色 | string | `#1890FF` | -| height | 图表高度 | number | - | -| data | 数据 | array<{x, y}> | - | - -### MiniArea - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| color | 图表颜色 | string | `rgba(24, 144, 255, 0.2)` | -| borderColor | 图表边颜色 | string | `#1890FF` | -| height | 图表高度 | number | - | -| line | 是否显示描边 | boolean | false | -| animate | 是否显示动画 | boolean | true | -| xAxis | [x 轴配置](http://antvis.github.io/g2/doc/tutorial/start/axis.html) | object | - | -| yAxis | [y 轴配置](http://antvis.github.io/g2/doc/tutorial/start/axis.html) | object | - | -| data | 数据 | array<{x, y}> | - | - -### MiniProgress - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| target | 目标比例 | number | - | -| color | 进度条颜色 | string | - | -| strokeWidth | 进度条高度 | number | - | -| percent | 进度比例 | number | - | - -### Bar - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| title | 图表标题 | ReactNode\|string | - | -| color | 图表颜色 | string | `rgba(24, 144, 255, 0.85)` | -| padding | 图表内部间距 | [array](https://github.com/alibaba/BizCharts/blob/master/doc/api/chart.md#7padding-object--number--array-) | `'auto'` | -| height | 图表高度 | number | - | -| data | 数据 | array<{x, y}> | - | -| autoLabel | 在宽度不足时,自动隐藏 x 轴的 label | boolean | `true` | - -### Pie - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| animate | 是否显示动画 | boolean | true | -| color | 图表颜色 | string | `rgba(24, 144, 255, 0.85)` | -| height | 图表高度 | number | - | -| hasLegend | 是否显示 legend | boolean | `false` | -| padding | 图表内部间距 | [array](https://github.com/alibaba/BizCharts/blob/master/doc/api/chart.md#7padding-object--number--array-) | `'auto'` | -| percent | 占比 | number | - | -| tooltip | 是否显示 tooltip | boolean | true | -| valueFormat | 显示值的格式化函数 | function | - | -| title | 图表标题 | ReactNode\|string | - | -| subTitle | 图表子标题 | ReactNode\|string | - | -| total | 图标中央的总数 | string | function | - | - -### Radar - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| title | 图表标题 | ReactNode\|string | - | -| height | 图表高度 | number | - | -| hasLegend | 是否显示 legend | boolean | `false` | -| padding | 图表内部间距 | [array](https://github.com/alibaba/BizCharts/blob/master/doc/api/chart.md#7padding-object--number--array-) | `'auto'` | -| data | 图标数据 | array<{name,label,value}> | - | - -### Gauge - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| title | 图表标题 | ReactNode\|string | - | -| height | 图表高度 | number | - | -| color | 图表颜色 | string | `#2F9CFF` | -| bgColor | 图表背景颜色 | string | `#F0F2F5` | -| percent | 进度比例 | number | - | - -### WaterWave - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| title | 图表标题 | ReactNode\|string | - | -| height | 图表高度 | number | - | -| color | 图表颜色 | string | `#1890FF` | -| percent | 进度比例 | number | - | - -### TagCloud - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| data | 标题 | Array | - | -| height | 高度值 | number | - | - -### TimelineChart - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| data | 标题 | Array | - | -| titleMap | 指标别名 | Object{y1: '客流量', y2: '支付笔数'} | - | -| height | 高度值 | number | 400 | - -### Field - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| label | 标题 | ReactNode\|string | - | -| value | 值 | ReactNode\|string | - | diff --git a/src/components/CountDown/demo/simple.md b/src/components/CountDown/demo/simple.md deleted file mode 100644 index e42cbf1d99caab99f7c986600717ed08d5df63e3..0000000000000000000000000000000000000000 --- a/src/components/CountDown/demo/simple.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -order: 0 -title: - zh-CN: 基本 - en-US: Basic ---- - -## zh-CN - -简单的倒计时组件使用。 - -## en-US - -The simplest usage. - -````jsx -import CountDown from 'ant-design-pro/lib/CountDown'; - -const targetTime = new Date().getTime() + 3900000; - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/CountDown/index.d.ts b/src/components/CountDown/index.d.ts deleted file mode 100644 index d39a2e951830d5cddca08c8becbdb500847448b3..0000000000000000000000000000000000000000 --- a/src/components/CountDown/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import * as React from 'react'; -export interface ICountDownProps { - format?: (time: number) => void; - target: Date | number; - onEnd?: () => void; - style?: React.CSSProperties; -} - -export default class CountDown extends React.Component {} diff --git a/src/components/CountDown/index.en-US.md b/src/components/CountDown/index.en-US.md deleted file mode 100644 index 7b452406b3528ccfb14fe3bdecb0ead9a2df4e6f..0000000000000000000000000000000000000000 --- a/src/components/CountDown/index.en-US.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: CountDown -cols: 1 -order: 3 ---- - -Simple CountDown Component. - -## API - -| Property | Description | Type | Default | -|----------|------------------------------------------|-------------|-------| -| format | Formatter of time | Function(time) | | -| target | Target time | Date | - | -| onEnd | Countdown to the end callback | funtion | -| diff --git a/src/components/CountDown/index.js b/src/components/CountDown/index.js deleted file mode 100644 index 7565bd82da8c6331840861a1dc7bc3b49fad947f..0000000000000000000000000000000000000000 --- a/src/components/CountDown/index.js +++ /dev/null @@ -1,121 +0,0 @@ -import React, { Component } from 'react'; - -function fixedZero(val) { - return val * 1 < 10 ? `0${val}` : val; -} -const initTime = props => { - let lastTime = 0; - let targetTime = 0; - try { - if (Object.prototype.toString.call(props.target) === '[object Date]') { - targetTime = props.target.getTime(); - } else { - targetTime = new Date(props.target).getTime(); - } - } catch (e) { - throw new Error('invalid target prop', e); - } - - lastTime = targetTime - new Date().getTime(); - return { - lastTime: lastTime < 0 ? 0 : lastTime, - }; -}; - -class CountDown extends Component { - timer = 0; - - interval = 1000; - - constructor(props) { - super(props); - const { lastTime } = initTime(props); - this.state = { - lastTime, - }; - } - - static getDerivedStateFromProps(nextProps, preState) { - const { lastTime } = initTime(nextProps); - if (preState.lastTime !== lastTime) { - return { - lastTime, - }; - } - return null; - } - - componentDidMount() { - this.tick(); - } - - componentDidUpdate(prevProps) { - const { target } = this.props; - if (target !== prevProps.target) { - clearTimeout(this.timer); - this.tick(); - } - } - - componentWillUnmount() { - clearTimeout(this.timer); - } - - // defaultFormat = time => ( - // {moment(time).format('hh:mm:ss')} - // ); - defaultFormat = time => { - const hours = 60 * 60 * 1000; - const minutes = 60 * 1000; - - const h = Math.floor(time / hours); - const m = Math.floor((time - h * hours) / minutes); - const s = Math.floor((time - h * hours - m * minutes) / 1000); - return ( - - {fixedZero(h)}:{fixedZero(m)}:{fixedZero(s)} - - ); - }; - - tick = () => { - const { onEnd } = this.props; - let { lastTime } = this.state; - - this.timer = setTimeout(() => { - if (lastTime < this.interval) { - clearTimeout(this.timer); - this.setState( - { - lastTime: 0, - }, - () => { - if (onEnd) { - onEnd(); - } - } - ); - } else { - lastTime -= this.interval; - this.setState( - { - lastTime, - }, - () => { - this.tick(); - } - ); - } - }, this.interval); - }; - - render() { - const { format = this.defaultFormat, onEnd, ...rest } = this.props; - const { lastTime } = this.state; - const result = format(lastTime); - - return {result}; - } -} - -export default CountDown; diff --git a/src/components/CountDown/index.zh-CN.md b/src/components/CountDown/index.zh-CN.md deleted file mode 100644 index 7e00ba1da5f3ed633dd2d2dc9c81b5acfc30c3fa..0000000000000000000000000000000000000000 --- a/src/components/CountDown/index.zh-CN.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: CountDown -subtitle: 倒计时 -cols: 1 -order: 3 ---- - -倒计时组件。 - -## API - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| format | 时间格式化显示 | Function(time) | | -| target | 目标时间 | Date | - | -| onEnd | 倒计时结束回调 | funtion | -| diff --git a/src/components/DescriptionList/Description.d.ts b/src/components/DescriptionList/Description.d.ts deleted file mode 100644 index 2a17be374accc8e2a1ffa9812327398a6c3f7173..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/Description.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import * as React from 'react'; - -export default class Description extends React.Component< - { - term: React.ReactNode; - style?: React.CSSProperties; - }, - any -> {} diff --git a/src/components/DescriptionList/Description.js b/src/components/DescriptionList/Description.js deleted file mode 100644 index fce9fd3cb7debf4551bae22dcfc48eefb176d959..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/Description.js +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { Col } from 'antd'; -import styles from './index.less'; -import responsive from './responsive'; - -const Description = ({ term, column, children, ...restProps }) => ( - - {term && {term}} - {children !== null && children !== undefined && {children}} - -); - -Description.defaultProps = { - term: '', -}; - -Description.propTypes = { - term: PropTypes.node, -}; - -export default Description; diff --git a/src/components/DescriptionList/DescriptionList.js b/src/components/DescriptionList/DescriptionList.js deleted file mode 100644 index 84bdbd79d3dd52c62833c16783010825ecdbd0c1..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/DescriptionList.js +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; -import classNames from 'classnames'; -import { Row } from 'antd'; -import styles from './index.less'; - -const DescriptionList = ({ - className, - title, - col = 3, - layout = 'horizontal', - gutter = 32, - children, - size, - ...restProps -}) => { - const clsString = classNames(styles.descriptionList, styles[layout], className, { - [styles.small]: size === 'small', - [styles.large]: size === 'large', - }); - const column = col > 4 ? 4 : col; - return ( - - {title ? {title} : null} - - {React.Children.map(children, child => - child ? React.cloneElement(child, { column }) : child - )} - - - ); -}; - -export default DescriptionList; diff --git a/src/components/DescriptionList/demo/basic.md b/src/components/DescriptionList/demo/basic.md deleted file mode 100644 index 87954551e6fa564d56d327d4ca330f43f5e6c1b7..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/demo/basic.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -order: 0 -title: - zh-CN: 基本 - en-US: Basic ---- - -## zh-CN - -基本描述列表。 - -## en-US - -Basic DescriptionList. - -````jsx -import DescriptionList from 'ant-design-pro/lib/DescriptionList'; - -const { Description } = DescriptionList; - -ReactDOM.render( - - - A free, open source, cross-platform, - graphical web browser developed by the - Mozilla Corporation and hundreds of - volunteers. - - - A free, open source, cross-platform, - graphical web browser developed by the - Mozilla Corporation and hundreds of - volunteers. - - - A free, open source, cross-platform, - graphical web browser developed by the - Mozilla Corporation and hundreds of - volunteers. - - -, mountNode); -```` diff --git a/src/components/DescriptionList/demo/vertical.md b/src/components/DescriptionList/demo/vertical.md deleted file mode 100644 index 2742f7c9f6b0a907570617ab422b5341a2151a4b..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/demo/vertical.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -order: 1 -title: - zh-CN: 垂直型 - en-US: Vertical ---- - -## zh-CN - -垂直布局。 - -## en-US - -Vertical layout. - -````jsx -import DescriptionList from 'ant-design-pro/lib/DescriptionList'; - -const { Description } = DescriptionList; - -ReactDOM.render( - - - A free, open source, cross-platform, - graphical web browser developed by the - Mozilla Corporation and hundreds of - volunteers. - - - A free, open source, cross-platform, - graphical web browser developed by the - Mozilla Corporation and hundreds of - volunteers. - - - A free, open source, cross-platform, - graphical web browser developed by the - Mozilla Corporation and hundreds of - volunteers. - - -, mountNode); -```` diff --git a/src/components/DescriptionList/index.d.ts b/src/components/DescriptionList/index.d.ts deleted file mode 100644 index 96ccfa7da3a21d790e3348a65603488303780669..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/index.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from 'react'; -import Description from './Description'; - -export interface IDescriptionListProps { - layout?: 'horizontal' | 'vertical'; - col?: number; - title: React.ReactNode; - gutter?: number; - size?: 'large' | 'small'; - style?: React.CSSProperties; -} - -export default class DescriptionList extends React.Component { - public static Description: typeof Description; -} diff --git a/src/components/DescriptionList/index.en-US.md b/src/components/DescriptionList/index.en-US.md deleted file mode 100644 index 089f30b1a1502bd6bfd8754821870e5db5df55ac..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/index.en-US.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: DescriptionList -cols: 1 -order: 4 ---- - -Groups display multiple read-only fields, which are common to informational displays on detail pages. - -## API - -### DescriptionList - -| Property | Description | Type | Default | -|----------|------------------------------------------|-------------|---------| -| layout | type of layout | Enum{'horizontal', 'vertical'} | 'horizontal' | -| col | specify the maximum number of columns to display, the final columns number is determined by col setting combined with [Responsive Rules](/components/DescriptionList#Responsive-Rules) | number(0 < col <= 4) | 3 | -| title | title | ReactNode | - | -| gutter | specify the distance between two items, unit is `px` | number | 32 | -| size | size of list | Enum{'large', 'small'} | - | - -#### Responsive Rules - -| Window Width | Columns Number | -|---------------------|---------------------------------------------| -| `≥768px` | `col` | -| `≥576px` | `col < 2 ? col : 2` | -| `<576px` | `1` | - -### DescriptionList.Description - -| Property | Description | Type | Default | -|----------|------------------------------------------|-------------|-------| -| term | item title | ReactNode | - | diff --git a/src/components/DescriptionList/index.js b/src/components/DescriptionList/index.js deleted file mode 100644 index 357f479fd5b279ad9e6141c8c70ae73310e373c3..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import DescriptionList from './DescriptionList'; -import Description from './Description'; - -DescriptionList.Description = Description; -export default DescriptionList; diff --git a/src/components/DescriptionList/index.less b/src/components/DescriptionList/index.less deleted file mode 100644 index bfb33fcc3f14e47bf03549f3e68dc11f86f184f2..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/index.less +++ /dev/null @@ -1,77 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.descriptionList { - // offset the padding-bottom of last row - :global { - .ant-row { - margin-bottom: -16px; - overflow: hidden; - } - } - - .title { - font-size: 14px; - color: @heading-color; - font-weight: 500; - margin-bottom: 16px; - } - - .term { - // Line-height is 22px IE dom height will calculate error - line-height: 20px; - padding-bottom: 16px; - margin-right: 8px; - color: @heading-color; - white-space: nowrap; - display: table-cell; - - &:after { - content: ':'; - margin: 0 8px 0 2px; - position: relative; - top: -0.5px; - } - } - - .detail { - line-height: 20px; - width: 100%; - padding-bottom: 16px; - color: @text-color; - display: table-cell; - } - - &.small { - // offset the padding-bottom of last row - :global { - .ant-row { - margin-bottom: -8px; - } - } - .title { - margin-bottom: 12px; - color: @text-color; - } - .term, - .detail { - padding-bottom: 8px; - } - } - - &.large { - .title { - font-size: 16px; - } - } - - &.vertical { - .term { - padding-bottom: 8px; - display: block; - } - - .detail { - display: block; - } - } -} diff --git a/src/components/DescriptionList/index.zh-CN.md b/src/components/DescriptionList/index.zh-CN.md deleted file mode 100644 index b16a7fe76907bdffb1fa20c53ac1ba72552f19d3..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/index.zh-CN.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: DescriptionList -subtitle: 描述列表 -cols: 1 -order: 4 ---- - -成组展示多个只读字段,常见于详情页的信息展示。 - -## API - -### DescriptionList - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| layout | 布局方式 | Enum{'horizontal', 'vertical'} | 'horizontal' | -| col | 指定信息最多分几列展示,最终一行几列由 col 配置结合[响应式规则](/components/DescriptionList#响应式规则)决定 | number(0 < col <= 4) | 3 | -| title | 列表标题 | ReactNode | - | -| gutter | 列表项间距,单位为 `px` | number | 32 | -| size | 列表型号 | Enum{'large', 'small'} | - | - -#### 响应式规则 - -| 窗口宽度 | 展示列数 | -|---------------------|---------------------------------------------| -| `≥768px` | `col` | -| `≥576px` | `col < 2 ? col : 2` | -| `<576px` | `1` | - -### DescriptionList.Description - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| term | 列表项标题 | ReactNode | - | - - - diff --git a/src/components/DescriptionList/responsive.js b/src/components/DescriptionList/responsive.js deleted file mode 100644 index a5aa73f781e3eccdbae4dffd656e201589575554..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/responsive.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - 1: { xs: 24 }, - 2: { xs: 24, sm: 12 }, - 3: { xs: 24, sm: 12, md: 8 }, - 4: { xs: 24, sm: 12, md: 6 }, -}; diff --git a/src/components/EditableItem/index.js b/src/components/EditableItem/index.js deleted file mode 100644 index 40034d0ac9d870967f9248dc34986fb085229278..0000000000000000000000000000000000000000 --- a/src/components/EditableItem/index.js +++ /dev/null @@ -1,50 +0,0 @@ -import React, { PureComponent } from 'react'; -import { Input, Icon } from 'antd'; -import styles from './index.less'; - -export default class EditableItem extends PureComponent { - constructor(props) { - super(props); - this.state = { - value: props.value, - editable: false, - }; - } - - handleChange = e => { - const { value } = e.target; - this.setState({ value }); - }; - - check = () => { - this.setState({ editable: false }); - const { value } = this.state; - const { onChange } = this.props; - if (onChange) { - onChange(value); - } - }; - - edit = () => { - this.setState({ editable: true }); - }; - - render() { - const { value, editable } = this.state; - return ( - - {editable ? ( - - - - - ) : ( - - {value || ' '} - - - )} - - ); - } -} diff --git a/src/components/EditableItem/index.less b/src/components/EditableItem/index.less deleted file mode 100644 index 457a18bd4b9b4775a5eb5619c8f80f212d1467f7..0000000000000000000000000000000000000000 --- a/src/components/EditableItem/index.less +++ /dev/null @@ -1,25 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.editableItem { - line-height: @input-height-base; - display: table; - width: 100%; - margin-top: (@font-size-base * @line-height-base - @input-height-base) / 2; - - .wrapper { - display: table-row; - - & > * { - display: table-cell; - } - - & > *:first-child { - width: 85%; - } - - .icon { - cursor: pointer; - text-align: right; - } - } -} diff --git a/src/components/Ellipsis/demo/line.md b/src/components/Ellipsis/demo/line.md deleted file mode 100644 index bc31170dc317f3f9a942fd041fd16350aba60858..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/demo/line.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -order: 1 -title: - zh-CN: 按照行数省略 - en-US: Truncate according to the number of rows ---- - -## zh-CN - -通过设置 `lines` 属性指定最大行数,如果超过这个行数的文本会自动截取。但是在这种模式下所有 `children` 将会被转换成纯文本。 - -并且注意在这种模式下,外容器需要有指定的宽度(或设置自身宽度)。 - -## en-US - -`lines` attribute specifies the maximum number of rows where the text will automatically be truncated when exceeded. In this mode, all children will be converted to plain text. - -Also note that, in this mode, the outer container needs to have a specified width (or set its own width). - - -````jsx -import Ellipsis from 'ant-design-pro/lib/Ellipsis'; - -const article = There were injuries alleged in three cases in 2015, and a fourth incident in September, according to the safety recall report. After meeting with US regulators in October, the firm decided to issue a voluntary recall.; - -ReactDOM.render( - - {article} - -, mountNode); -```` diff --git a/src/components/Ellipsis/demo/number.md b/src/components/Ellipsis/demo/number.md deleted file mode 100644 index 0bc1a0ff7847711f27ac85aa98ae222d14904be4..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/demo/number.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -order: 0 -title: - zh-CN: 按照字符数省略 - en-US: Truncate according to the number of character ---- - -## zh-CN - -通过设置 `length` 属性指定文本最长长度,如果超过这个长度会自动截取。 - -## en-US - -`length` attribute specifies the maximum length where the text will automatically be truncated when exceeded. - -````jsx -import Ellipsis from 'ant-design-pro/lib/Ellipsis'; - -const article = 'There were injuries alleged in three cases in 2015, and a fourth incident in September, according to the safety recall report. After meeting with US regulators in October, the firm decided to issue a voluntary recall.'; - -ReactDOM.render( - - {article} - Show Tooltip - {article} - -, mountNode); -```` diff --git a/src/components/Ellipsis/index.d.ts b/src/components/Ellipsis/index.d.ts deleted file mode 100644 index 37d508d77335048de87287fc52fb9f457e89dc33..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/index.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react'; -import { TooltipProps } from 'antd/lib/tooltip'; - -export interface IEllipsisTooltipProps extends TooltipProps { - title?: undefined; - overlayStyle?: undefined; -} - -export interface IEllipsisProps { - tooltip?: boolean | IEllipsisTooltipProps; - length?: number; - lines?: number; - style?: React.CSSProperties; - className?: string; - fullWidthRecognition?: boolean; -} - -export function getStrFullLength(str: string): number; -export function cutStrByFullLength(str: string, maxLength: number): string; - -export default class Ellipsis extends React.Component {} diff --git a/src/components/Ellipsis/index.en-US.md b/src/components/Ellipsis/index.en-US.md deleted file mode 100644 index 15139cc9dc13e1f0db7c50f942d884761ed82fec..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/index.en-US.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Ellipsis -cols: 1 -order: 10 ---- - -When the text is too long, the Ellipsis automatically shortens it according to its length or the maximum number of lines. - -## API - -Property | Description | Type | Default -----|------|-----|------ -tooltip | tooltip for showing the full text content when hovering over | boolean | - -length | maximum number of characters in the text before being truncated | number | - -lines | maximum number of rows in the text before being truncated | number | `1` -fullWidthRecognition | whether consider full-width character length as 2 when calculate string length | boolean | - diff --git a/src/components/Ellipsis/index.js b/src/components/Ellipsis/index.js deleted file mode 100644 index de700b74b192b5c634ee88a0fc5533f59a504ab5..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/index.js +++ /dev/null @@ -1,270 +0,0 @@ -import React, { Component } from 'react'; -import { Tooltip } from 'antd'; -import classNames from 'classnames'; -import styles from './index.less'; - -/* eslint react/no-did-mount-set-state: 0 */ -/* eslint no-param-reassign: 0 */ - -const isSupportLineClamp = document.body.style.webkitLineClamp !== undefined; - -const TooltipOverlayStyle = { - overflowWrap: 'break-word', - wordWrap: 'break-word', -}; - -export const getStrFullLength = (str = '') => - str.split('').reduce((pre, cur) => { - const charCode = cur.charCodeAt(0); - if (charCode >= 0 && charCode <= 128) { - return pre + 1; - } - return pre + 2; - }, 0); - -export const cutStrByFullLength = (str = '', maxLength) => { - let showLength = 0; - return str.split('').reduce((pre, cur) => { - const charCode = cur.charCodeAt(0); - if (charCode >= 0 && charCode <= 128) { - showLength += 1; - } else { - showLength += 2; - } - if (showLength <= maxLength) { - return pre + cur; - } - return pre; - }, ''); -}; - -const getTooltip = ({ tooltip, overlayStyle, title, children }) => { - if (tooltip) { - const props = tooltip === true ? { overlayStyle, title } : { ...tooltip, overlayStyle, title }; - return {children}; - } - return children; -}; - -const EllipsisText = ({ text, length, tooltip, fullWidthRecognition, ...other }) => { - if (typeof text !== 'string') { - throw new Error('Ellipsis children must be string.'); - } - const textLength = fullWidthRecognition ? getStrFullLength(text) : text.length; - if (textLength <= length || length < 0) { - return {text}; - } - const tail = '...'; - let displayText; - if (length - tail.length <= 0) { - displayText = ''; - } else { - displayText = fullWidthRecognition ? cutStrByFullLength(text, length) : text.slice(0, length); - } - - const spanAttrs = tooltip ? {} : { ...other }; - return getTooltip({ - tooltip, - overlayStyle: TooltipOverlayStyle, - title: text, - children: ( - - {displayText} - {tail} - - ), - }); -}; - -export default class Ellipsis extends Component { - state = { - text: '', - targetCount: 0, - }; - - componentDidMount() { - if (this.node) { - this.computeLine(); - } - } - - componentDidUpdate(perProps) { - const { lines } = this.props; - if (lines !== perProps.lines) { - this.computeLine(); - } - } - - computeLine = () => { - const { lines } = this.props; - if (lines && !isSupportLineClamp) { - const text = this.shadowChildren.innerText || this.shadowChildren.textContent; - const lineHeight = parseInt(getComputedStyle(this.root).lineHeight, 10); - const targetHeight = lines * lineHeight; - this.content.style.height = `${targetHeight}px`; - const totalHeight = this.shadowChildren.offsetHeight; - const shadowNode = this.shadow.firstChild; - - if (totalHeight <= targetHeight) { - this.setState({ - text, - targetCount: text.length, - }); - return; - } - - // bisection - const len = text.length; - const mid = Math.ceil(len / 2); - - const count = this.bisection(targetHeight, mid, 0, len, text, shadowNode); - - this.setState({ - text, - targetCount: count, - }); - } - }; - - bisection = (th, m, b, e, text, shadowNode) => { - const suffix = '...'; - let mid = m; - let end = e; - let begin = b; - shadowNode.innerHTML = text.substring(0, mid) + suffix; - let sh = shadowNode.offsetHeight; - - if (sh <= th) { - shadowNode.innerHTML = text.substring(0, mid + 1) + suffix; - sh = shadowNode.offsetHeight; - if (sh > th || mid === begin) { - return mid; - } - begin = mid; - if (end - begin === 1) { - mid = 1 + begin; - } else { - mid = Math.floor((end - begin) / 2) + begin; - } - return this.bisection(th, mid, begin, end, text, shadowNode); - } - if (mid - 1 < 0) { - return mid; - } - shadowNode.innerHTML = text.substring(0, mid - 1) + suffix; - sh = shadowNode.offsetHeight; - if (sh <= th) { - return mid - 1; - } - end = mid; - mid = Math.floor((end - begin) / 2) + begin; - return this.bisection(th, mid, begin, end, text, shadowNode); - }; - - handleRoot = n => { - this.root = n; - }; - - handleContent = n => { - this.content = n; - }; - - handleNode = n => { - this.node = n; - }; - - handleShadow = n => { - this.shadow = n; - }; - - handleShadowChildren = n => { - this.shadowChildren = n; - }; - - render() { - const { text, targetCount } = this.state; - const { - children, - lines, - length, - className, - tooltip, - fullWidthRecognition, - ...restProps - } = this.props; - - const cls = classNames(styles.ellipsis, className, { - [styles.lines]: lines && !isSupportLineClamp, - [styles.lineClamp]: lines && isSupportLineClamp, - }); - - if (!lines && !length) { - return ( - - {children} - - ); - } - - // length - if (!lines) { - return ( - - ); - } - - const id = `antd-pro-ellipsis-${`${new Date().getTime()}${Math.floor(Math.random() * 100)}`}`; - - // support document.body.style.webkitLineClamp - if (isSupportLineClamp) { - const style = `#${id}{-webkit-line-clamp:${lines};-webkit-box-orient: vertical;}`; - - const node = ( - - - {children} - - ); - - return getTooltip({ - tooltip, - overlayStyle: TooltipOverlayStyle, - title: children, - children: node, - }); - } - - const childNode = ( - - {targetCount > 0 && text.substring(0, targetCount)} - {targetCount > 0 && targetCount < text.length && '...'} - - ); - - return ( - - - {getTooltip({ - tooltip, - overlayStyle: TooltipOverlayStyle, - title: text, - children: childNode, - })} - - {children} - - - {text} - - - - ); - } -} diff --git a/src/components/Ellipsis/index.less b/src/components/Ellipsis/index.less deleted file mode 100644 index 2c4a867c1582a6725004510656729ece8167f0b1..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/index.less +++ /dev/null @@ -1,24 +0,0 @@ -.ellipsis { - overflow: hidden; - display: inline-block; - word-break: break-all; - width: 100%; -} - -.lines { - position: relative; - .shadow { - display: block; - position: absolute; - color: transparent; - opacity: 0; - z-index: -999; - } -} - -.lineClamp { - position: relative; - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; -} diff --git a/src/components/Ellipsis/index.test.js b/src/components/Ellipsis/index.test.js deleted file mode 100644 index 4d057b24e7f726f25165dcae7ec9cd064f577f11..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/index.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import { getStrFullLength, cutStrByFullLength } from './index'; - -describe('test calculateShowLength', () => { - it('get full length', () => { - expect(getStrFullLength('一二,a,')).toEqual(8); - }); - it('cut str by full length', () => { - expect(cutStrByFullLength('一二,a,', 7)).toEqual('一二,a'); - }); - it('cut str when length small', () => { - expect(cutStrByFullLength('一22三', 5)).toEqual('一22'); - }); -}); diff --git a/src/components/Ellipsis/index.zh-CN.md b/src/components/Ellipsis/index.zh-CN.md deleted file mode 100644 index f7a70eadd41a8251e76dbe4bcebdb909cdafbc43..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/index.zh-CN.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Ellipsis -subtitle: 文本自动省略号 -cols: 1 -order: 10 ---- - -文本过长自动处理省略号,支持按照文本长度和最大行数两种方式截取。 - -## API - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -tooltip | 移动到文本展示完整内容的提示 | boolean | - -length | 在按照长度截取下的文本最大字符数,超过则截取省略 | number | - -lines | 在按照行数截取下最大的行数,超过则截取省略 | number | `1` -fullWidthRecognition | 是否将全角字符的长度视为2来计算字符串长度 | boolean | - diff --git a/src/components/Exception/demo/403.md b/src/components/Exception/demo/403.md deleted file mode 100644 index bb46037fea8daa2732c466c26c54f45a47d0fe22..0000000000000000000000000000000000000000 --- a/src/components/Exception/demo/403.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -order: 2 -title: - zh-CN: 403 - en-US: 403 ---- - -## zh-CN - -403 页面,配合自定义操作。 - -## en-US - -403 page with custom operations. - -````jsx -import Exception from 'ant-design-pro/lib/Exception'; -import { Button } from 'antd'; - -const actions = ( - - Home - Detail - -); -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Exception/demo/404.md b/src/components/Exception/demo/404.md deleted file mode 100644 index db50de653eb2acb08c5ed4a0aa83ee3ff73e3180..0000000000000000000000000000000000000000 --- a/src/components/Exception/demo/404.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -order: 0 -title: - zh-CN: 404 - en-US: 404 ---- - -## zh-CN - -404 页面。 - -## en-US - -404 page. - -````jsx -import Exception from 'ant-design-pro/lib/Exception'; - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Exception/demo/500.md b/src/components/Exception/demo/500.md deleted file mode 100644 index 096ca8e511d2b19c952a68a9d1c8da606e747b28..0000000000000000000000000000000000000000 --- a/src/components/Exception/demo/500.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -order: 1 -title: - zh-CN: 500 - en-US: 500 ---- - -## zh-CN - -500 页面。 - -## en-US - -500 page. - -````jsx -import Exception from 'ant-design-pro/lib/Exception'; - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Exception/index.d.ts b/src/components/Exception/index.d.ts deleted file mode 100644 index a74abb1fa6334cb2b8ef987aab5a1b5dc1f0d531..0000000000000000000000000000000000000000 --- a/src/components/Exception/index.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from 'react'; -export interface IExceptionProps { - type?: '403' | '404' | '500'; - title?: React.ReactNode; - desc?: React.ReactNode; - img?: string; - actions?: React.ReactNode; - linkElement?: string | React.ComponentType; - style?: React.CSSProperties; - className?: string; - backText?: React.ReactNode; - redirect?: string; -} - -export default class Exception extends React.Component {} diff --git a/src/components/Exception/index.en-US.md b/src/components/Exception/index.en-US.md deleted file mode 100644 index 37e7e80756fb7517239658775e4ce5ef170dcb21..0000000000000000000000000000000000000000 --- a/src/components/Exception/index.en-US.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Exception -cols: 1 -order: 5 ---- - -Exceptions page is used to provide feedback on specific abnormal state. Usually, it contains an explanation of the error status, and provides users with suggestions or operations, to prevent users from feeling lost and confused. - -## API - -Property | Description | Type | Default ----------|-------------|------|-------- -| backText | default return button text | ReactNode | back to home | -type | type of exception, the corresponding default `title`, `desc`, `img` will be given if set, which can be overridden by explicit setting of `title`, `desc`, `img` | Enum {'403', '404', '500'} | - -title | title | ReactNode | - -desc | supplementary description | ReactNode | - -img | the url of background image | string | - -actions | suggested operations, a default 'Home' link will show if not set | ReactNode | - -linkElement | to specify the element of link | string\|ReactElement | 'a' -redirect | redirect path | string | '/' \ No newline at end of file diff --git a/src/components/Exception/index.js b/src/components/Exception/index.js deleted file mode 100644 index 2c7223cc7655ce457ef1c597dc3fe8ef86b49c49..0000000000000000000000000000000000000000 --- a/src/components/Exception/index.js +++ /dev/null @@ -1,61 +0,0 @@ -import React, { createElement } from 'react'; -import classNames from 'classnames'; -import { Button } from 'antd'; -import config from './typeConfig'; -import styles from './index.less'; - -class Exception extends React.PureComponent { - static defaultProps = { - backText: 'back to home', - redirect: '/', - }; - - constructor(props) { - super(props); - this.state = {}; - } - - render() { - const { - className, - backText, - linkElement = 'a', - type, - title, - desc, - img, - actions, - redirect, - ...rest - } = this.props; - const pageType = type in config ? type : '404'; - const clsString = classNames(styles.exception, className); - return ( - - - - - - {title || config[pageType].title} - {desc || config[pageType].desc} - - {actions || - createElement( - linkElement, - { - to: redirect, - href: redirect, - }, - {backText} - )} - - - - ); - } -} - -export default Exception; diff --git a/src/components/Exception/index.less b/src/components/Exception/index.less deleted file mode 100644 index b55fe3a928020e82b2c80f0adb7ebc4fb55eecec..0000000000000000000000000000000000000000 --- a/src/components/Exception/index.less +++ /dev/null @@ -1,89 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.exception { - display: flex; - align-items: center; - height: 80%; - min-height: 500px; - - .imgBlock { - flex: 0 0 62.5%; - width: 62.5%; - padding-right: 152px; - zoom: 1; - &:before, - &:after { - content: ' '; - display: table; - } - &:after { - clear: both; - visibility: hidden; - font-size: 0; - height: 0; - } - } - - .imgEle { - height: 360px; - width: 100%; - max-width: 430px; - float: right; - background-repeat: no-repeat; - background-position: 50% 50%; - background-size: contain; - } - - .content { - flex: auto; - - h1 { - color: #434e59; - font-size: 72px; - font-weight: 600; - line-height: 72px; - margin-bottom: 24px; - } - - .desc { - color: @text-color-secondary; - font-size: 20px; - line-height: 28px; - margin-bottom: 16px; - } - - .actions { - button:not(:last-child) { - margin-right: 8px; - } - } - } -} - -@media screen and (max-width: @screen-xl) { - .exception { - .imgBlock { - padding-right: 88px; - } - } -} - -@media screen and (max-width: @screen-sm) { - .exception { - display: block; - text-align: center; - .imgBlock { - padding-right: 0; - margin: 0 auto 24px; - } - } -} - -@media screen and (max-width: @screen-xs) { - .exception { - .imgBlock { - margin-bottom: -24px; - overflow: hidden; - } - } -} diff --git a/src/components/Exception/index.zh-CN.md b/src/components/Exception/index.zh-CN.md deleted file mode 100644 index 2e64399fcbe4fe2c0eca7b9c4cb7742ccef3ed9a..0000000000000000000000000000000000000000 --- a/src/components/Exception/index.zh-CN.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Exception -subtitle: 异常 -cols: 1 -order: 5 ---- - -异常页用于对页面特定的异常状态进行反馈。通常,它包含对错误状态的阐述,并向用户提供建议或操作,避免用户感到迷失和困惑。 - -## API - -| 参数 | 说明| 类型 | 默认值 | -|-------------|------------------------------------------|-------------|-------| -| backText| 默认的返回按钮文本 | ReactNode| back to home | -| type| 页面类型,若配置,则自带对应类型默认的 `title`,`desc`,`img`,此默认设置可以被 `title`,`desc`,`img` 覆盖 | Enum {'403', '404', '500'} | - | -| title | 标题 | ReactNode| -| -| desc| 补充描述| ReactNode| -| -| img | 背景图片地址 | string| -| -| actions | 建议操作,配置此属性时默认的『返回首页』按钮不生效| ReactNode| -| -| linkElement | 定义链接的元素 | string\|ReactElement | 'a' | -| redirect | 返回按钮的跳转地址 | string | '/' diff --git a/src/components/Exception/typeConfig.js b/src/components/Exception/typeConfig.js deleted file mode 100644 index b6e1ee5a9bd7ac2990b9c319ccceeb9040632798..0000000000000000000000000000000000000000 --- a/src/components/Exception/typeConfig.js +++ /dev/null @@ -1,19 +0,0 @@ -const config = { - 403: { - img: 'https://gw.alipayobjects.com/zos/rmsportal/wZcnGqRDyhPOEYFcZDnb.svg', - title: '403', - desc: '抱歉,你无权访问该页面', - }, - 404: { - img: 'https://gw.alipayobjects.com/zos/rmsportal/KpnpchXsobRgLElEozzI.svg', - title: '404', - desc: '抱歉,你访问的页面不存在', - }, - 500: { - img: 'https://gw.alipayobjects.com/zos/rmsportal/RVRUAYdCGeYNBWoKiIwB.svg', - title: '500', - desc: '抱歉,服务器出错了', - }, -}; - -export default config; diff --git a/src/components/FooterToolbar/demo/basic.md b/src/components/FooterToolbar/demo/basic.md deleted file mode 100644 index 3043dbf74e8b2927c50821a583a49b7c9c75f3c0..0000000000000000000000000000000000000000 --- a/src/components/FooterToolbar/demo/basic.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -order: 0 -title: - zh-CN: 演示 - en-US: demo -iframe: 400 ---- - -## zh-CN - -浮动固定页脚。 - -## en-US - -Fixed to the footer. - -````jsx -import FooterToolbar from 'ant-design-pro/lib/FooterToolbar'; -import { Button } from 'antd'; - -ReactDOM.render( - - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - - Cancel - Submit - - -, mountNode); -```` \ No newline at end of file diff --git a/src/components/FooterToolbar/index.d.ts b/src/components/FooterToolbar/index.d.ts deleted file mode 100644 index 9c6ac5b4cad95ade8f24a1b02e6de72f4770bfeb..0000000000000000000000000000000000000000 --- a/src/components/FooterToolbar/index.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import * as React from 'react'; -export interface IFooterToolbarProps { - extra: React.ReactNode; - style?: React.CSSProperties; -} - -export default class FooterToolbar extends React.Component {} diff --git a/src/components/FooterToolbar/index.en-US.md b/src/components/FooterToolbar/index.en-US.md deleted file mode 100644 index 69fd80bda80723c118f8fa1abdbc53372303305c..0000000000000000000000000000000000000000 --- a/src/components/FooterToolbar/index.en-US.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: FooterToolbar -cols: 1 -order: 6 ---- - -A toolbar fixed at the bottom. - -## Usage - -It is fixed at the bottom of the content area and does not move along with the scroll bar, which is usually used for data collection and submission for long pages. - -## API - -Property | Description | Type | Default ----------|-------------|------|-------- -children | toolbar content, align to the right | ReactNode | - -extra | extra information, align to the left | ReactNode | - \ No newline at end of file diff --git a/src/components/FooterToolbar/index.js b/src/components/FooterToolbar/index.js deleted file mode 100644 index d43f72fb45315521f9b5cd5a71589228f8d66de8..0000000000000000000000000000000000000000 --- a/src/components/FooterToolbar/index.js +++ /dev/null @@ -1,47 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import classNames from 'classnames'; -import styles from './index.less'; - -export default class FooterToolbar extends Component { - static contextTypes = { - isMobile: PropTypes.bool, - }; - - state = { - width: undefined, - }; - - componentDidMount() { - window.addEventListener('resize', this.resizeFooterToolbar); - this.resizeFooterToolbar(); - } - - componentWillUnmount() { - window.removeEventListener('resize', this.resizeFooterToolbar); - } - - resizeFooterToolbar = () => { - const sider = document.querySelector('.ant-layout-sider'); - if (sider == null) { - return; - } - const { isMobile } = this.context; - const width = isMobile ? null : `calc(100% - ${sider.style.width})`; - const { width: stateWidth } = this.state; - if (stateWidth !== width) { - this.setState({ width }); - } - }; - - render() { - const { children, className, extra, ...restProps } = this.props; - const { width } = this.state; - return ( - - {extra} - {children} - - ); - } -} diff --git a/src/components/FooterToolbar/index.less b/src/components/FooterToolbar/index.less deleted file mode 100644 index de6606bd43cc46ce191dada6117d13b37f32603a..0000000000000000000000000000000000000000 --- a/src/components/FooterToolbar/index.less +++ /dev/null @@ -1,33 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.toolbar { - position: fixed; - width: 100%; - bottom: 0; - right: 0; - height: 56px; - line-height: 56px; - box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.03); - background: #fff; - border-top: 1px solid @border-color-split; - padding: 0 24px; - z-index: 9; - - &:after { - content: ''; - display: block; - clear: both; - } - - .left { - float: left; - } - - .right { - float: right; - } - - button + button { - margin-left: 8px; - } -} diff --git a/src/components/FooterToolbar/index.zh-CN.md b/src/components/FooterToolbar/index.zh-CN.md deleted file mode 100644 index 421ac08e70782ec3fb19eb6b96dc8e6d58fd51be..0000000000000000000000000000000000000000 --- a/src/components/FooterToolbar/index.zh-CN.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: FooterToolbar -subtitle: 底部工具栏 -cols: 1 -order: 6 ---- - -固定在底部的工具栏。 - -## 何时使用 - -固定在内容区域的底部,不随滚动条移动,常用于长页面的数据搜集和提交工作。 - -## API - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -children | 工具栏内容,向右对齐 | ReactNode | - -extra | 额外信息,向左对齐 | ReactNode | - diff --git a/src/components/GlobalFooter/demo/basic.md b/src/components/GlobalFooter/demo/basic.md deleted file mode 100644 index 9a06bade622c4657dd9b39fa97c2e267c119d14c..0000000000000000000000000000000000000000 --- a/src/components/GlobalFooter/demo/basic.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -order: 0 -title: 演示 -iframe: 400 ---- - -基本页脚。 - -````jsx -import GlobalFooter from 'ant-design-pro/lib/GlobalFooter'; -import { Icon } from 'antd'; - -const links = [{ - key: '帮助', - title: '帮助', - href: '', -}, { - key: 'github', - title: , - href: 'https://github.com/ant-design/ant-design-pro', - blankTarget: true, -}, { - key: '条款', - title: '条款', - href: '', - blankTarget: true, -}]; - -const copyright = Copyright 2017 蚂蚁金服体验技术部出品; - -ReactDOM.render( - - - - -, mountNode); -```` diff --git a/src/components/GlobalFooter/index.d.ts b/src/components/GlobalFooter/index.d.ts deleted file mode 100644 index 3fa5c423eba263aa4c9d39eb49f395781c5e8f43..0000000000000000000000000000000000000000 --- a/src/components/GlobalFooter/index.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import * as React from 'react'; -export interface IGlobalFooterProps { - links?: Array<{ - key?: string; - title: React.ReactNode; - href: string; - blankTarget?: boolean; - }>; - copyright?: React.ReactNode; - style?: React.CSSProperties; -} - -export default class GlobalFooter extends React.Component {} diff --git a/src/components/GlobalFooter/index.js b/src/components/GlobalFooter/index.js deleted file mode 100644 index 1c2fb74efec05e82c1a19992cdbe09784d3bb7a8..0000000000000000000000000000000000000000 --- a/src/components/GlobalFooter/index.js +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react'; -import classNames from 'classnames'; -import styles from './index.less'; - -const GlobalFooter = ({ className, links, copyright }) => { - const clsString = classNames(styles.globalFooter, className); - return ( - - ); -}; - -export default GlobalFooter; diff --git a/src/components/GlobalFooter/index.less b/src/components/GlobalFooter/index.less deleted file mode 100644 index 101dcf04511b3bc17ce1da72de1ec8ad52cd865f..0000000000000000000000000000000000000000 --- a/src/components/GlobalFooter/index.less +++ /dev/null @@ -1,29 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.globalFooter { - padding: 0 16px; - margin: 48px 0 24px 0; - text-align: center; - - .links { - margin-bottom: 8px; - - a { - color: @text-color-secondary; - transition: all 0.3s; - - &:not(:last-child) { - margin-right: 40px; - } - - &:hover { - color: @text-color; - } - } - } - - .copyright { - color: @text-color-secondary; - font-size: @font-size-base; - } -} diff --git a/src/components/GlobalFooter/index.md b/src/components/GlobalFooter/index.md deleted file mode 100644 index 55b4be46c9187818887c020f72ec3465d29b1294..0000000000000000000000000000000000000000 --- a/src/components/GlobalFooter/index.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: - en-US: GlobalFooter - zh-CN: GlobalFooter -subtitle: 全局页脚 -cols: 1 -order: 7 ---- - -页脚属于全局导航的一部分,作为对顶部导航的补充,通过传递数据控制展示内容。 - -## API - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -links | 链接数据 | array<{ title: ReactNode, href: string, blankTarget?: boolean }> | - -copyright | 版权信息 | ReactNode | - diff --git a/src/components/GlobalHeader/RightContent.js b/src/components/GlobalHeader/RightContent.js deleted file mode 100644 index dad360ff08299518c7d3fdc7026c2b3b289b883f..0000000000000000000000000000000000000000 --- a/src/components/GlobalHeader/RightContent.js +++ /dev/null @@ -1,217 +0,0 @@ -import React, { PureComponent } from 'react'; -import { FormattedMessage, formatMessage } from 'umi/locale'; -import { Spin, Tag, Menu, Icon, Avatar, Tooltip } from 'antd'; -import moment from 'moment'; -import groupBy from 'lodash/groupBy'; -import NoticeIcon from '../NoticeIcon'; -import HeaderSearch from '../HeaderSearch'; -import HeaderDropdown from '../HeaderDropdown'; -import SelectLang from '../SelectLang'; -import styles from './index.less'; - -export default class GlobalHeaderRight extends PureComponent { - getNoticeData() { - 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(); - } - if (newNotice.id) { - newNotice.key = newNotice.id; - } - if (newNotice.extra && newNotice.status) { - const color = { - todo: '', - processing: 'blue', - urgent: 'red', - doing: 'gold', - }[newNotice.status]; - newNotice.extra = ( - - {newNotice.extra} - - ); - } - return newNotice; - }); - return groupBy(newNotices, 'type'); - } - - getUnreadData = noticeData => { - const unreadMsg = {}; - Object.entries(noticeData).forEach(([key, value]) => { - if (!unreadMsg[key]) { - unreadMsg[key] = 0; - } - if (Array.isArray(value)) { - unreadMsg[key] = value.filter(item => !item.read).length; - } - }); - return unreadMsg; - }; - - changeReadState = clickedItem => { - const { id } = clickedItem; - const { dispatch } = this.props; - dispatch({ - type: 'global/changeNoticeReadState', - payload: id, - }); - }; - - fetchMoreNotices = tabProps => { - const { list, name } = tabProps; - const { dispatch, notices = [] } = this.props; - const lastItemId = notices[notices.length - 1].id; - dispatch({ - type: 'global/fetchMoreNotices', - payload: { - lastItemId, - type: name, - offset: list.length, - }, - }); - }; - - render() { - const { - currentUser, - fetchingMoreNotices, - fetchingNotices, - loadedAllNotices, - onNoticeVisibleChange, - onMenuClick, - onNoticeClear, - skeletonCount, - theme, - } = this.props; - const menu = ( - - - - - - - - - - - - - - - - - - - - ); - const loadMoreProps = { - skeletonCount, - loadedAll: loadedAllNotices, - loading: fetchingMoreNotices, - }; - const noticeData = this.getNoticeData(); - const unreadMsg = this.getUnreadData(noticeData); - let className = styles.right; - if (theme === 'dark') { - className = `${styles.right} ${styles.dark}`; - } - return ( - - { - console.log('input', value); // eslint-disable-line - }} - onPressEnter={value => { - console.log('enter', value); // eslint-disable-line - }} - /> - - - - - - { - console.log(item, tabProps); // eslint-disable-line - this.changeReadState(item, tabProps); - }} - locale={{ - emptyText: formatMessage({ id: 'component.noticeIcon.empty' }), - clear: formatMessage({ id: 'component.noticeIcon.clear' }), - loadedAll: formatMessage({ id: 'component.noticeIcon.loaded' }), - loadMore: formatMessage({ id: 'component.noticeIcon.loading-more' }), - }} - onClear={onNoticeClear} - onLoadMore={this.fetchMoreNotices} - onPopupVisibleChange={onNoticeVisibleChange} - loading={fetchingNotices} - clearClose - > - - - - - {currentUser.name ? ( - - - - {currentUser.name} - - - ) : ( - - )} - - - ); - } -} diff --git a/src/components/GlobalHeader/index.js b/src/components/GlobalHeader/index.js deleted file mode 100644 index fe96cdea6d003485c78bd404cee957f7d0a345b1..0000000000000000000000000000000000000000 --- a/src/components/GlobalHeader/index.js +++ /dev/null @@ -1,41 +0,0 @@ -import React, { PureComponent } from 'react'; -import { Icon } from 'antd'; -import Link from 'umi/link'; -import Debounce from 'lodash-decorators/debounce'; -import styles from './index.less'; -import RightContent from './RightContent'; - -export default class GlobalHeader extends PureComponent { - componentWillUnmount() { - this.triggerResizeEvent.cancel(); - } - /* eslint-disable*/ - @Debounce(600) - triggerResizeEvent() { - // eslint-disable-line - const event = document.createEvent('HTMLEvents'); - event.initEvent('resize', true, false); - window.dispatchEvent(event); - } - toggle = () => { - const { collapsed, onCollapse } = this.props; - onCollapse(!collapsed); - this.triggerResizeEvent(); - }; - render() { - const { collapsed, isMobile, logo } = this.props; - return ( - - {isMobile && ( - - - - )} - - - - - - ); - } -} diff --git a/src/components/GlobalHeader/index.less b/src/components/GlobalHeader/index.less deleted file mode 100644 index 83a4151ed6164be0a1fb5f7ecdc741e6899c23ec..0000000000000000000000000000000000000000 --- a/src/components/GlobalHeader/index.less +++ /dev/null @@ -1,130 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -@pro-header-hover-bg: rgba(0, 0, 0, 0.025); - -.header { - height: @layout-header-height; - padding: 0; - background: #fff; - box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); - position: relative; -} - -.logo { - height: @layout-header-height; - line-height: @layout-header-height; - vertical-align: top; - display: inline-block; - padding: 0 0 0 24px; - cursor: pointer; - font-size: 20px; - img { - display: inline-block; - vertical-align: middle; - } -} - -.menu { - :global(.anticon) { - margin-right: 8px; - } - :global(.ant-dropdown-menu-item) { - min-width: 160px; - } -} - -.trigger { - font-size: 20px; - height: @layout-header-height; - cursor: pointer; - transition: all 0.3s, padding 0s; - padding: ~'calc((@{layout-header-height} - 20px) / 2)' 24px; - &:hover { - background: @pro-header-hover-bg; - } -} - -.right { - float: right; - height: 100%; - overflow: hidden; - .action { - cursor: pointer; - padding: 0 12px; - display: inline-block; - transition: all 0.3s; - height: 100%; - > i { - vertical-align: middle; - color: @text-color; - } - &:hover { - background: @pro-header-hover-bg; - } - &:global(.opened) { - background: @pro-header-hover-bg; - } - } - .search { - padding: 0 12px; - &:hover { - background: transparent; - } - } - .account { - .avatar { - margin: ~'calc((@{layout-header-height} - 24px) / 2)' 0; - margin-right: 8px; - color: @primary-color; - background: rgba(255, 255, 255, 0.85); - vertical-align: top; - } - } -} - -.dark { - height: @layout-header-height; - .action { - color: rgba(255, 255, 255, 0.85); - > i { - color: rgba(255, 255, 255, 0.85); - } - &:hover, - &:global(.opened) { - background: @primary-color; - } - :global(.ant-badge) { - color: rgba(255, 255, 255, 0.85); - } - } -} - -@media only screen and (max-width: @screen-md) { - .header { - :global(.ant-divider-vertical) { - vertical-align: unset; - } - .name { - display: none; - } - i.trigger { - padding: 22px 12px; - } - .logo { - padding-left: 12px; - padding-right: 12px; - position: relative; - } - .right { - position: absolute; - right: 12px; - top: 0; - background: #fff; - .account { - .avatar { - margin-right: 0; - } - } - } - } -} diff --git a/src/components/HeaderDropdown/index.js b/src/components/HeaderDropdown/index.js deleted file mode 100644 index a19c471ac19c61933d6c4c79e0ced4b8f8b43fba..0000000000000000000000000000000000000000 --- 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.less b/src/components/HeaderDropdown/index.less deleted file mode 100644 index 6494de0a6a23f993875c16439e73ef8d3f121922..0000000000000000000000000000000000000000 --- a/src/components/HeaderDropdown/index.less +++ /dev/null @@ -1,16 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.container > * { - background-color: #fff; - box-shadow: @shadow-1-down; - border-radius: 4px; -} - -@media screen and (max-width: @screen-xs) { - .container { - width: 100% !important; - } - .container > * { - border-radius: 0 !important; - } -} diff --git a/src/components/HeaderSearch/demo/basic.md b/src/components/HeaderSearch/demo/basic.md deleted file mode 100644 index 2139207c026ba26da47c5ef7191abf1dc4b81a98..0000000000000000000000000000000000000000 --- a/src/components/HeaderSearch/demo/basic.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -order: 0 -title: 全局搜索 ---- - -通常放置在导航工具条右侧。(点击搜索图标预览效果) - -````jsx -import HeaderSearch from 'ant-design-pro/lib/HeaderSearch'; - -ReactDOM.render( - - { - console.log('input', value); // eslint-disable-line - }} - onPressEnter={(value) => { - console.log('enter', value); // eslint-disable-line - }} - /> - -, mountNode); -```` diff --git a/src/components/HeaderSearch/index.d.ts b/src/components/HeaderSearch/index.d.ts deleted file mode 100644 index d78fde471ccd522d821f77b790647f5620efdb7e..0000000000000000000000000000000000000000 --- 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.en-US.md b/src/components/HeaderSearch/index.en-US.md deleted file mode 100644 index 6f4d06b4e10f43f16e2b997629a8ecd79ca50a3c..0000000000000000000000000000000000000000 --- a/src/components/HeaderSearch/index.en-US.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: - en-US: HeaderSearch - zh-CN: HeaderSearch -subtitle: Top search box -cols: 1 -order: 8 ---- - -Usually placed as an entry to the global search, placed on the right side of the navigation toolbar. - -## API - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -placeholder | placeholder text | string | - -dataSource | current list of prompts | string[] | - -onSearch | Called when searching items. | function(value) | - -onChange | Called when select an option or input value change, or value of input is changed | function(value) | - -onSelect | Called when a option is selected. param is option's value and option instance. | function(value) | - -onPressEnter | Callback when pressing Enter | function(value) | - -onVisibleChange | Show or hide the callback of the text box | function(value) |- -defaultOpen | The input box is displayed for the first time. | boolean | false -open | The input box is displayed | booelan |false \ No newline at end of file diff --git a/src/components/HeaderSearch/index.js b/src/components/HeaderSearch/index.js deleted file mode 100644 index 04f8b38ec8ff2e1c06455363a91d3e1e8f64aa9e..0000000000000000000000000000000000000000 --- a/src/components/HeaderSearch/index.js +++ /dev/null @@ -1,145 +0,0 @@ -import React, { PureComponent } from 'react'; -import PropTypes from 'prop-types'; -import { Input, Icon, AutoComplete } from 'antd'; -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, - }; - - static defaultProps = { - defaultActiveFirstOption: false, - onPressEnter: () => {}, - onSearch: () => {}, - onChange: () => {}, - className: '', - placeholder: '', - dataSource: [], - defaultOpen: false, - onVisibleChange: () => {}, - }; - - static getDerivedStateFromProps(props) { - if ('open' in props) { - return { - searchMode: props.open, - }; - } - return null; - } - - constructor(props) { - super(props); - this.state = { - searchMode: props.defaultOpen, - value: '', - }; - } - - componentWillUnmount() { - clearTimeout(this.timeout); - } - - onKeyDown = e => { - if (e.key === 'Enter') { - const { onPressEnter } = this.props; - const { value } = this.state; - this.timeout = setTimeout(() => { - onPressEnter(value); // Fix duplicate onPressEnter - }, 0); - } - }; - - onChange = value => { - const { onSearch, onChange } = this.props; - this.setState({ value }); - if (onSearch) { - onSearch(value); - } - if (onChange) { - onChange(value); - } - }; - - enterSearchMode = () => { - const { onVisibleChange } = this.props; - onVisibleChange(true); - this.setState({ searchMode: true }, () => { - const { searchMode } = this.state; - if (searchMode) { - this.input.focus(); - } - }); - }; - - leaveSearchMode = () => { - this.setState({ - searchMode: false, - value: '', - }); - }; - - // NOTE: 不能小于500,如果长按某键,第一次触发auto repeat的间隔是500ms,小于500会导致触发2次 - @Bind() - @Debounce(500, { - leading: true, - trailing: false, - }) - debouncePressEnter() { - const { onPressEnter } = this.props; - const { value } = this.state; - onPressEnter(value); - } - - render() { - const { className, placeholder, open, ...restProps } = this.props; - const { searchMode, value } = this.state; - delete restProps.defaultOpen; // for rc-select not affected - const inputClass = classNames(styles.input, { - [styles.show]: searchMode, - }); - return ( - { - if (propertyName === 'width' && !searchMode) { - const { onVisibleChange } = this.props; - onVisibleChange(searchMode); - } - }} - > - - - { - this.input = node; - }} - aria-label={placeholder} - placeholder={placeholder} - onKeyDown={this.onKeyDown} - onBlur={this.leaveSearchMode} - /> - - - ); - } -} diff --git a/src/components/HeaderSearch/index.less b/src/components/HeaderSearch/index.less deleted file mode 100644 index e97386d82d6dc3fe3bfee8d30d0dd38b6174b984..0000000000000000000000000000000000000000 --- a/src/components/HeaderSearch/index.less +++ /dev/null @@ -1,32 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.headerSearch { - :global(.anticon-search) { - cursor: pointer; - font-size: 16px; - } - .input { - transition: width 0.3s, margin-left 0.3s; - width: 0; - background: transparent; - border-radius: 0; - :global(.ant-select-selection) { - background: transparent; - } - input { - border: 0; - padding-left: 0; - padding-right: 0; - box-shadow: none !important; - } - &, - &:hover, - &:focus { - border-bottom: 1px solid @border-color-base; - } - &.show { - width: 210px; - margin-left: 8px; - } - } -} diff --git a/src/components/HeaderSearch/index.zh-CN.md b/src/components/HeaderSearch/index.zh-CN.md deleted file mode 100644 index 9c108c2bc14594ea082fe93af37836e610862f63..0000000000000000000000000000000000000000 --- a/src/components/HeaderSearch/index.zh-CN.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: - en-US: HeaderSearch - zh-CN: HeaderSearch -subtitle: 顶部搜索框 -cols: 1 -order: 8 ---- - -通常作为全局搜索的入口,放置在导航工具条右侧。 - -## API - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -placeholder | 占位文字 | string | - -dataSource | 当前提示内容列表 | string[] | - -onSearch | 搜索补全项的时候调用 | function(value) | - -onChange | 选中 option,或 input 的 value 变化时,调用此函数 | function(value) | - -onSelect | 被选中时调用,参数为选中项的 value 值 | function(value) | - -onPressEnter | 按下回车时的回调 | function(value) | - -onVisibleChange | 显示或隐藏文本框的回调 | function(value) |- -defaultOpen | 输入框首次显示是否显示 | boolean | false -open | 控制输入框是否显示 | booelan |false \ No newline at end of file diff --git a/src/components/Login/LoginItem.d.ts b/src/components/Login/LoginItem.d.ts deleted file mode 100644 index 30a7a2d6a483e2a8224fd315498f35ce72958f63..0000000000000000000000000000000000000000 --- a/src/components/Login/LoginItem.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as React from 'react'; -export interface ILoginItemProps { - name?: string; - rules?: any[]; - style?: React.CSSProperties; - onGetCaptcha?: () => void; - placeholder?: string; - buttonText?: React.ReactNode; -} - -export class LoginItem extends React.Component {} diff --git a/src/components/Login/LoginItem.js b/src/components/Login/LoginItem.js deleted file mode 100644 index b3cc4d48a978da65faa8d85fef62c7e00040f09a..0000000000000000000000000000000000000000 --- a/src/components/Login/LoginItem.js +++ /dev/null @@ -1,147 +0,0 @@ -import React, { Component } from 'react'; -import { Form, Input, Button, Row, Col } from 'antd'; -import omit from 'omit.js'; -import styles from './index.less'; -import ItemMap from './map'; -import LoginContext from './loginContext'; - -const FormItem = Form.Item; - -class WrapFormItem extends Component { - static defaultProps = { - getCaptchaButtonText: 'captcha', - getCaptchaSecondText: 'second', - }; - - constructor(props) { - super(props); - this.state = { - count: 0, - }; - } - - componentDidMount() { - const { updateActive, name } = this.props; - if (updateActive) { - updateActive(name); - } - } - - componentWillUnmount() { - clearInterval(this.interval); - } - - onGetCaptcha = () => { - const { onGetCaptcha } = this.props; - const result = onGetCaptcha ? onGetCaptcha() : null; - if (result === false) { - return; - } - if (result instanceof Promise) { - result.then(this.runGetCaptchaCountDown); - } else { - this.runGetCaptchaCountDown(); - } - }; - - getFormItemOptions = ({ onChange, defaultValue, customprops, rules }) => { - const options = { - rules: rules || customprops.rules, - }; - if (onChange) { - options.onChange = onChange; - } - if (defaultValue) { - options.initialValue = defaultValue; - } - return options; - }; - - runGetCaptchaCountDown = () => { - const { countDown } = this.props; - let count = countDown || 59; - this.setState({ count }); - this.interval = setInterval(() => { - count -= 1; - this.setState({ count }); - if (count === 0) { - clearInterval(this.interval); - } - }, 1000); - }; - - render() { - const { count } = this.state; - - const { - form: { getFieldDecorator }, - } = this.props; - - // 这么写是为了防止restProps中 带入 onChange, defaultValue, rules props - const { - onChange, - customprops, - defaultValue, - rules, - name, - getCaptchaButtonText, - getCaptchaSecondText, - updateActive, - type, - ...restProps - } = this.props; - - // get getFieldDecorator props - const options = this.getFormItemOptions(this.props); - - const otherProps = restProps || {}; - if (type === 'Captcha') { - const inputProps = omit(otherProps, ['onGetCaptcha', 'countDown']); - return ( - - - - {getFieldDecorator(name, options)()} - - - - {count ? `${count} ${getCaptchaSecondText}` : getCaptchaButtonText} - - - - - ); - } - return ( - - {getFieldDecorator(name, options)()} - - ); - } -} - -const LoginItem = {}; -Object.keys(ItemMap).forEach(key => { - const item = ItemMap[key]; - LoginItem[key] = props => ( - - {context => ( - - )} - - ); -}); - -export default LoginItem; diff --git a/src/components/Login/LoginSubmit.js b/src/components/Login/LoginSubmit.js deleted file mode 100644 index 4aebabf89a98a530292ba87534620e9ded8f88e7..0000000000000000000000000000000000000000 --- a/src/components/Login/LoginSubmit.js +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import classNames from 'classnames'; -import { Button, Form } from 'antd'; -import styles from './index.less'; - -const FormItem = Form.Item; - -const LoginSubmit = ({ className, ...rest }) => { - const clsString = classNames(styles.submit, className); - return ( - - - - ); -}; - -export default LoginSubmit; diff --git a/src/components/Login/LoginTab.d.ts b/src/components/Login/LoginTab.d.ts deleted file mode 100644 index db651f7b40c6194d1cd0cb8430736fc4d369e34d..0000000000000000000000000000000000000000 --- a/src/components/Login/LoginTab.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import * as React from 'react'; - -export interface ILoginTabProps { - key?: string; - tab?: React.ReactNode; -} -export default class LoginTab extends React.Component {} diff --git a/src/components/Login/LoginTab.js b/src/components/Login/LoginTab.js deleted file mode 100644 index 7c46db53292feb02b13ef3863f21ef25294b3a0e..0000000000000000000000000000000000000000 --- a/src/components/Login/LoginTab.js +++ /dev/null @@ -1,41 +0,0 @@ -import React, { Component } from 'react'; -import { Tabs } from 'antd'; -import LoginContext from './loginContext'; - -const { TabPane } = Tabs; - -const generateId = (() => { - let i = 0; - return (prefix = '') => { - i += 1; - return `${prefix}${i}`; - }; -})(); - -class LoginTab extends Component { - constructor(props) { - super(props); - this.uniqueId = generateId('login-tab-'); - } - - componentDidMount() { - const { tabUtil } = this.props; - tabUtil.addTab(this.uniqueId); - } - - render() { - const { children } = this.props; - return {children}; - } -} - -const wrapContext = props => ( - - {value => } - -); - -// 标志位 用来判断是不是自定义组件 -wrapContext.typeName = 'LoginTab'; - -export default wrapContext; diff --git a/src/components/Login/demo/basic.md b/src/components/Login/demo/basic.md deleted file mode 100644 index 5fbd0ca25448f92e964538c545edaf07d595ff27..0000000000000000000000000000000000000000 --- a/src/components/Login/demo/basic.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -order: 0 -title: - zh-CN: 标准登录 - en-US: Standard Login ---- - -Support login with account and mobile number. - -````jsx -import Login from 'ant-design-pro/lib/Login'; -import { Alert, Checkbox } from 'antd'; - -const { Tab, UserName, Password, Mobile, Captcha, Submit } = Login; - -class LoginDemo extends React.Component { - state = { - notice: '', - type: 'tab2', - autoLogin: true, - } - onSubmit = (err, values) => { - console.log('value collected ->', { ...values, autoLogin: this.state.autoLogin }); - if (this.state.type === 'tab1') { - this.setState({ - notice: '', - }, () => { - if (!err && (values.username !== 'admin' || values.password !== '888888')) { - setTimeout(() => { - this.setState({ - notice: 'The combination of username and password is incorrect!', - }); - }, 500); - } - }); - } - } - onTabChange = (key) => { - this.setState({ - type: key, - }); - } - changeAutoLogin = (e) => { - this.setState({ - autoLogin: e.target.checked, - }); - } - render() { - return ( - - - { - this.state.notice && - - } - - - - - - console.log('Get captcha!')} name="captcha" /> - - - Keep me logged in - Forgot password - - Login - - Other login methods - - - - Register - - - ); - } -} - -ReactDOM.render(, mountNode); -```` - - diff --git a/src/components/Login/index.d.ts b/src/components/Login/index.d.ts deleted file mode 100644 index 6a6f67fe6b1f250bd3708d0120bea1a22026b81b..0000000000000000000000000000000000000000 --- a/src/components/Login/index.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import Button from 'antd/lib/button'; -import * as React from 'react'; -import LoginItem from './LoginItem'; -import LoginTab from './LoginTab'; - -export interface ILoginProps { - defaultActiveKey?: string; - onTabChange?: (key: string) => void; - style?: React.CSSProperties; - onSubmit?: (error: any, values: any) => void; -} - -export default class Login extends React.Component { - public static Tab: typeof LoginTab; - public static UserName: typeof LoginItem; - public static Password: typeof LoginItem; - public static Mobile: typeof LoginItem; - public static Captcha: typeof LoginItem; - public static Submit: typeof Button; -} diff --git a/src/components/Login/index.en-US.md b/src/components/Login/index.en-US.md deleted file mode 100644 index 3b5992e28de312daba880f4ce9f834c61c626d40..0000000000000000000000000000000000000000 --- a/src/components/Login/index.en-US.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: Login -cols: 1 -order: 15 ---- - -Support multiple common ways of login with built-in controls. You can choose your own combinations and use with your custom controls. - -## API - -### Login - -Property | Description | Type | Default -----|------|-----|------ -defaultActiveKey | default key to activate the tab panel | String | - -onTabChange | callback on changing tabs | (key) => void | - -onSubmit | callback on submit | (err, values) => void | - - -### Login.Tab - -Property | Description | Type | Default -----|------|-----|------ -key | key of the tab | String | - -tab | displayed text of the tab | ReactNode | - - -### Login.UserName - -Property | Description | Type | Default -----|------|-----|------ -name | name of the control, also the key of the submitted data | String | - -rules | validation rules, same with [option.rules](getFieldDecorator(id, options)) in Form getFieldDecorator(id, options) | object[] | - - -Apart from the above properties, Login.Username also support all properties of antd.Input, together with the default values of basic settings, such as _placeholder_, _size_ and _prefix_. All of these default values can be over-written. - -### Login.Password, Login.Mobile are the same as Login.UserName - -### Login.Captcha - -Property | Description | Type | Default -----|------|-----|------ -onGetCaptcha | callback on getting a new Captcha | () => (void \| false \| Promise) | - -countDown | count down | number |- -buttonText | text on getting a new Captcha | ReactNode | '获取验证码' - -Apart from the above properties, _Login.Captcha_ support the same properties with _Login.UserName_. - -### Login.Submit - -Support all properties of _antd.Button_. \ No newline at end of file diff --git a/src/components/Login/index.js b/src/components/Login/index.js deleted file mode 100644 index 79cc56deb5e50f15d9e90915e96545794a7360dc..0000000000000000000000000000000000000000 --- a/src/components/Login/index.js +++ /dev/null @@ -1,132 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import { Form, Tabs } from 'antd'; -import classNames from 'classnames'; -import LoginItem from './LoginItem'; -import LoginTab from './LoginTab'; -import LoginSubmit from './LoginSubmit'; -import styles from './index.less'; -import LoginContext from './loginContext'; - -class Login extends Component { - static propTypes = { - className: PropTypes.string, - defaultActiveKey: PropTypes.string, - onTabChange: PropTypes.func, - onSubmit: PropTypes.func, - }; - - static defaultProps = { - className: '', - defaultActiveKey: '', - onTabChange: () => {}, - onSubmit: () => {}, - }; - - constructor(props) { - super(props); - this.state = { - type: props.defaultActiveKey, - tabs: [], - active: {}, - }; - } - - onSwitch = type => { - this.setState({ - type, - }); - const { onTabChange } = this.props; - onTabChange(type); - }; - - getContext = () => { - const { tabs } = this.state; - const { form } = this.props; - return { - tabUtil: { - addTab: id => { - this.setState({ - tabs: [...tabs, id], - }); - }, - removeTab: id => { - this.setState({ - tabs: tabs.filter(currentId => currentId !== id), - }); - }, - }, - form, - updateActive: activeItem => { - const { type, active } = this.state; - if (active[type]) { - active[type].push(activeItem); - } else { - active[type] = [activeItem]; - } - this.setState({ - active, - }); - }, - }; - }; - - handleSubmit = e => { - e.preventDefault(); - const { active, type } = this.state; - const { form, onSubmit } = this.props; - const activeFileds = active[type]; - form.validateFields(activeFileds, { force: true }, (err, values) => { - onSubmit(err, values); - }); - }; - - render() { - const { className, children } = this.props; - const { type, tabs } = this.state; - const TabChildren = []; - const otherChildren = []; - React.Children.forEach(children, item => { - if (!item) { - return; - } - // eslint-disable-next-line - if (item.type.typeName === 'LoginTab') { - TabChildren.push(item); - } else { - otherChildren.push(item); - } - }); - return ( - - - - {tabs.length ? ( - - - {TabChildren} - - {otherChildren} - - ) : ( - children - )} - - - - ); - } -} - -Login.Tab = LoginTab; -Login.Submit = LoginSubmit; -Object.keys(LoginItem).forEach(item => { - Login[item] = LoginItem[item]; -}); - -export default Form.create()(Login); diff --git a/src/components/Login/index.less b/src/components/Login/index.less deleted file mode 100644 index 646b6631d2b771e6f09332e62f310230715e462b..0000000000000000000000000000000000000000 --- a/src/components/Login/index.less +++ /dev/null @@ -1,53 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.login { - :global { - .ant-tabs .ant-tabs-bar { - border-bottom: 0; - margin-bottom: 24px; - text-align: center; - } - - .ant-form-item { - margin: 0 2px 24px; - } - } - - .getCaptcha { - display: block; - width: 100%; - } - - .icon { - font-size: 24px; - color: rgba(0, 0, 0, 0.2); - margin-left: 16px; - vertical-align: middle; - cursor: pointer; - transition: color 0.3s; - - &:hover { - color: @primary-color; - } - } - - .other { - text-align: left; - margin-top: 24px; - line-height: 22px; - - .register { - float: right; - } - } - - .prefixIcon { - font-size: @font-size-base; - color: @disabled-color; - } - - .submit { - width: 100%; - margin-top: 24px; - } -} diff --git a/src/components/Login/index.zh-CN.md b/src/components/Login/index.zh-CN.md deleted file mode 100644 index a869e96c323ab2cb9861121e4278f65d08b3e167..0000000000000000000000000000000000000000 --- a/src/components/Login/index.zh-CN.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: Login -subtitle: 登录 -cols: 1 -order: 15 ---- - -支持多种登录方式切换,内置了几种常见的登录控件,可以灵活组合,也支持和自定义控件配合使用。 - -## API - -### Login - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -defaultActiveKey | 默认激活 tab 面板的 key | String | - -onTabChange | 切换页签时的回调 | (key) => void | - -onSubmit | 点击提交时的回调 | (err, values) => void | - - -### Login.Tab - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -key | 对应选项卡的 key | String | - -tab | 选项卡头显示文字 | ReactNode | - - -### Login.UserName - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -name | 控件标记,提交数据中同样以此为 key | String | - -rules | 校验规则,同 Form getFieldDecorator(id, options) 中 [option.rules 的规则](getFieldDecorator(id, options)) | object[] | - - -除上述属性以外,Login.UserName 还支持 antd.Input 的所有属性,并且自带默认的基础配置,包括 `placeholder` `size` `prefix` 等,这些基础配置均可被覆盖。 -## Login.Password、Login.Mobile 同 Login.UserName - -### Login.Captcha - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -onGetCaptcha | 点击获取校验码的回调 | () => (void \| false \| Promise) | - -countDown | 倒计时 | number |- -buttonText | 点击获取校验码的说明文字 | ReactNode | '获取验证码' - -除上述属性以外,Login.Captcha 支持的属性与 Login.UserName 相同。 - -### Login.Submit - -支持 antd.Button 的所有属性。 diff --git a/src/components/Login/loginContext.js b/src/components/Login/loginContext.js deleted file mode 100644 index a13e6599c4f4278d8bc5d4cf76e20e374e413fba..0000000000000000000000000000000000000000 --- a/src/components/Login/loginContext.js +++ /dev/null @@ -1,4 +0,0 @@ -import { createContext } from 'react'; - -const LoginContext = createContext(); -export default LoginContext; diff --git a/src/components/Login/map.js b/src/components/Login/map.js deleted file mode 100644 index dfa88199875ab0079636c8ccfc8f3037fc7eab99..0000000000000000000000000000000000000000 --- a/src/components/Login/map.js +++ /dev/null @@ -1,65 +0,0 @@ -import React from 'react'; -import { Icon } from 'antd'; -import styles from './index.less'; - -export default { - UserName: { - props: { - size: 'large', - id: 'userName', - prefix: , - placeholder: 'admin', - }, - rules: [ - { - required: true, - message: 'Please enter username!', - }, - ], - }, - Password: { - props: { - size: 'large', - prefix: , - type: 'password', - id: 'password', - placeholder: '888888', - }, - rules: [ - { - required: true, - message: 'Please enter password!', - }, - ], - }, - Mobile: { - props: { - size: 'large', - prefix: , - placeholder: 'mobile number', - }, - rules: [ - { - required: true, - message: 'Please enter mobile number!', - }, - { - pattern: /^1\d{10}$/, - message: 'Wrong mobile number format!', - }, - ], - }, - Captcha: { - props: { - size: 'large', - prefix: , - placeholder: 'captcha', - }, - rules: [ - { - required: true, - message: 'Please enter Captcha!', - }, - ], - }, -}; diff --git a/src/components/NoticeIcon/NoticeIconTab.d.ts b/src/components/NoticeIcon/NoticeIconTab.d.ts deleted file mode 100644 index 6ffaf032159f3cb909fde4bcda2ce57549bd9166..0000000000000000000000000000000000000000 --- a/src/components/NoticeIcon/NoticeIconTab.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { SkeletonProps } from 'antd/lib/skeleton'; -import * as React from 'react'; - -export interface INoticeIconData { - avatar?: string | React.ReactNode; - title?: React.ReactNode; - description?: React.ReactNode; - datetime?: React.ReactNode; - extra?: React.ReactNode; - style?: React.CSSProperties; -} - -export interface INoticeIconTabProps { - count?: number; - emptyText?: React.ReactNode; - emptyImage?: string; - list?: INoticeIconData[]; - loadedAll?: boolean; - loading?: boolean; - name?: string; - showClear?: boolean; - skeletonCount?: number; - skeletonProps?: SkeletonProps; - style?: React.CSSProperties; - title?: string; -} - -export default class NoticeIconTab extends React.Component {} diff --git a/src/components/NoticeIcon/NoticeList.js b/src/components/NoticeIcon/NoticeList.js deleted file mode 100644 index 6b73e6e0de9987fcc11a8df296b43e5cda5822bf..0000000000000000000000000000000000000000 --- a/src/components/NoticeIcon/NoticeList.js +++ /dev/null @@ -1,108 +0,0 @@ -import React from 'react'; -import { Avatar, List, Skeleton } from 'antd'; -import classNames from 'classnames'; -import styles from './NoticeList.less'; - -let ListElement = null; - -export default function NoticeList({ - data = [], - onClick, - onClear, - title, - locale, - emptyText, - emptyImage, - loading, - onLoadMore, - visible, - loadedAll = true, - scrollToLoad = true, - showClear = true, - skeletonCount = 5, - skeletonProps = {}, -}) { - if (data.length === 0) { - return ( - - {emptyImage ? : null} - {emptyText || locale.emptyText} - - ); - } - const loadingList = Array.from({ length: loading ? skeletonCount : 0 }).map(() => ({ loading })); - const LoadMore = loadedAll ? ( - - {locale.loadedAll} - - ) : ( - - {locale.loadMore} - - ); - const onScroll = event => { - if (!scrollToLoad || loading || loadedAll) return; - if (typeof onLoadMore !== 'function') return; - const { currentTarget: t } = event; - if (t.scrollHeight - t.scrollTop - t.clientHeight <= 40) { - onLoadMore(event); - ListElement = t; - } - }; - if (!visible && ListElement) { - try { - ListElement.scrollTo(null, 0); - } catch (err) { - ListElement = null; - } - } - return ( - - - {[...data, ...loadingList].map((item, i) => { - const itemCls = classNames(styles.item, { - [styles.read]: item.read, - }); - // eslint-disable-next-line no-nested-ternary - const leftIcon = item.avatar ? ( - typeof item.avatar === 'string' ? ( - - ) : ( - {item.avatar} - ) - ) : null; - - return ( - onClick(item)}> - - - {item.title} - {item.extra} - - } - description={ - - - {item.description} - - {item.datetime} - - } - /> - - - ); - })} - - {showClear ? ( - - {locale.clear} {title} - - ) : null} - - ); -} diff --git a/src/components/NoticeIcon/NoticeList.less b/src/components/NoticeIcon/NoticeList.less deleted file mode 100644 index 8435414a23e724846f5b2d8f6679f834cf8cd79e..0000000000000000000000000000000000000000 --- a/src/components/NoticeIcon/NoticeList.less +++ /dev/null @@ -1,94 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.list { - max-height: 400px; - overflow: auto; - &::-webkit-scrollbar { - display: none; - } - .item { - transition: all 0.3s; - overflow: hidden; - cursor: pointer; - padding-left: 24px; - padding-right: 24px; - - .meta { - width: 100%; - } - - .avatar { - background: #fff; - margin-top: 4px; - } - .iconElement { - font-size: 32px; - } - - &.read { - opacity: 0.4; - } - &:last-child { - border-bottom: 0; - } - &:hover { - background: @primary-1; - } - .title { - font-weight: normal; - margin-bottom: 8px; - } - .description { - font-size: 12px; - line-height: @line-height-base; - } - .datetime { - font-size: 12px; - margin-top: 4px; - line-height: @line-height-base; - } - .extra { - float: right; - color: @text-color-secondary; - font-weight: normal; - margin-right: 0; - margin-top: -1.5px; - } - } - .loadMore { - padding: 8px 0; - cursor: pointer; - color: @primary-6; - text-align: center; - &.loadedAll { - cursor: unset; - color: rgba(0, 0, 0, 0.25); - } - } -} - -.notFound { - text-align: center; - padding: 73px 0 88px 0; - color: @text-color-secondary; - img { - display: inline-block; - margin-bottom: 16px; - height: 76px; - } -} - -.clear { - height: 46px; - line-height: 46px; - text-align: center; - color: @text-color; - border-radius: 0 0 @border-radius-base @border-radius-base; - border-top: 1px solid @border-color-split; - transition: all 0.3s; - cursor: pointer; - - &:hover { - color: @heading-color; - } -} diff --git a/src/components/NoticeIcon/demo/basic.md b/src/components/NoticeIcon/demo/basic.md deleted file mode 100644 index dc9afeaa84b67071ac477b3cdda7f1e6b3acda9f..0000000000000000000000000000000000000000 --- a/src/components/NoticeIcon/demo/basic.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -order: 1 -title: 通知图标 ---- - -通常用在导航工具栏上。 - -````jsx -import NoticeIcon from 'ant-design-pro/lib/NoticeIcon'; - -ReactDOM.render(, mountNode); -```` diff --git a/src/components/NoticeIcon/demo/popover.md b/src/components/NoticeIcon/demo/popover.md deleted file mode 100644 index e49e2a2f0bb7d57dc9efaab49942c96ab40b147b..0000000000000000000000000000000000000000 --- a/src/components/NoticeIcon/demo/popover.md +++ /dev/null @@ -1,178 +0,0 @@ ---- -order: 2 -title: 带浮层卡片 ---- - -点击展开通知卡片,展现多种类型的通知,通常放在导航工具栏。 - -````jsx -import NoticeIcon from 'ant-design-pro/lib/NoticeIcon'; -import moment from 'moment'; -import groupBy from 'lodash/groupBy'; -import { Tag } from 'antd'; - -const data = [{ - id: '000000001', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', - title: '你收到了 14 份新周报', - datetime: '2017-08-09', - type: '通知', -}, { - id: '000000002', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png', - title: '你推荐的 曲妮妮 已通过第三轮面试', - datetime: '2017-08-08', - type: '通知', -}, { - id: '000000003', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png', - title: '这种模板可以区分多种通知类型', - datetime: '2017-08-07', - read: true, - type: '通知', -}, { - id: '000000004', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', - title: '左侧图标用于区分不同的类型', - datetime: '2017-08-07', - type: '通知', -}, { - id: '000000005', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', - title: '内容不要超过两行字,超出时自动截断', - datetime: '2017-08-07', - type: '通知', -}, { - id: '000000006', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', - title: '曲丽丽 评论了你', - description: '描述信息描述信息描述信息', - datetime: '2017-08-07', - type: '消息', - clickClose: true, -}, { - id: '000000007', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', - title: '朱偏右 回复了你', - description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', - datetime: '2017-08-07', - type: '消息', - clickClose: true, -}, { - id: '000000008', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', - title: '标题', - description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', - datetime: '2017-08-07', - type: '消息', - clickClose: true, -}, { - id: '000000009', - title: '任务名称', - description: '任务需要在 2017-01-12 20:00 前启动', - extra: '未开始', - status: 'todo', - type: '待办', -}, { - id: '000000010', - title: '第三方紧急代码变更', - description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', - extra: '马上到期', - status: 'urgent', - type: '待办', -}, { - id: '000000011', - title: '信息安全考试', - description: '指派竹尔于 2017-01-09 前完成更新并发布', - extra: '已耗时 8 天', - status: 'doing', - type: '待办', -}, { - id: '000000012', - title: 'ABCD 版本发布', - description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', - extra: '进行中', - status: 'processing', - type: '待办', -}]; - -function onItemClick(item, tabProps) { - console.log(item, tabProps); -} - -function onClear(tabTitle) { - console.log(tabTitle); -} - -function getNoticeData(notices) { - if (notices.length === 0) { - return {}; - } - const newNotices = notices.map((notice) => { - const newNotice = { ...notice }; - if (newNotice.datetime) { - newNotice.datetime = moment(notice.datetime).fromNow(); - } - // transform id to item key - if (newNotice.id) { - newNotice.key = newNotice.id; - } - if (newNotice.extra && newNotice.status) { - const color = ({ - todo: '', - processing: 'blue', - urgent: 'red', - doing: 'gold', - })[newNotice.status]; - newNotice.extra = {newNotice.extra}; - } - return newNotice; - }); - return groupBy(newNotices, 'type'); -} - -const noticeData = getNoticeData(data); - -ReactDOM.render( - - - - - - - -, mountNode); -```` - -```css - -``` diff --git a/src/components/NoticeIcon/index.d.ts b/src/components/NoticeIcon/index.d.ts deleted file mode 100644 index f7d6479aa89d8584d37e0f7360b1ddc705a71ca8..0000000000000000000000000000000000000000 --- a/src/components/NoticeIcon/index.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import * as React from 'react'; -import NoticeIconTab, { INoticeIconData } from './NoticeIconTab'; - -export interface INoticeIconProps { - count?: number; - bell?: React.ReactNode; - className?: string; - loading?: boolean; - onClear?: (tabName: string) => void; - onItemClick?: (item: INoticeIconData, tabProps: INoticeIconProps) => void; - onLoadMore?: (tabProps: INoticeIconProps) => void; - onTabChange?: (tabTile: string) => void; - style?: React.CSSProperties; - onPopupVisibleChange?: (visible: boolean) => void; - popupVisible?: boolean; - locale?: { - emptyText: string; - clear: string; - loadedAll: string; - loadMore: string; - }; - clearClose?: boolean; -} - -export default class NoticeIcon extends React.Component { - public static Tab: typeof NoticeIconTab; -} diff --git a/src/components/NoticeIcon/index.en-US.md b/src/components/NoticeIcon/index.en-US.md deleted file mode 100644 index a5a5f214b1043ea09c200ea70d839128df87484b..0000000000000000000000000000000000000000 --- a/src/components/NoticeIcon/index.en-US.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: NoticeIcon -subtitle: Notification Menu -cols: 1 -order: 9 ---- - -用在导航工具栏上,作为整个产品统一的通知中心。 - -## API - -Property | Description | Type | Default -----|------|-----|------ -count | Total number of messages | number | - -bell | Change the bell Icon | ReactNode | `` -loading | Popup card loading status | boolean | `false` -onClear | Click to clear button the callback | function(tabName) | - -onItemClick | Click on the list item's callback | function(item, tabProps) | - -onLoadMore | Callback of click for loading more | function(tabProps, event) | - -onPopupVisibleChange | Popup Card Showing or Hiding Callbacks | function(visible) | - -onTabChange | Switching callbacks for tabs | function(tabTitle) | - -popupVisible | Popup card display state | boolean | - -locale | Default message text | Object | `{ emptyText: 'No notifications', clear: 'Clear', loadedAll: 'Loaded', loadMore: 'Loading more' }` -clearClose | Close menu after clear | boolean | `false` - -### NoticeIcon.Tab - -Property | Description | Type | Default -----|------|-----|------ -count | Unread messages count of this tab | number | list.length -emptyText | Message text when list is empty | ReactNode | - -emptyImage | Image when list is empty | string | - -list | List data, format refer to the following table | Array | `[]` -loadedAll | All messages have been loaded | boolean | `true` -loading | Loading status of this tab | boolean | `false` -name | identifier for message Tab | string | - -scrollToLoad | Scroll to load | boolean | `true` -skeletonCount | Number of skeleton when tab is loading | number | `5` -skeletonProps | Props of skeleton | SkeletonProps | `{}` -showClear | Clear button display status | boolean | `true` -title | header for message Tab | string | - - -### Tab data - -Property | Description | Type | Default -----|------|-----|------ -avatar | avatar img url | string \| ReactNode | - -title | title | ReactNode | - -description | description info | ReactNode | - -datetime | Timestamps | ReactNode | - -extra | Additional information in the upper right corner of the list item | ReactNode | - -clickClose | Close menu after clicking list item | boolean | `false` diff --git a/src/components/NoticeIcon/index.js b/src/components/NoticeIcon/index.js deleted file mode 100644 index 133819bb1e580f88020b5609c6d4afd3aae35883..0000000000000000000000000000000000000000 --- a/src/components/NoticeIcon/index.js +++ /dev/null @@ -1,159 +0,0 @@ -import React, { PureComponent, Fragment } from 'react'; -import ReactDOM from 'react-dom'; -import { Icon, Tabs, Badge, Spin } from 'antd'; -import classNames from 'classnames'; -import HeaderDropdown from '../HeaderDropdown'; -import List from './NoticeList'; -import styles from './index.less'; - -const { TabPane } = Tabs; - -export default class NoticeIcon extends PureComponent { - static Tab = TabPane; - - static defaultProps = { - onItemClick: () => {}, - onPopupVisibleChange: () => {}, - onTabChange: () => {}, - onClear: () => {}, - loading: false, - clearClose: false, - locale: { - emptyText: 'No notifications', - clear: 'Clear', - loadedAll: 'Loaded', - loadMore: 'Loading more', - }, - emptyImage: 'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg', - }; - - state = { - visible: false, - }; - - onItemClick = (item, tabProps) => { - const { onItemClick } = this.props; - const { clickClose } = item; - onItemClick(item, tabProps); - if (clickClose) { - this.popover.click(); - } - }; - - onClear = name => { - const { onClear, clearClose } = this.props; - onClear(name); - if (clearClose) { - this.popover.click(); - } - }; - - onTabChange = tabType => { - const { onTabChange } = this.props; - onTabChange(tabType); - }; - - onLoadMore = (tabProps, event) => { - const { onLoadMore } = this.props; - onLoadMore(tabProps, event); - }; - - getNotificationBox() { - const { visible } = this.state; - const { children, loading, locale } = this.props; - if (!children) { - return null; - } - const panes = React.Children.map(children, child => { - const { - list, - title, - name, - count, - emptyText, - emptyImage, - showClear, - loadedAll, - scrollToLoad, - skeletonCount, - skeletonProps, - loading: tabLoading, - } = child.props; - const len = list && list.length ? list.length : 0; - const msgCount = count || count === 0 ? count : len; - const tabTitle = msgCount > 0 ? `${title} (${msgCount})` : title; - return ( - - this.onClear(name)} - onClick={item => this.onItemClick(item, child.props)} - onLoadMore={event => this.onLoadMore(child.props, event)} - scrollToLoad={scrollToLoad} - showClear={showClear} - skeletonCount={skeletonCount} - skeletonProps={skeletonProps} - title={title} - visible={visible} - /> - - ); - }); - return ( - - - - {panes} - - - - ); - } - - handleVisibleChange = visible => { - const { onPopupVisibleChange } = this.props; - this.setState({ visible }); - onPopupVisibleChange(visible); - }; - - render() { - const { className, count, popupVisible, bell } = this.props; - const { visible } = this.state; - const noticeButtonClass = classNames(className, styles.noticeButton); - const notificationBox = this.getNotificationBox(); - const NoticeBellIcon = bell || ; - const trigger = ( - - - {NoticeBellIcon} - - - ); - if (!notificationBox) { - return trigger; - } - const popoverProps = {}; - if ('popupVisible' in this.props) { - popoverProps.visible = popupVisible; - } - return ( - (this.popover = ReactDOM.findDOMNode(node))} // eslint-disable-line - > - {trigger} - - ); - } -} diff --git a/src/components/NoticeIcon/index.less b/src/components/NoticeIcon/index.less deleted file mode 100644 index 3ca7c5d1e7126893c6044603f06e5c76cabed104..0000000000000000000000000000000000000000 --- a/src/components/NoticeIcon/index.less +++ /dev/null @@ -1,26 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.popover { - width: 336px; -} - -.noticeButton { - cursor: pointer; - display: inline-block; - transition: all 0.3s; -} - -.icon { - padding: 4px; -} - -.tabs { - :global { - .ant-tabs-nav-scroll { - text-align: center; - } - .ant-tabs-bar { - margin-bottom: 0; - } - } -} diff --git a/src/components/NoticeIcon/index.zh-CN.md b/src/components/NoticeIcon/index.zh-CN.md deleted file mode 100644 index 23dab2203ed8c6fb3db427359c0ad3b15533a089..0000000000000000000000000000000000000000 --- a/src/components/NoticeIcon/index.zh-CN.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: NoticeIcon -subtitle: 通知菜单 -cols: 1 -order: 9 ---- - -用在导航工具栏上,作为整个产品统一的通知中心。 - -## API - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -count | 图标上的消息总数 | number | - -bell | translate this please -> Change the bell Icon | ReactNode | `` -loading | 弹出卡片加载状态 | boolean | `false` -onClear | 点击清空按钮的回调 | function(tabName) | - -onItemClick | 点击列表项的回调 | function(item, tabProps) | - -onLoadMore | 加载更多的回调 | function(tabProps, event) | - -onPopupVisibleChange | 弹出卡片显隐的回调 | function(visible) | - -onTabChange | 切换页签的回调 | function(tabTitle) | - -popupVisible | 控制弹层显隐 | boolean | - -locale | 默认文案 | Object | `{ emptyText: 'No notifications', clear: 'Clear', loadedAll: 'Loaded', loadMore: 'Loading more' }` -clearClose | 点击清空按钮后关闭通知菜单 | boolean | `false` - -### NoticeIcon.Tab - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -count | 当前 Tab 未读消息数量 | number | list.length -emptyText | 针对每个 Tab 定制空数据文案 | ReactNode | - -emptyImage | 针对每个 Tab 定制空数据图片 | string | - -list | 列表数据,格式参照下表 | Array | `[]` -loadedAll | 已加载完所有消息 | boolean | `true` -loading | 当前 Tab 的加载状态 | boolean | `false` -name | 消息分类的标识符 | string | - -scrollToLoad | 允许滚动自加载 | boolean | `true` -skeletonCount | 加载时占位骨架的数量 | number | `5` -skeletonProps | 加载时占位骨架的属性 | SkeletonProps | `{}` -showClear | 是否显示清空按钮 | boolean | `true` -title | 消息分类的页签标题 | string | - - -### Tab data - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -avatar | 头像图片链接 | string \| ReactNode | - -title | 标题 | ReactNode | - -description | 描述信息 | ReactNode | - -datetime | 时间戳 | ReactNode | - -extra | 额外信息,在列表项右上角 | ReactNode | - -clickClose | 点击列表项关闭通知菜单 | boolean | `false` diff --git a/src/components/NumberInfo/demo/basic.md b/src/components/NumberInfo/demo/basic.md deleted file mode 100644 index b399655ee40e07588b444110458e30b237a88a71..0000000000000000000000000000000000000000 --- a/src/components/NumberInfo/demo/basic.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -order: 0 -title: - zh-CN: 演示 - en-US: Demo ---- - -## zh-CN - -各种数据文案的展现方式。 - -## en-US - -Used for presenting various numerical data. - -````jsx -import NumberInfo from 'ant-design-pro/lib/NumberInfo'; -import numeral from 'numeral'; - -ReactDOM.render( - - Visits this week} - total={numeral(12321).format('0,0')} - status="up" - subTotal={17.1} - /> - -, mountNode); -```` diff --git a/src/components/NumberInfo/index.d.ts b/src/components/NumberInfo/index.d.ts deleted file mode 100644 index ca93ba5d3df702af793cc15f70c7416d2610d366..0000000000000000000000000000000000000000 --- a/src/components/NumberInfo/index.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import * as React from 'react'; -export interface INumberInfoProps { - title?: React.ReactNode | string; - subTitle?: React.ReactNode | string; - total?: React.ReactNode | string; - status?: 'up' | 'down'; - theme?: string; - gap?: number; - subTotal?: number; - style?: React.CSSProperties; -} - -export default class NumberInfo extends React.Component {} diff --git a/src/components/NumberInfo/index.en-US.md b/src/components/NumberInfo/index.en-US.md deleted file mode 100644 index b82afbe4f218b36603fa0c37dbb6431696d5f3ee..0000000000000000000000000000000000000000 --- a/src/components/NumberInfo/index.en-US.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: NumberInfo -cols: 1 -order: 10 ---- - -Often used in data cards for highlighting the business data. - -## API - -Property | Description | Type | Default -----|------|-----|------ -title | title | ReactNode\|string | - -subTitle | subtitle | ReactNode\|string | - -total | total amount | ReactNode\|string | - -subTotal | total amount of additional information | ReactNode\|string | - -status | increase state | 'up \| down' | - -theme | state style | string | 'light' -gap | set the spacing (pixels) between numbers and descriptions | number | 8 diff --git a/src/components/NumberInfo/index.js b/src/components/NumberInfo/index.js deleted file mode 100644 index 717aee9dd746185cd7c867cb9b443c1b378f03d2..0000000000000000000000000000000000000000 --- a/src/components/NumberInfo/index.js +++ /dev/null @@ -1,41 +0,0 @@ -import React from 'react'; -import { Icon } from 'antd'; -import classNames from 'classnames'; -import styles from './index.less'; - -const NumberInfo = ({ theme, title, subTitle, total, subTotal, status, suffix, gap, ...rest }) => ( - - {title && ( - - {title} - - )} - {subTitle && ( - - {subTitle} - - )} - - - {total} - {suffix && {suffix}} - - {(status || subTotal) && ( - - {subTotal} - {status && } - - )} - - -); - -export default NumberInfo; diff --git a/src/components/NumberInfo/index.less b/src/components/NumberInfo/index.less deleted file mode 100644 index c8fad650b3b6cdad9969d1a0604c505cae1f5a2e..0000000000000000000000000000000000000000 --- a/src/components/NumberInfo/index.less +++ /dev/null @@ -1,68 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.numberInfo { - .suffix { - color: @text-color; - font-size: 16px; - font-style: normal; - margin-left: 4px; - } - .numberInfoTitle { - color: @text-color; - font-size: @font-size-lg; - margin-bottom: 16px; - transition: all 0.3s; - } - .numberInfoSubTitle { - color: @text-color-secondary; - font-size: @font-size-base; - height: 22px; - line-height: 22px; - overflow: hidden; - text-overflow: ellipsis; - word-break: break-all; - white-space: nowrap; - } - .numberInfoValue { - margin-top: 4px; - font-size: 0; - overflow: hidden; - text-overflow: ellipsis; - word-break: break-all; - white-space: nowrap; - & > span { - color: @heading-color; - display: inline-block; - line-height: 32px; - height: 32px; - font-size: 24px; - margin-right: 32px; - } - .subTotal { - color: @text-color-secondary; - font-size: @font-size-lg; - vertical-align: top; - margin-right: 0; - i { - font-size: 12px; - transform: scale(0.82); - margin-left: 4px; - } - :global { - .anticon-caret-up { - color: @red-6; - } - .anticon-caret-down { - color: @green-6; - } - } - } - } -} -.numberInfolight { - .numberInfoValue { - & > span { - color: @text-color; - } - } -} diff --git a/src/components/NumberInfo/index.zh-CN.md b/src/components/NumberInfo/index.zh-CN.md deleted file mode 100644 index 719853948654a5c57939640cd35b9212adde365b..0000000000000000000000000000000000000000 --- a/src/components/NumberInfo/index.zh-CN.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: NumberInfo -subtitle: 数据文本 -cols: 1 -order: 10 ---- - -常用在数据卡片中,用于突出展示某个业务数据。 - -## API - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -title | 标题 | ReactNode\|string | - -subTitle | 子标题 | ReactNode\|string | - -total | 总量 | ReactNode\|string | - -subTotal | 子总量 | ReactNode\|string | - -status | 增加状态 | 'up \| down' | - -theme | 状态样式 | string | 'light' -gap | 设置数字和描述之间的间距(像素)| number | 8 diff --git a/src/components/PageHeader/breadcrumb.d.ts b/src/components/PageHeader/breadcrumb.d.ts deleted file mode 100644 index cfed402113aaffc2000b99712c13add232fd0b16..0000000000000000000000000000000000000000 --- a/src/components/PageHeader/breadcrumb.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import * as React from 'react'; -import { IPageHeaderProps } from './index'; - -export default class BreadcrumbView extends React.Component {} - -export function getBreadcrumb(breadcrumbNameMap: object, url: string): object; diff --git a/src/components/PageHeader/breadcrumb.js b/src/components/PageHeader/breadcrumb.js deleted file mode 100644 index 28c71b068c79201c980bc2c209c04407e62e1b28..0000000000000000000000000000000000000000 --- a/src/components/PageHeader/breadcrumb.js +++ /dev/null @@ -1,176 +0,0 @@ -import React, { PureComponent, createElement } from 'react'; -import pathToRegexp from 'path-to-regexp'; -import { Breadcrumb } from 'antd'; -import styles from './index.less'; -import { urlToList } from '../_utils/pathTools'; - -export const getBreadcrumb = (breadcrumbNameMap, url) => { - let breadcrumb = breadcrumbNameMap[url]; - if (!breadcrumb) { - Object.keys(breadcrumbNameMap).forEach(item => { - if (pathToRegexp(item).test(url)) { - breadcrumb = breadcrumbNameMap[item]; - } - }); - } - return breadcrumb || {}; -}; - -export default class BreadcrumbView extends PureComponent { - state = { - breadcrumb: null, - }; - - componentDidMount() { - this.getBreadcrumbDom(); - } - - componentDidUpdate(preProps) { - const { location } = this.props; - if (!location || !preProps.location) { - return; - } - const prePathname = preProps.location.pathname; - if (prePathname !== location.pathname) { - this.getBreadcrumbDom(); - } - } - - getBreadcrumbDom = () => { - const breadcrumb = this.conversionBreadcrumbList(); - this.setState({ - breadcrumb, - }); - }; - - getBreadcrumbProps = () => { - const { routes, params, location, breadcrumbNameMap } = this.props; - return { - routes, - params, - routerLocation: location, - breadcrumbNameMap, - }; - }; - - // Generated according to props - conversionFromProps = () => { - const { breadcrumbList, breadcrumbSeparator, itemRender, linkElement = 'a' } = this.props; - return ( - - {breadcrumbList.map(item => { - const title = itemRender ? itemRender(item) : item.title; - return ( - - {item.href - ? createElement( - linkElement, - { - [linkElement === 'a' ? 'href' : 'to']: item.href, - }, - title - ) - : title} - - ); - })} - - ); - }; - - conversionFromLocation = (routerLocation, breadcrumbNameMap) => { - const { breadcrumbSeparator, home, itemRender, linkElement = 'a' } = this.props; - // Convert the url to an array - const pathSnippets = urlToList(routerLocation.pathname); - // Loop data mosaic routing - const extraBreadcrumbItems = pathSnippets.map((url, index) => { - const currentBreadcrumb = getBreadcrumb(breadcrumbNameMap, url); - if (currentBreadcrumb.inherited) { - return null; - } - const isLinkable = index !== pathSnippets.length - 1 && currentBreadcrumb.component; - const name = itemRender ? itemRender(currentBreadcrumb) : currentBreadcrumb.name; - return currentBreadcrumb.name && !currentBreadcrumb.hideInBreadcrumb ? ( - - {createElement( - isLinkable ? linkElement : 'span', - { [linkElement === 'a' ? 'href' : 'to']: url }, - name - )} - - ) : null; - }); - // Add home breadcrumbs to your head - extraBreadcrumbItems.unshift( - - {createElement( - linkElement, - { - [linkElement === 'a' ? 'href' : 'to']: '/', - }, - home || 'Home' - )} - - ); - return ( - - {extraBreadcrumbItems} - - ); - }; - - /** - * 将参数转化为面包屑 - * Convert parameters into breadcrumbs - */ - conversionBreadcrumbList = () => { - const { breadcrumbList, breadcrumbSeparator } = this.props; - const { routes, params, routerLocation, breadcrumbNameMap } = this.getBreadcrumbProps(); - if (breadcrumbList && breadcrumbList.length) { - return this.conversionFromProps(); - } - // 如果传入 routes 和 params 属性 - // If pass routes and params attributes - if (routes && params) { - return ( - route.breadcrumbName)} - params={params} - itemRender={this.itemRender} - separator={breadcrumbSeparator} - /> - ); - } - // 根据 location 生成 面包屑 - // Generate breadcrumbs based on location - if (routerLocation && routerLocation.pathname) { - return this.conversionFromLocation(routerLocation, breadcrumbNameMap); - } - return null; - }; - - // 渲染Breadcrumb 子节点 - // Render the Breadcrumb child node - itemRender = (route, params, routes, paths) => { - const { linkElement = 'a' } = this.props; - const last = routes.indexOf(route) === routes.length - 1; - return last || !route.component ? ( - {route.breadcrumbName} - ) : ( - createElement( - linkElement, - { - href: paths.join('/') || '/', - to: paths.join('/') || '/', - }, - route.breadcrumbName - ) - ); - }; - - render() { - const { breadcrumb } = this.state; - return breadcrumb; - } -} diff --git a/src/components/PageHeader/demo/image.md b/src/components/PageHeader/demo/image.md deleted file mode 100644 index 511bac5d0bac833562aff5e23e182522f2c94288..0000000000000000000000000000000000000000 --- a/src/components/PageHeader/demo/image.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -order: 2 -title: With Image ---- - -带图片的页头。 - -````jsx -import PageHeader from 'ant-design-pro/lib/PageHeader'; - -const content = ( - - 段落示意:蚂蚁金服务设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。 - - - 快速开始 - - - 产品简介 - - - 产品文档 - - - -); - -const extra = ( - - - -); - -const breadcrumbList = [{ - title: '一级菜单', - href: '/', -}, { - title: '二级菜单', - href: '/', -}, { - title: '三级菜单', -}]; - -ReactDOM.render( - - - -, mountNode); -```` - - diff --git a/src/components/PageHeader/demo/simple.md b/src/components/PageHeader/demo/simple.md deleted file mode 100644 index d0ad1f7d2f4e07208900b9e57891952cb7d39942..0000000000000000000000000000000000000000 --- a/src/components/PageHeader/demo/simple.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -order: 3 -title: Simple ---- - -简单的页头。 - -````jsx -import PageHeader from 'ant-design-pro/lib/PageHeader'; - -const breadcrumbList = [{ - title: '一级菜单', - href: '/', -}, { - title: '二级菜单', - href: '/', -}, { - title: '三级菜单', -}]; - -ReactDOM.render( - - - -, mountNode); -```` - - diff --git a/src/components/PageHeader/demo/standard.md b/src/components/PageHeader/demo/standard.md deleted file mode 100644 index 5c59c933c282b913b4bb56d69ee915feb56fc29f..0000000000000000000000000000000000000000 --- a/src/components/PageHeader/demo/standard.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -order: 1 -title: Standard ---- - -标准页头。 - -````jsx -import PageHeader from 'ant-design-pro/lib/PageHeader'; -import DescriptionList from 'ant-design-pro/lib/DescriptionList'; -import { Button, Menu, Dropdown, Icon, Row, Col } from 'antd'; - -const { Description } = DescriptionList; -const ButtonGroup = Button.Group; - -const description = ( - - 曲丽丽 - XX 服务 - 2017-07-07 - 12421 - -); - -const menu = ( - - 选项一 - 选项二 - 选项三 - -); - -const action = ( - - - 操作 - 操作 - - - - - 主操作 - -); - -const extra = ( - - - 状态 - 待审批 - - - 订单金额 - ¥ 568.08 - - -); - -const breadcrumbList = [{ - title: '一级菜单', - href: '/', -}, { - title: '二级菜单', - href: '/', -}, { - title: '三级菜单', -}]; - -const tabList = [{ - key: 'detail', - tab: '详情', -}, { - key: 'rule', - tab: '规则', -}]; - -function onTabChange(key) { - console.log(key); -} - -ReactDOM.render( - - } - action={action} - content={description} - extraContent={extra} - breadcrumbList={breadcrumbList} - tabList={tabList} - tabActiveKey="detail" - onTabChange={onTabChange} - /> - -, mountNode); -```` - - diff --git a/src/components/PageHeader/demo/structure.md b/src/components/PageHeader/demo/structure.md deleted file mode 100644 index 429eed6319f6f483da6ac724242a07f0626e3f0c..0000000000000000000000000000000000000000 --- a/src/components/PageHeader/demo/structure.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -order: 0 -title: Structure ---- - -基本结构,具备响应式布局功能,主要断点为 768px 和 576px,拖动窗口改变大小试试看。 - -````jsx -import PageHeader from 'ant-design-pro/lib/PageHeader'; - -const breadcrumbList = [{ - title: '面包屑', -}]; - -const tabList = [{ - key: '1', - tab: '页签一', -}, { - key: '2', - tab: '页签二', -}, { - key: '3', - tab: '页签三', -}]; - -ReactDOM.render( - - Title} - logo={logo} - action={action} - content={content} - extraContent={extraContent} - breadcrumbList={breadcrumbList} - tabList={tabList} - tabActiveKey="1" - /> - -, mountNode); -```` - - diff --git a/src/components/PageHeader/index.d.ts b/src/components/PageHeader/index.d.ts deleted file mode 100644 index eacbb2de903681f1eee250d83c71e4642ca41d0d..0000000000000000000000000000000000000000 --- a/src/components/PageHeader/index.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as React from 'react'; -export interface IPageHeaderProps { - title?: React.ReactNode | string; - logo?: React.ReactNode | string; - action?: React.ReactNode | string; - content?: React.ReactNode; - extraContent?: React.ReactNode; - routes?: any[]; - params?: any; - breadcrumbList?: Array<{ title: React.ReactNode; href?: string }>; - tabList?: Array<{ key: string; tab: React.ReactNode }>; - tabActiveKey?: string; - tabDefaultActiveKey?: string; - onTabChange?: (key: string) => void; - tabBarExtraContent?: React.ReactNode; - linkElement?: React.ReactNode; - style?: React.CSSProperties; - home?: React.ReactNode; - wide?: boolean; - hiddenBreadcrumb?: boolean; -} - -export default class PageHeader extends React.Component {} diff --git a/src/components/PageHeader/index.js b/src/components/PageHeader/index.js deleted file mode 100644 index 5d47b34568f3e1ea1ae8d35e5a2897b2e985eeff..0000000000000000000000000000000000000000 --- a/src/components/PageHeader/index.js +++ /dev/null @@ -1,82 +0,0 @@ -import React, { PureComponent } from 'react'; -import { Tabs, Skeleton } from 'antd'; -import classNames from 'classnames'; -import styles from './index.less'; -import BreadcrumbView from './breadcrumb'; - -const { TabPane } = Tabs; -export default class PageHeader extends PureComponent { - onChange = key => { - const { onTabChange } = this.props; - if (onTabChange) { - onTabChange(key); - } - }; - - render() { - const { - title, - logo, - action, - content, - extraContent, - tabList, - className, - tabActiveKey, - tabDefaultActiveKey, - tabBarExtraContent, - loading = false, - wide = false, - hiddenBreadcrumb = false, - } = this.props; - - const clsString = classNames(styles.pageHeader, className); - const activeKeyProps = {}; - if (tabDefaultActiveKey !== undefined) { - activeKeyProps.defaultActiveKey = tabDefaultActiveKey; - } - if (tabActiveKey !== undefined) { - activeKeyProps.activeKey = tabActiveKey; - } - return ( - - - - {hiddenBreadcrumb ? null : } - - {logo && {logo}} - - - {title && {title}} - {action && {action}} - - - {content && {content}} - {extraContent && {extraContent}} - - - - {tabList && tabList.length ? ( - - {tabList.map(item => ( - - ))} - - ) : null} - - - - ); - } -} diff --git a/src/components/PageHeader/index.less b/src/components/PageHeader/index.less deleted file mode 100644 index da947d09d5ead3fbfa8a532fcf24d33755f16724..0000000000000000000000000000000000000000 --- a/src/components/PageHeader/index.less +++ /dev/null @@ -1,161 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.pageHeader { - background: @component-background; - padding: 16px 32px 0 32px; - border-bottom: @border-width-base @border-style-base @border-color-split; - .wide { - max-width: 1200px; - margin: auto; - } - .detail { - display: flex; - } - - .row { - display: flex; - width: 100%; - } - - .breadcrumb { - margin-bottom: 16px; - } - - .tabs { - margin: 0 0 0 -8px; - - :global { - // 1px 可以让选中效果显示完成 - .ant-tabs-bar { - border-bottom: none; - margin-bottom: 1px; - } - } - } - - .logo { - flex: 0 1 auto; - margin-right: 16px; - padding-top: 1px; - > img { - width: 28px; - height: 28px; - border-radius: @border-radius-base; - display: block; - } - } - - .title { - font-size: 20px; - font-weight: 500; - color: @heading-color; - } - - .action { - margin-left: 56px; - min-width: 266px; - - :global { - .ant-btn-group:not(:last-child), - .ant-btn:not(:last-child) { - margin-right: 8px; - } - - .ant-btn-group > .ant-btn { - margin-right: 0; - } - } - } - - .title, - .content { - flex: auto; - } - - .action, - .extraContent, - .main { - flex: 0 1 auto; - } - - .main { - width: 100%; - } - - .title, - .action { - margin-bottom: 16px; - } - - .logo, - .content, - .extraContent { - margin-bottom: 16px; - } - - .action, - .extraContent { - text-align: right; - } - - .extraContent { - margin-left: 88px; - min-width: 242px; - } -} - -@media screen and (max-width: @screen-xl) { - .pageHeader { - .extraContent { - margin-left: 44px; - } - } -} - -@media screen and (max-width: @screen-lg) { - .pageHeader { - .extraContent { - margin-left: 20px; - } - } -} - -@media screen and (max-width: @screen-md) { - .pageHeader { - .row { - display: block; - } - - .action, - .extraContent { - margin-left: 0; - text-align: left; - } - } -} - -@media screen and (max-width: @screen-sm) { - .pageHeader { - .detail { - display: block; - } - } -} - -@media screen and (max-width: @screen-xs) { - .pageHeader { - .action { - :global { - .ant-btn-group, - .ant-btn { - display: block; - margin-bottom: 8px; - } - .ant-btn-group > .ant-btn { - display: inline-block; - margin-bottom: 0; - } - } - } - } -} diff --git a/src/components/PageHeader/index.md b/src/components/PageHeader/index.md deleted file mode 100644 index e82c8b89a81e6bfdadb3edf49c405a83daff5eda..0000000000000000000000000000000000000000 --- a/src/components/PageHeader/index.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: - en-US: PageHeader - zh-CN: PageHeader -subtitle: 页头 -cols: 1 -order: 11 ---- - -页头用来声明页面的主题,包含了用户所关注的最重要的信息,使用户可以快速理解当前页面是什么以及它的功能。 - -## API - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| title | title 区域 | ReactNode | - | -| logo | logo区域 | ReactNode | - | -| action | 操作区,位于 title 行的行尾 | ReactNode | - | -| home | 默认的主页说明文字 | ReactNode | - | -| content | 内容区 | ReactNode | - | -| extraContent | 额外内容区,位于content的右侧 | ReactNode | - | -| breadcrumbList | 面包屑数据,配置了此属性时 `routes` `params` `location` `breadcrumbNameMap` 无效 | array<{title: ReactNode, href?: string}> | - | -| hiddenBreadcrumb |隐藏面包屑 | boolean | false | -| routes | 面包屑相关属性,router 的路由栈信息 | object[] | - | -| params | 面包屑相关属性,路由的参数 | object | - | -| location | 面包屑相关属性,当前的路由信息 | object | - | -| breadcrumbNameMap | 面包屑相关属性,路由的地址-名称映射表 | object | - | -| tabList | tab 标题列表 | array<{key: string, tab: ReactNode}> | - | -| tabActiveKey | 当前高亮的 tab 项 | string | - | -| tabDefaultActiveKey | 默认高亮的 tab 项 | string | 第一项 | -| wide | 是否定宽 | boolean | false | -| onTabChange | 切换面板的回调 | (key) => void | - | -| itemRender | 自定义节点方法 | (menuItem) => ReactNode | - | -| linkElement | 定义链接的元素,默认为 `a`,可传入 react-router 的 Link | string\|ReactElement | - | - -> 面包屑的配置方式有三种,一是直接配置 `breadcrumbList`,二是结合 `react-router@2` `react-router@3`,配置 `routes` 及 `params` 实现,类似 [面包屑 Demo](https://ant.design/components/breadcrumb-cn/#components-breadcrumb-demo-router),三是结合 `react-router@4`,配置 `location` `breadcrumbNameMap`,优先级依次递减,脚手架中使用最后一种。 对于后两种用法,你也可以将 `routes` `params` 及 `location` `breadcrumbNameMap` 放到 context 中,组件会自动获取。 diff --git a/src/components/PageHeader/index.test.js b/src/components/PageHeader/index.test.js deleted file mode 100644 index d22706e9c231db2c8c7e3e2981b5d26f04c86750..0000000000000000000000000000000000000000 --- a/src/components/PageHeader/index.test.js +++ /dev/null @@ -1,43 +0,0 @@ -import { getBreadcrumb } from './breadcrumb'; -import { urlToList } from '../_utils/pathTools'; - -const routerData = { - '/dashboard/analysis': { - name: '分析页', - }, - '/userinfo': { - name: '用户列表', - }, - '/userinfo/:id': { - name: '用户信息', - }, - '/userinfo/:id/addr': { - name: '收货订单', - }, -}; -describe('test getBreadcrumb', () => { - it('Simple url', () => { - expect(getBreadcrumb(routerData, '/dashboard/analysis').name).toEqual('分析页'); - }); - it('Parameters url', () => { - expect(getBreadcrumb(routerData, '/userinfo/2144').name).toEqual('用户信息'); - }); - it('The middle parameter url', () => { - expect(getBreadcrumb(routerData, '/userinfo/2144/addr').name).toEqual('收货订单'); - }); - it('Loop through the parameters', () => { - const urlNameList = urlToList('/userinfo/2144/addr').map( - url => getBreadcrumb(routerData, url).name - ); - expect(urlNameList).toEqual(['用户列表', '用户信息', '收货订单']); - }); - - it('a path', () => { - const urlNameList = urlToList('/userinfo').map(url => getBreadcrumb(routerData, url).name); - expect(urlNameList).toEqual(['用户列表']); - }); - it('Secondary path', () => { - const urlNameList = urlToList('/userinfo/2144').map(url => getBreadcrumb(routerData, url).name); - expect(urlNameList).toEqual(['用户列表', '用户信息']); - }); -}); diff --git a/src/components/PageHeaderWrapper/GridContent.js b/src/components/PageHeaderWrapper/GridContent.js deleted file mode 100644 index 931ea20c91b21724f8680a7cf12f3aaefb2fda75..0000000000000000000000000000000000000000 --- a/src/components/PageHeaderWrapper/GridContent.js +++ /dev/null @@ -1,18 +0,0 @@ -import React, { PureComponent } from 'react'; -import { connect } from 'dva'; -import styles from './GridContent.less'; - -class GridContent extends PureComponent { - render() { - const { contentWidth, children } = this.props; - let className = `${styles.main}`; - if (contentWidth === 'Fixed') { - className = `${styles.main} ${styles.wide}`; - } - return {children}; - } -} - -export default connect(({ setting }) => ({ - contentWidth: setting.contentWidth, -}))(GridContent); diff --git a/src/components/PageHeaderWrapper/GridContent.less b/src/components/PageHeaderWrapper/GridContent.less deleted file mode 100644 index d5496e9ecb95318c38a30f1369d35e8fcf583758..0000000000000000000000000000000000000000 --- a/src/components/PageHeaderWrapper/GridContent.less +++ /dev/null @@ -1,10 +0,0 @@ -.main { - width: 100%; - height: 100%; - min-height: 100%; - transition: 0.3s; - &.wide { - max-width: 1200px; - margin: 0 auto; - } -} diff --git a/src/components/PageHeaderWrapper/index.js b/src/components/PageHeaderWrapper/index.js deleted file mode 100644 index cd745f66e8db1182493560238cc60762235dad09..0000000000000000000000000000000000000000 --- a/src/components/PageHeaderWrapper/index.js +++ /dev/null @@ -1,41 +0,0 @@ -import React from 'react'; -import { FormattedMessage } from 'umi/locale'; -import Link from 'umi/link'; -import PageHeader from '@/components/PageHeader'; -import { connect } from 'dva'; -import GridContent from './GridContent'; -import styles from './index.less'; -import MenuContext from '@/layouts/MenuContext'; - -const PageHeaderWrapper = ({ children, contentWidth, wrapperClassName, top, ...restProps }) => ( - - {top} - - {value => ( - } - {...value} - key="pageheader" - {...restProps} - linkElement={Link} - itemRender={item => { - if (item.locale) { - return ; - } - return item.title; - }} - /> - )} - - {children ? ( - - {children} - - ) : null} - -); - -export default connect(({ setting }) => ({ - contentWidth: setting.contentWidth, -}))(PageHeaderWrapper); diff --git a/src/components/Result/demo/classic.md b/src/components/Result/demo/classic.md deleted file mode 100644 index 0cd9d14b32a1ac3327611aee7cf74bf7a636b2bf..0000000000000000000000000000000000000000 --- a/src/components/Result/demo/classic.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -order: 1 -title: Classic ---- - -典型结果页面。 - -````jsx -import Result from 'ant-design-pro/lib/Result'; -import { Button, Row, Col, Icon, Steps } from 'antd'; - -const { Step } = Steps; - -const desc1 = ( - - - 曲丽丽 - - - 2016-12-12 12:32 - -); - -const desc2 = ( - - - 周毛毛 - - - 催一下 - -); - -const extra = ( - - - 项目名称 - - - - 项目 ID: - 23421 - - - 负责人: - 曲丽丽 - - - 生效时间: - 2016-12-12 ~ 2017-12-12 - - - - - - - - - -); - -const actions = ( - - 返回列表 - 查看项目 - 打 印 - -); - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Result/demo/error.md b/src/components/Result/demo/error.md deleted file mode 100644 index 5fd25cfdd948e1e1b458d682bdb35384eab90784..0000000000000000000000000000000000000000 --- a/src/components/Result/demo/error.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -order: 2 -title: Failed ---- - -提交失败。 - -````jsx -import Result from 'ant-design-pro/lib/Result'; -import { Button, Icon } from 'antd'; - -const extra = ( - - - 您提交的内容有如下错误: - - - 您的账户已被冻结 - 立即解冻 - - - 您的账户还不具备申请资格 - 立即升级 - - -); - -const actions = 返回修改; - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Result/demo/structure.md b/src/components/Result/demo/structure.md deleted file mode 100644 index 7fcecfd6d0c0f539c32454b14d7a39f63c006606..0000000000000000000000000000000000000000 --- a/src/components/Result/demo/structure.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -order: 0 -title: Structure ---- - -结构包含 `处理结果`,`补充信息` 以及 `操作建议` 三个部分,其中 `处理结果` 由 `提示图标`,`标题` 和 `结果描述` 组成。 - -````jsx -import Result from 'ant-design-pro/lib/Result'; - -ReactDOM.render( - 标题} - description={结果描述} - extra="其他补充信息,自带灰底效果" - actions={操作建议,一般放置按钮组} - /> -, mountNode); -```` diff --git a/src/components/Result/index.d.ts b/src/components/Result/index.d.ts deleted file mode 100644 index 0c34c254014f49c0d7322acc1dab47cbd2fd52b4..0000000000000000000000000000000000000000 --- a/src/components/Result/index.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as React from 'react'; -export interface IResultProps { - type: 'success' | 'error'; - title: React.ReactNode; - description?: React.ReactNode; - extra?: React.ReactNode; - actions?: React.ReactNode; - style?: React.CSSProperties; -} - -export default class Result extends React.Component {} diff --git a/src/components/Result/index.js b/src/components/Result/index.js deleted file mode 100644 index 89f9f31abec8ca437d3bf741411d3987a0f63714..0000000000000000000000000000000000000000 --- a/src/components/Result/index.js +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; -import classNames from 'classnames'; -import { Icon } from 'antd'; -import styles from './index.less'; - -export default function Result({ - className, - type, - title, - description, - extra, - actions, - ...restProps -}) { - const iconMap = { - error: , - success: , - }; - const clsString = classNames(styles.result, className); - return ( - - {iconMap[type]} - {title} - {description && {description}} - {extra && {extra}} - {actions && {actions}} - - ); -} diff --git a/src/components/Result/index.less b/src/components/Result/index.less deleted file mode 100644 index 5cd2aff589606f5684fd1c8aeff6540ee81b8b6c..0000000000000000000000000000000000000000 --- a/src/components/Result/index.less +++ /dev/null @@ -1,58 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.result { - text-align: center; - width: 72%; - margin: 0 auto; - @media screen and (max-width: @screen-xs) { - width: 100%; - } - - .icon { - font-size: 72px; - line-height: 72px; - margin-bottom: 24px; - - & > .success { - color: @success-color; - } - - & > .error { - color: @error-color; - } - } - - .title { - font-size: 24px; - color: @heading-color; - font-weight: 500; - line-height: 32px; - margin-bottom: 16px; - } - - .description { - font-size: 14px; - line-height: 22px; - color: @text-color-secondary; - margin-bottom: 24px; - } - - .extra { - background: #fafafa; - padding: 24px 40px; - border-radius: @border-radius-sm; - text-align: left; - - @media screen and (max-width: @screen-xs) { - padding: 18px 20px; - } - } - - .actions { - margin-top: 32px; - - button:not(:last-child) { - margin-right: 8px; - } - } -} diff --git a/src/components/Result/index.md b/src/components/Result/index.md deleted file mode 100644 index dc11206cc4dc88bea7f2c9b182849361ba18c0f4..0000000000000000000000000000000000000000 --- a/src/components/Result/index.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: - en-US: Result - zh-CN: Result -subtitle: 处理结果 -cols: 1 -order: 12 ---- - -结果页用于对用户进行的一系列任务处理结果进行反馈。 - -## API - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| type | 类型,不同类型自带对应的图标 | Enum {'success', 'error'} | - | -| title | 标题 | ReactNode | - | -| description | 结果描述 | ReactNode | - | -| extra | 补充信息,有默认的灰色背景 | ReactNode | - | -| actions | 操作建议,推荐放置跳转链接,按钮组等 | ReactNode | - | diff --git a/src/components/SelectLang/index.js b/src/components/SelectLang/index.js deleted file mode 100644 index f6abe2f279ef9c8c34463406f0c2a94503e6650d..0000000000000000000000000000000000000000 --- 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.less b/src/components/SelectLang/index.less deleted file mode 100644 index 971ef2aa98be7393a749381e64976df111ffd306..0000000000000000000000000000000000000000 --- a/src/components/SelectLang/index.less +++ /dev/null @@ -1,24 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.menu { - :global(.anticon) { - margin-right: 8px; - } - :global(.ant-dropdown-menu-item) { - min-width: 160px; - } -} - -.dropDown { - cursor: pointer; - vertical-align: top; - line-height: @layout-header-height; - > i { - font-size: 14px !important; - transform: none !important; - svg { - position: relative; - top: -1px; - } - } -} diff --git a/src/components/SettingDrawer/BlockCheckbox.js b/src/components/SettingDrawer/BlockCheckbox.js deleted file mode 100644 index 49af42c730224cc76b9cac47f87c91cca0ef6da9..0000000000000000000000000000000000000000 --- a/src/components/SettingDrawer/BlockCheckbox.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; -import { Tooltip, Icon } from 'antd'; -import style from './index.less'; - -const BlockChecbox = ({ value, onChange, list }) => ( - - {list.map(item => ( - - onChange(item.key)}> - - - - - - - ))} - -); - -export default BlockChecbox; diff --git a/src/components/SettingDrawer/ThemeColor.js b/src/components/SettingDrawer/ThemeColor.js deleted file mode 100644 index e5d66d4be5cb29a2684eff46734e06fba17d6923..0000000000000000000000000000000000000000 --- a/src/components/SettingDrawer/ThemeColor.js +++ /dev/null @@ -1,74 +0,0 @@ -import React from 'react'; -import { Tooltip, Icon } from 'antd'; -import { formatMessage } from 'umi/locale'; -import styles from './ThemeColor.less'; - -const Tag = ({ color, check, ...rest }) => ( - - {check ? : ''} - -); - -const ThemeColor = ({ colors, title, value, onChange }) => { - let colorList = colors; - if (!colors) { - colorList = [ - { - key: 'dust', - color: '#F5222D', - }, - { - key: 'volcano', - color: '#FA541C', - }, - { - key: 'sunset', - color: '#FAAD14', - }, - { - key: 'cyan', - color: '#13C2C2', - }, - { - key: 'green', - color: '#52C41A', - }, - { - key: 'daybreak', - color: '#1890FF', - }, - { - key: 'geekblue', - color: '#2F54EB', - }, - { - key: 'purple', - color: '#722ED1', - }, - ]; - } - return ( - - {title} - - {colorList.map(({ key, color }) => ( - - onChange && onChange(color)} - /> - - ))} - - - ); -}; - -export default ThemeColor; diff --git a/src/components/SettingDrawer/ThemeColor.less b/src/components/SettingDrawer/ThemeColor.less deleted file mode 100644 index 4983eb9c67d207cfa4f9470a5a82068eb9c20c71..0000000000000000000000000000000000000000 --- a/src/components/SettingDrawer/ThemeColor.less +++ /dev/null @@ -1,21 +0,0 @@ -.themeColor { - overflow: hidden; - margin-top: 24px; - .title { - font-size: 14px; - color: rgba(0, 0, 0, 0.65); - line-height: 22px; - margin-bottom: 12px; - } - .colorBlock { - width: 20px; - height: 20px; - border-radius: 2px; - float: left; - cursor: pointer; - margin-right: 8px; - text-align: center; - color: #fff; - font-weight: bold; - } -} diff --git a/src/components/SettingDrawer/index.js b/src/components/SettingDrawer/index.js deleted file mode 100644 index 4b279f593ec8cf032d00bb6783b01b001a4b016d..0000000000000000000000000000000000000000 --- a/src/components/SettingDrawer/index.js +++ /dev/null @@ -1,254 +0,0 @@ -import React, { PureComponent } from 'react'; -import { Select, message, Drawer, List, Switch, Divider, Icon, Button, Alert, Tooltip } from 'antd'; -import { formatMessage } from 'umi/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'; - -const { Option } = Select; - -const Body = ({ children, title, style }) => ( - - {title} - {children} - -); - -@connect(({ setting }) => ({ setting })) -class SettingDrawer extends PureComponent { - state = { - collapse: false, - }; - - getLayoutSetting = () => { - const { - setting: { contentWidth, fixedHeader, layout, autoHideHeader, fixSiderbar }, - } = this.props; - return [ - { - title: formatMessage({ id: 'app.setting.content-width' }), - action: ( - this.changeSetting('contentWidth', value)} - style={{ width: 80 }} - > - {layout === 'sidemenu' ? null : ( - - {formatMessage({ id: 'app.setting.content-width.fixed' })} - - )} - - {formatMessage({ id: 'app.setting.content-width.fluid' })} - - - ), - }, - { - title: formatMessage({ id: 'app.setting.fixedheader' }), - action: ( - this.changeSetting('fixedHeader', checked)} - /> - ), - }, - { - title: formatMessage({ id: 'app.setting.hideheader' }), - disabled: !fixedHeader, - disabledReason: formatMessage({ id: 'app.setting.hideheader.hint' }), - action: ( - this.changeSetting('autoHideHeader', checked)} - /> - ), - }, - { - title: formatMessage({ id: 'app.setting.fixedsidebar' }), - disabled: layout === 'topmenu', - disabledReason: formatMessage({ id: 'app.setting.fixedsidebar.hint' }), - action: ( - this.changeSetting('fixSiderbar', checked)} - /> - ), - }, - ]; - }; - - changeSetting = (key, value) => { - const { setting } = this.props; - const nextState = { ...setting }; - nextState[key] = value; - if (key === 'layout') { - nextState.contentWidth = value === 'topmenu' ? 'Fixed' : 'Fluid'; - } else if (key === 'fixedHeader' && !value) { - nextState.autoHideHeader = false; - } - this.setState(nextState, () => { - const { dispatch } = this.props; - dispatch({ - type: 'setting/changeSetting', - payload: this.state, - }); - }); - }; - - togglerContent = () => { - const { collapse } = this.state; - this.setState({ collapse: !collapse }); - }; - - renderLayoutSettingItem = item => { - const action = React.cloneElement(item.action, { - disabled: item.disabled, - }); - return ( - - - {item.title} - - - ); - }; - - render() { - const { setting } = this.props; - const { navTheme, primaryColor, layout, colorWeak } = setting; - const { collapse } = this.state; - return ( - - - - } - onHandleClick={this.togglerContent} - style={{ - zIndex: 999, - }} - > - - - this.changeSetting('navTheme', value)} - /> - - - this.changeSetting('primaryColor', color)} - /> - - - - - this.changeSetting('layout', value)} - /> - - - - - - - - this.changeSetting('colorWeak', checked)} - />, - ]} - > - {formatMessage({ id: 'app.setting.weakmode' })} - - - - message.success(formatMessage({ id: 'app.setting.copyinfo' }))} - > - - {formatMessage({ id: 'app.setting.copy' })} - - - - {formatMessage({ id: 'app.setting.production.hint' })}{' '} - - src/defaultSettings.js - - - } - /> - - - ); - } -} - -export default SettingDrawer; diff --git a/src/components/SettingDrawer/index.less b/src/components/SettingDrawer/index.less deleted file mode 100644 index af4109be3a3293a4cbdee09eda6a7355d20d62a2..0000000000000000000000000000000000000000 --- a/src/components/SettingDrawer/index.less +++ /dev/null @@ -1,74 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.content { - min-height: 100%; - background: #fff; - position: relative; -} - -.blockChecbox { - display: flex; - .item { - margin-right: 16px; - position: relative; - // box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); - border-radius: @border-radius-base; - cursor: pointer; - img { - width: 48px; - } - } - .selectIcon { - position: absolute; - top: 0; - right: 0; - width: 100%; - padding-top: 15px; - padding-left: 24px; - height: 100%; - color: @primary-color; - font-size: 14px; - font-weight: bold; - } -} - -.color_block { - width: 38px; - height: 22px; - margin: 4px; - border-radius: 4px; - cursor: pointer; - margin-right: 12px; - display: inline-block; - vertical-align: middle; -} - -.title { - font-size: 14px; - color: @heading-color; - line-height: 22px; - margin-bottom: 12px; -} - -.handle { - position: absolute; - top: 240px; - background: @primary-color; - width: 48px; - height: 48px; - right: 300px; - display: flex; - justify-content: center; - align-items: center; - cursor: pointer; - pointer-events: auto; - z-index: 0; - text-align: center; - font-size: 16px; - border-radius: 4px 0 0 4px; -} - -.productionHint { - font-size: 12px; - margin-top: 16px; -} diff --git a/src/components/SiderMenu/BaseMenu.js b/src/components/SiderMenu/BaseMenu.js deleted file mode 100644 index 2ad6113465994fe177114a41c3efd8dab45734ad..0000000000000000000000000000000000000000 --- a/src/components/SiderMenu/BaseMenu.js +++ /dev/null @@ -1,161 +0,0 @@ -import React, { PureComponent } from 'react'; -import classNames from 'classnames'; -import { Menu, Icon } from 'antd'; -import Link from 'umi/link'; -import { urlToList } from '../_utils/pathTools'; -import { getMenuMatches } from './SiderMenuUtils'; -import { isUrl } from '@/utils/utils'; -import styles from './index.less'; - -const { SubMenu } = Menu; - -// Allow menu.js config icon as string or ReactNode -// icon: 'setting', -// icon: 'http://demo.com/icon.png', -// icon: , -const getIcon = icon => { - if (typeof icon === 'string' && isUrl(icon)) { - return ; - } - if (typeof icon === 'string') { - return ; - } - return icon; -}; - -export default class BaseMenu extends PureComponent { - /** - * 获得菜单子节点 - * @memberof SiderMenu - */ - getNavMenuItems = (menusData, parent) => { - if (!menusData) { - return []; - } - return menusData - .filter(item => item.name && !item.hideInMenu) - .map(item => this.getSubMenuOrItem(item, parent)) - .filter(item => item); - }; - - // Get the currently selected menu - getSelectedMenuKeys = pathname => { - const { flatMenuKeys } = this.props; - return urlToList(pathname).map(itemPath => getMenuMatches(flatMenuKeys, itemPath).pop()); - }; - - /** - * get SubMenu or Item - */ - getSubMenuOrItem = item => { - // doc: add hideChildrenInMenu - if (item.children && !item.hideChildrenInMenu && item.children.some(child => child.name)) { - const { name } = item; - return ( - - {getIcon(item.icon)} - {name} - - ) : ( - name - ) - } - key={item.path} - > - {this.getNavMenuItems(item.children)} - - ); - } - return {this.getMenuItemPath(item)}; - }; - - /** - * 判断是否是http链接.返回 Link 或 a - * Judge whether it is http link.return a or Link - * @memberof SiderMenu - */ - getMenuItemPath = item => { - const { name } = item; - const itemPath = this.conversionPath(item.path); - const icon = getIcon(item.icon); - const { target } = item; - // Is it a http link - if (/^https?:\/\//.test(itemPath)) { - return ( - - {icon} - {name} - - ); - } - const { location, isMobile, onCollapse } = this.props; - return ( - { - onCollapse(true); - } - : undefined - } - > - {icon} - {name} - - ); - }; - - conversionPath = path => { - if (path && path.indexOf('http') === 0) { - return path; - } - return `/${path || ''}`.replace(/\/+/g, '/'); - }; - - render() { - const { - openKeys, - theme, - mode, - location: { pathname }, - className, - collapsed, - } = this.props; - // if pathname can't match, use the nearest parent's key - let selectedKeys = this.getSelectedMenuKeys(pathname); - if (!selectedKeys.length && openKeys) { - selectedKeys = [openKeys[openKeys.length - 1]]; - } - let props = {}; - if (openKeys && !collapsed) { - props = { - openKeys: openKeys.length === 0 ? [...selectedKeys] : openKeys, - }; - } - const { handleOpenChange, style, menuData } = this.props; - const cls = classNames(className, { - 'top-nav-menu': mode === 'horizontal', - }); - - return ( - - {this.getNavMenuItems(menuData)} - - ); - } -} diff --git a/src/components/SiderMenu/SiderMenu.js b/src/components/SiderMenu/SiderMenu.js deleted file mode 100644 index e1b49d0037e20972f044e2691e00869fd01a0ed1..0000000000000000000000000000000000000000 --- a/src/components/SiderMenu/SiderMenu.js +++ /dev/null @@ -1,87 +0,0 @@ -import React, { PureComponent, Suspense } from 'react'; -import { Layout } from 'antd'; -import classNames from 'classnames'; -import Link from 'umi/link'; -import styles from './index.less'; -import PageLoading from '../PageLoading'; -import { getDefaultCollapsedSubMenus } from './SiderMenuUtils'; - -const BaseMenu = React.lazy(() => import('./BaseMenu')); -const { Sider } = Layout; - -export default class SiderMenu extends PureComponent { - constructor(props) { - super(props); - this.state = { - openKeys: getDefaultCollapsedSubMenus(props), - }; - } - - static getDerivedStateFromProps(props, state) { - const { pathname } = state; - if (props.location.pathname !== pathname) { - return { - pathname: props.location.pathname, - openKeys: getDefaultCollapsedSubMenus(props), - }; - } - return null; - } - - isMainMenu = key => { - const { menuData } = this.props; - return menuData.some(item => { - if (key) { - return item.key === key || item.path === key; - } - return false; - }); - }; - - handleOpenChange = openKeys => { - const moreThanOne = openKeys.filter(openKey => this.isMainMenu(openKey)).length > 1; - this.setState({ - openKeys: moreThanOne ? [openKeys.pop()] : [...openKeys], - }); - }; - - render() { - const { logo, collapsed, onCollapse, fixSiderbar, theme } = this.props; - const { openKeys } = this.state; - const defaultProps = collapsed ? {} : { openKeys }; - - const siderClassName = classNames(styles.sider, { - [styles.fixSiderbar]: fixSiderbar, - [styles.light]: theme === 'light', - }); - return ( - - - - - Ant Design Pro - - - }> - - - - ); - } -} diff --git a/src/components/SiderMenu/SiderMenu.test.js b/src/components/SiderMenu/SiderMenu.test.js deleted file mode 100644 index 3d280da08a8510cf056d46d9e239fbbdacc44001..0000000000000000000000000000000000000000 --- 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/SiderMenuUtils.js b/src/components/SiderMenu/SiderMenuUtils.js deleted file mode 100644 index 6722ed7a8544c6e19e46f157cf7a14aca27feb3b..0000000000000000000000000000000000000000 --- a/src/components/SiderMenu/SiderMenuUtils.js +++ /dev/null @@ -1,39 +0,0 @@ -import pathToRegexp from 'path-to-regexp'; -import { urlToList } from '../_utils/pathTools'; - -/** - * Recursively flatten the data - * [{path:string},{path:string}] => {path,path2} - * @param menus - */ -export const getFlatMenuKeys = menuData => { - let keys = []; - menuData.forEach(item => { - keys.push(item.path); - if (item.children) { - keys = keys.concat(getFlatMenuKeys(item.children)); - } - }); - return keys; -}; - -export const getMenuMatches = (flatMenuKeys, path) => - flatMenuKeys.filter(item => { - if (item) { - return pathToRegexp(item).test(path); - } - return false; - }); -/** - * 获得菜单子节点 - * @memberof SiderMenu - */ -export const getDefaultCollapsedSubMenus = props => { - const { - location: { pathname }, - flatMenuKeys, - } = props; - return urlToList(pathname) - .map(item => getMenuMatches(flatMenuKeys, item)[0]) - .filter(item => item); -}; diff --git a/src/components/SiderMenu/index.js b/src/components/SiderMenu/index.js deleted file mode 100644 index 0be273314d593c01b54cd127b39c97d55833a990..0000000000000000000000000000000000000000 --- a/src/components/SiderMenu/index.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; -import { Drawer } from 'antd'; -import SiderMenu from './SiderMenu'; -import { getFlatMenuKeys } from './SiderMenuUtils'; - -const SiderMenuWrapper = React.memo(props => { - const { isMobile, menuData, collapsed, onCollapse } = props; - const flatMenuKeys = getFlatMenuKeys(menuData); - return isMobile ? ( - onCollapse(true)} - style={{ - padding: 0, - height: '100vh', - }} - > - - - ) : ( - - ); -}); - -export default SiderMenuWrapper; diff --git a/src/components/SiderMenu/index.less b/src/components/SiderMenu/index.less deleted file mode 100644 index 9ae37db198bbb263e206bddbaf5f9e189b07fd9f..0000000000000000000000000000000000000000 --- a/src/components/SiderMenu/index.less +++ /dev/null @@ -1,96 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -@nav-header-height: @layout-header-height; - -.logo { - height: @nav-header-height; - position: relative; - line-height: @nav-header-height; - padding-left: (@menu-collapsed-width - 32px) / 2; - transition: all 0.3s; - background: #002140; - overflow: hidden; - img { - display: inline-block; - vertical-align: middle; - height: 32px; - } - h1 { - color: white; - display: inline-block; - vertical-align: middle; - font-size: 20px; - margin: 0 0 0 12px; - font-family: Avenir, 'Helvetica Neue', Arial, Helvetica, sans-serif; - font-weight: 600; - } -} - -.sider { - min-height: 100vh; - box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35); - position: relative; - z-index: 10; - &.fixSiderbar { - position: fixed; - top: 0; - left: 0; - :global(.ant-menu-root) { - overflow-y: auto; - height: ~'calc(100vh - @{nav-header-height})'; - } - } - &.light { - box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05); - background-color: white; - .logo { - background: white; - box-shadow: 1px 1px 0 0 @border-color-split; - h1 { - color: @primary-color; - } - } - :global(.ant-menu-light) { - border-right-color: transparent; - } - } -} - -.icon { - width: 14px; - margin-right: 10px; -} - -:global { - .top-nav-menu li.ant-menu-item { - height: @nav-header-height; - line-height: @nav-header-height; - } - .drawer .drawer-content { - background: #001529; - } - .ant-menu-inline-collapsed { - & > .ant-menu-item .sider-menu-item-img + span, - & - > .ant-menu-item-group - > .ant-menu-item-group-list - > .ant-menu-item - .sider-menu-item-img - + span, - & > .ant-menu-submenu > .ant-menu-submenu-title .sider-menu-item-img + span { - max-width: 0; - display: inline-block; - opacity: 0; - } - } - .ant-menu-item .sider-menu-item-img + span, - .ant-menu-submenu-title .sider-menu-item-img + span { - transition: opacity 0.3s @ease-in-out, width 0.3s @ease-in-out; - opacity: 1; - } - .ant-drawer-left { - .ant-drawer-body { - padding: 0; - } - } -} diff --git a/src/components/TagSelect/TagSelectOption.d.ts b/src/components/TagSelect/TagSelectOption.d.ts deleted file mode 100644 index 366b297a7d3ff01c2a07a5c219b1b04558b8f8ab..0000000000000000000000000000000000000000 --- a/src/components/TagSelect/TagSelectOption.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import * as React from 'react'; - -export interface ITagSelectOptionProps { - value: string | number; - style?: React.CSSProperties; -} - -export default class TagSelectOption extends React.Component {} diff --git a/src/components/TagSelect/demo/controlled.md b/src/components/TagSelect/demo/controlled.md deleted file mode 100644 index 4e9defa78218a3b8e86675982b9ab54ccd719447..0000000000000000000000000000000000000000 --- a/src/components/TagSelect/demo/controlled.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -order: 3 -title: 受控模式 ---- - -结合 `Tag` 的 `TagSelect` 组件,方便的应用于筛选类目的业务场景中。 - -```jsx -import { Button } from 'antd'; -import TagSelect from 'ant-design-pro/lib/TagSelect'; - -class Demo extends React.Component { - state = { - value: ['cat1'], - }; - handleFormSubmit = value => { - this.setState({ - value, - }); - }; - checkAll = () => { - this.setState({ - value: ['cat1', 'cat2', 'cat3', 'cat4', 'cat5', 'cat6'], - }); - }; - render() { - return ( - - 全部 - - - 类目一 - 类目二 - 类目三 - 类目四 - 类目五 - 类目六 - - - - ); - } -} - -ReactDOM.render(, mountNode); -``` diff --git a/src/components/TagSelect/demo/expandable.md b/src/components/TagSelect/demo/expandable.md deleted file mode 100644 index c45a30a34ebac6ead244bf84301f9c795bc04086..0000000000000000000000000000000000000000 --- a/src/components/TagSelect/demo/expandable.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -order: 1 -title: 可展开和收起 ---- - -使用 `expandable` 属性,让标签组可以收起,避免过高。 - -````jsx -import TagSelect from 'ant-design-pro/lib/TagSelect'; - -function handleFormSubmit(checkedValue) { - console.log(checkedValue); -} - -ReactDOM.render( - - 类目一 - 类目二 - 类目三 - 类目四 - 类目五 - 类目六 - 类目七 - 类目八 - 类目九 - 类目十 - 类目十一 - 类目十二 - -, mountNode); -```` diff --git a/src/components/TagSelect/demo/simple.md b/src/components/TagSelect/demo/simple.md deleted file mode 100644 index 9e7a13a495d53997b1848d4e04d44f85fd6d1bbf..0000000000000000000000000000000000000000 --- a/src/components/TagSelect/demo/simple.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -order: 0 -title: 基础样例 ---- - -结合 `Tag` 的 `TagSelect` 组件,方便的应用于筛选类目的业务场景中。 - -````jsx -import TagSelect from 'ant-design-pro/lib/TagSelect'; - -function handleFormSubmit(checkedValue) { - console.log(checkedValue); -} - -ReactDOM.render( - - 类目一 - 类目二 - 类目三 - 类目四 - 类目五 - 类目六 - -, mountNode); -```` diff --git a/src/components/TagSelect/index.d.ts b/src/components/TagSelect/index.d.ts deleted file mode 100644 index 736ca52f17bb12a137d0c04b1be260b4c7c6c1e8..0000000000000000000000000000000000000000 --- a/src/components/TagSelect/index.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import * as React from 'react'; -import TagSelectOption from './TagSelectOption'; - -export interface ITagSelectProps { - onChange?: (value: string[]) => void; - expandable?: boolean; - value?: string[] | number[]; - style?: React.CSSProperties; - hideCheckAll?: boolean; -} - -export default class TagSelect extends React.Component { - public static Option: typeof TagSelectOption; - private children: - | React.ReactElement - | Array>; -} diff --git a/src/components/TagSelect/index.js b/src/components/TagSelect/index.js deleted file mode 100644 index f65764f54ac9f2104e8051a0a8fe73b65b6371cd..0000000000000000000000000000000000000000 --- a/src/components/TagSelect/index.js +++ /dev/null @@ -1,130 +0,0 @@ -import React, { Component } from 'react'; -import classNames from 'classnames'; -import { Tag, Icon } from 'antd'; - -import styles from './index.less'; - -const { CheckableTag } = Tag; - -const TagSelectOption = ({ children, checked, onChange, value }) => ( - onChange(value, state)}> - {children} - -); - -TagSelectOption.isTagSelectOption = true; - -class TagSelect extends Component { - static defaultProps = { - hideCheckAll: false, - }; - - constructor(props) { - super(props); - this.state = { - expand: false, - value: props.value || props.defaultValue || [], - }; - } - - static getDerivedStateFromProps(nextProps) { - if ('value' in nextProps) { - return { value: nextProps.value || [] }; - } - return null; - } - - onChange = value => { - const { onChange } = this.props; - if (!('value' in this.props)) { - this.setState({ value }); - } - if (onChange) { - onChange(value); - } - }; - - onSelectAll = checked => { - let checkedTags = []; - if (checked) { - checkedTags = this.getAllTags(); - } - this.onChange(checkedTags); - }; - - getAllTags() { - let { children } = this.props; - children = React.Children.toArray(children); - const checkedTags = children - .filter(child => this.isTagSelectOption(child)) - .map(child => child.props.value); - return checkedTags || []; - } - - handleTagChange = (value, checked) => { - const { value: StateValue } = this.state; - const checkedTags = [...StateValue]; - - const index = checkedTags.indexOf(value); - if (checked && index === -1) { - checkedTags.push(value); - } else if (!checked && index > -1) { - checkedTags.splice(index, 1); - } - this.onChange(checkedTags); - }; - - handleExpand = () => { - const { expand } = this.state; - this.setState({ - expand: !expand, - }); - }; - - isTagSelectOption = node => - node && - node.type && - (node.type.isTagSelectOption || node.type.displayName === 'TagSelectOption'); - - render() { - const { value, expand } = this.state; - const { children, hideCheckAll, className, style, expandable } = this.props; - - const checkedAll = this.getAllTags().length === value.length; - - const cls = classNames(styles.tagSelect, className, { - [styles.hasExpandTag]: expandable, - [styles.expanded]: expand, - }); - return ( - - {hideCheckAll ? null : ( - - 全部 - - )} - {value && - React.Children.map(children, child => { - if (this.isTagSelectOption(child)) { - return React.cloneElement(child, { - key: `tag-select-${child.props.value}`, - value: child.props.value, - checked: value.indexOf(child.props.value) > -1, - onChange: this.handleTagChange, - }); - } - return child; - })} - {expandable && ( - - {expand ? '收起' : '展开'} - - )} - - ); - } -} - -TagSelect.Option = TagSelectOption; - -export default TagSelect; diff --git a/src/components/TagSelect/index.less b/src/components/TagSelect/index.less deleted file mode 100644 index 834b39a6dba63919c8444e713548740b8b23d943..0000000000000000000000000000000000000000 --- a/src/components/TagSelect/index.less +++ /dev/null @@ -1,33 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.tagSelect { - user-select: none; - margin-left: -8px; - position: relative; - overflow: hidden; - max-height: 32px; - line-height: 32px; - transition: all 0.3s; - :global { - .ant-tag { - padding: 0 8px; - margin-right: 24px; - font-size: @font-size-base; - } - } - &.expanded { - transition: all 0.3s; - max-height: 200px; - } - .trigger { - position: absolute; - top: 0; - right: 0; - i { - font-size: 12px; - } - } - &.hasExpandTag { - padding-right: 50px; - } -} diff --git a/src/components/TagSelect/index.md b/src/components/TagSelect/index.md deleted file mode 100644 index 25a42b57a114818e4de2d30d58124acfde99eef7..0000000000000000000000000000000000000000 --- a/src/components/TagSelect/index.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: - en-US: TagSelect - zh-CN: TagSelect -subtitle: 标签选择器 -cols: 1 -order: 13 ---- - -可进行多选,带折叠收起和展开更多功能,常用于对列表进行筛选。 - -## API - -### TagSelect - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| value |选中的项 |string[] \| number[] | | -| defaultValue |默认选中的项 |string[] \| number[] | | -| onChange | 标签选择的回调函数 | Function(checkedTags) | | -| expandable | 是否展示 `展开/收起` 按钮 | Boolean | false | -| hideCheckAll | 隐藏 `全部` 按钮 | Boolean | false | - -### TagSelectOption - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| value | TagSelect的值 | string\| number | - | -| children | tag的内容 | string \| ReactNode | - | diff --git a/src/components/TopNavHeader/index.js b/src/components/TopNavHeader/index.js deleted file mode 100644 index eca4dbe4b993b21de576c903c4fafe1fda856a9d..0000000000000000000000000000000000000000 --- a/src/components/TopNavHeader/index.js +++ /dev/null @@ -1,51 +0,0 @@ -import React, { PureComponent } 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'; - -export default class TopNavHeader extends PureComponent { - state = { - maxWidth: undefined, - }; - - static getDerivedStateFromProps(props) { - return { - maxWidth: (props.contentWidth === 'Fixed' ? 1200 : window.innerWidth) - 280 - 165 - 40, - }; - } - - render() { - const { theme, contentWidth, menuData, logo } = this.props; - const { maxWidth } = this.state; - const flatMenuKeys = getFlatMenuKeys(menuData); - return ( - - { - this.maim = ref; - }} - className={`${styles.main} ${contentWidth === 'Fixed' ? styles.wide : ''}`} - > - - - - - Ant Design Pro - - - - - - - - - - ); - } -} diff --git a/src/components/TopNavHeader/index.less b/src/components/TopNavHeader/index.less deleted file mode 100644 index b299fa96a6c5bc0fef98a024ad77ddd163209f36..0000000000000000000000000000000000000000 --- a/src/components/TopNavHeader/index.less +++ /dev/null @@ -1,72 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.head { - width: 100%; - transition: background 0.3s, width 0.2s; - height: @layout-header-height; - box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); - position: relative; - :global { - .ant-menu-submenu.ant-menu-submenu-horizontal { - line-height: @layout-header-height; - height: 100%; - .ant-menu-submenu-title { - height: 100%; - } - } - } - &.light { - background-color: #fff; - } - .main { - display: flex; - height: @layout-header-height; - padding-left: 24px; - &.wide { - max-width: 1200px; - margin: auto; - padding-left: 0; - } - .left { - flex: 1; - display: flex; - } - .right { - width: 324px; - } - } -} - -.logo { - width: 165px; - height: @layout-header-height; - position: relative; - line-height: @layout-header-height; - transition: all 0.3s; - overflow: hidden; - img { - display: inline-block; - vertical-align: middle; - height: 32px; - } - h1 { - color: #fff; - display: inline-block; - vertical-align: top; - font-size: 16px; - margin: 0 0 0 12px; - font-weight: 400; - } -} - -.light { - h1 { - color: #002140; - } -} - -.menu { - border: none; - height: @layout-header-height; - line-height: @layout-header-height; -} diff --git a/src/components/Trend/demo/basic.md b/src/components/Trend/demo/basic.md deleted file mode 100644 index da771dc2f03742b09be1a903c0ce96c26997e759..0000000000000000000000000000000000000000 --- a/src/components/Trend/demo/basic.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -order: 0 -title: 演示 ---- - -在数值背后添加一个小图标来标识涨跌情况。 - -```jsx -import Trend from 'ant-design-pro/lib/Trend'; - -ReactDOM.render( - - 12% - 11% - -, mountNode); -``` diff --git a/src/components/Trend/demo/reverse.md b/src/components/Trend/demo/reverse.md deleted file mode 100644 index 26f736672cafedc0f0ea6c267eebe4c929fd9df2..0000000000000000000000000000000000000000 --- a/src/components/Trend/demo/reverse.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -order: 0 -title: 颜色反转 ---- - -在数值背后添加一个小图标来标识涨跌情况。 - -```jsx -import Trend from 'ant-design-pro/lib/Trend'; - -ReactDOM.render( - - 12% - 11% - -, mountNode); -``` diff --git a/src/components/Trend/index.d.ts b/src/components/Trend/index.d.ts deleted file mode 100644 index 7dc02010301cb3194c41d91b6bf01ac1dbdce1b8..0000000000000000000000000000000000000000 --- a/src/components/Trend/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as React from 'react'; - -export interface ITrendProps { - colorful?: boolean; - flag: 'up' | 'down'; - style?: React.CSSProperties; - reverseColor?: boolean; -} - -export default class Trend extends React.Component {} diff --git a/src/components/Trend/index.js b/src/components/Trend/index.js deleted file mode 100644 index c476ef62c722f10ca6dcf05c121111f9f91d89db..0000000000000000000000000000000000000000 --- a/src/components/Trend/index.js +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; -import { Icon } from 'antd'; -import classNames from 'classnames'; -import styles from './index.less'; - -const Trend = ({ colorful = true, reverseColor = false, flag, children, className, ...rest }) => { - const classString = classNames( - styles.trendItem, - { - [styles.trendItemGrey]: !colorful, - [styles.reverseColor]: reverseColor && colorful, - }, - className - ); - return ( - - {children} - {flag && ( - - - - )} - - ); -}; - -export default Trend; diff --git a/src/components/Trend/index.less b/src/components/Trend/index.less deleted file mode 100644 index b14b802cb2db73a4e25e9517661498e86866d4d3..0000000000000000000000000000000000000000 --- a/src/components/Trend/index.less +++ /dev/null @@ -1,37 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.trendItem { - display: inline-block; - font-size: @font-size-base; - line-height: 22px; - - .up, - .down { - margin-left: 4px; - position: relative; - top: 1px; - i { - font-size: 12px; - transform: scale(0.83); - } - } - .up { - color: @red-6; - } - .down { - color: @green-6; - top: -1px; - } - - &.trendItemGrey .up, - &.trendItemGrey .down { - color: @text-color; - } - - &.reverseColor .up { - color: @green-6; - } - &.reverseColor .down { - color: @red-6; - } -} diff --git a/src/components/Trend/index.md b/src/components/Trend/index.md deleted file mode 100644 index 3e3ac07a57cf8c20b71ccf8fe21ed27820db2804..0000000000000000000000000000000000000000 --- a/src/components/Trend/index.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: - en-US: Trend - zh-CN: Trend -subtitle: 趋势标记 -cols: 1 -order: 14 ---- - -趋势符号,标记上升和下降趋势。通常用绿色代表“好”,红色代表“不好”,股票涨跌场景除外。 - -## API - -```html -50% -``` - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| colorful | 是否彩色标记 | Boolean | true | -| flag | 上升下降标识:`up|down` | string | - | -| reverseColor | 颜色反转 | Boolean | false | diff --git a/src/components/_utils/pathTools.js b/src/components/_utils/pathTools.js deleted file mode 100644 index bfb94e74e0d354797ab573f7cdcf13a81983716b..0000000000000000000000000000000000000000 --- a/src/components/_utils/pathTools.js +++ /dev/null @@ -1,6 +0,0 @@ -// /userinfo/2144/id => ['/userinfo','/useinfo/2144,'/userindo/2144/id'] -// eslint-disable-next-line import/prefer-default-export -export function urlToList(url) { - const urllist = url.split('/').filter(i => i); - return urllist.map((urlItem, index) => `/${urllist.slice(0, index + 1).join('/')}`); -} diff --git a/src/components/_utils/pathTools.test.js b/src/components/_utils/pathTools.test.js deleted file mode 100644 index a9b93155176fb9cd8a7eaf088e6ba50c9103e512..0000000000000000000000000000000000000000 --- 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/defaultSettings.js b/src/defaultSettings.js deleted file mode 100644 index 0c61109719fe305522f29e963194a502fb1d33f1..0000000000000000000000000000000000000000 --- a/src/defaultSettings.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - navTheme: 'dark', // theme for nav menu - primaryColor: '#1890FF', // primary color of ant design - layout: 'sidemenu', // nav menu position: sidemenu or topmenu - contentWidth: 'Fluid', // layout of content: Fluid or Fixed, only works when layout is topmenu - fixedHeader: false, // sticky header - autoHideHeader: false, // auto hide header - fixSiderbar: false, // sticky siderbar - title: 'Ant Design Pro', -}; diff --git a/src/e2e/baseLayout.e2e.js b/src/e2e/baseLayout.e2e.js deleted file mode 100644 index 74938719d5a2c071fba3f1e407ca18af1c36720e..0000000000000000000000000000000000000000 --- a/src/e2e/baseLayout.e2e.js +++ /dev/null @@ -1,34 +0,0 @@ -import RouterConfig from '../../config/router.config'; - -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/src/e2e/home.e2e.js b/src/e2e/home.e2e.js deleted file mode 100644 index 0531d5f4b549d477d51f980df92b016bf8e00cc2..0000000000000000000000000000000000000000 --- a/src/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/src/e2e/login.e2e.js b/src/e2e/login.e2e.js deleted file mode 100644 index b991af44ba7a953df0786fd28d8e64a536870aaf..0000000000000000000000000000000000000000 --- a/src/e2e/login.e2e.js +++ /dev/null @@ -1,34 +0,0 @@ -const BASE_URL = `http://localhost:${process.env.PORT || 8000}`; - -describe('Login', () => { - beforeAll(async () => { - jest.setTimeout(1000000); - }); - - beforeEach(async () => { - await page.goto(`${BASE_URL}/user/login`, { waitUntil: 'networkidle2' }); - await page.evaluate(() => window.localStorage.setItem('antd-pro-authority', 'guest')); - }); - - it('should login with failure', async () => { - await page.waitForSelector('#userName', { - timeout: 2000, - }); - await page.type('#userName', 'mockuser'); - await page.type('#password', 'wrong_password'); - await page.click('button[type="submit"]'); - await page.waitForSelector('.ant-alert-error'); // should display error - }); - - it('should login successfully', async () => { - await page.waitForSelector('#userName', { - timeout: 2000, - }); - await page.type('#userName', 'admin'); - await page.type('#password', 'ant.design'); - await page.click('button[type="submit"]'); - await page.waitForSelector('.ant-layout-sider h1'); // should display error - const text = await page.evaluate(() => document.body.innerHTML); - expect(text).toContain('Ant Design Pro'); - }); -}); diff --git a/src/e2e/topMenu.e2e.js b/src/e2e/topMenu.e2e.js deleted file mode 100644 index 51ff9f35c632e3c6471b153b45f76b40e9a11cc9..0000000000000000000000000000000000000000 --- a/src/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/src/e2e/userLayout.e2e.js b/src/e2e/userLayout.e2e.js deleted file mode 100644 index a2edfc7b80d13cd7fee411e07642a7ef74e80951..0000000000000000000000000000000000000000 --- a/src/e2e/userLayout.e2e.js +++ /dev/null @@ -1,32 +0,0 @@ -import RouterConfig from '../../config/router.config'; - -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/src/global.js b/src/global.js deleted file mode 100644 index 62f8ccebefe899371f39e0419cc3f82d514fafc9..0000000000000000000000000000000000000000 --- a/src/global.js +++ /dev/null @@ -1,54 +0,0 @@ -import React from 'react'; -import { notification, Button, message } from 'antd'; -import { formatMessage } from 'umi/locale'; - -// Notify user if offline now -window.addEventListener('sw.offline', () => { - message.warning(formatMessage({ id: 'app.pwa.offline' })); -}); - -// Pop up a prompt on the page asking the user if they want to use the latest version -window.addEventListener('sw.updated', e => { - const reloadSW = async () => { - // Check if there is sw whose state is waiting in ServiceWorkerRegistration - // https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration - const worker = e.detail && e.detail.waiting; - if (!worker) { - return Promise.resolve(); - } - // Send skip-waiting event to waiting SW with MessageChannel - await new Promise((resolve, reject) => { - const channel = new MessageChannel(); - channel.port1.onmessage = event => { - if (event.data.error) { - reject(event.data.error); - } else { - resolve(event.data); - } - }; - worker.postMessage({ type: 'skip-waiting' }, [channel.port2]); - }); - // Refresh current page to use the updated HTML and other assets after SW has skiped waiting - window.location.reload(true); - return true; - }; - const key = `open${Date.now()}`; - const btn = ( - { - notification.close(key); - reloadSW(); - }} - > - {formatMessage({ id: 'app.pwa.serviceworker.updated.ok' })} - - ); - notification.open({ - message: formatMessage({ id: 'app.pwa.serviceworker.updated' }), - description: formatMessage({ id: 'app.pwa.serviceworker.updated.hint' }), - btn, - key, - onClose: async () => {}, - }); -}); diff --git a/src/global.less b/src/global.less deleted file mode 100644 index fccd7e835aa07b44811beb7ce65a16bee02dce15..0000000000000000000000000000000000000000 --- a/src/global.less +++ /dev/null @@ -1,33 +0,0 @@ -html, -body, -#root { - height: 100%; -} - -.colorWeak { - filter: invert(80%); -} - -.ant-layout { - min-height: 100vh; -} - -canvas { - display: block; -} - -body { - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.globalSpin { - width: 100%; - margin: 40px 0 !important; -} - -ul, -ol { - list-style: none; -} diff --git a/src/layouts/BasicLayout.js b/src/layouts/BasicLayout.js deleted file mode 100644 index 914f47f8ce81adc592bde2361c6587893d21a59a..0000000000000000000000000000000000000000 --- a/src/layouts/BasicLayout.js +++ /dev/null @@ -1,233 +0,0 @@ -import React, { Suspense } from 'react'; -import { Layout } from 'antd'; -import DocumentTitle from 'react-document-title'; -import isEqual from 'lodash/isEqual'; -import memoizeOne from 'memoize-one'; -import { connect } from 'dva'; -import { ContainerQuery } from 'react-container-query'; -import classNames from 'classnames'; -import pathToRegexp from 'path-to-regexp'; -import Media from 'react-media'; -import { formatMessage } from 'umi/locale'; -import Authorized from '@/utils/Authorized'; -import logo from '../assets/logo.svg'; -import Footer from './Footer'; -import Header from './Header'; -import Context from './MenuContext'; -import Exception403 from '../pages/Exception/403'; -import PageLoading from '@/components/PageLoading'; -import SiderMenu from '@/components/SiderMenu'; -import { title } from '../defaultSettings'; -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.PureComponent { - constructor(props) { - super(props); - this.getPageTitle = memoizeOne(this.getPageTitle); - this.matchParamsPath = memoizeOne(this.matchParamsPath, isEqual); - } - - componentDidMount() { - const { - dispatch, - route: { routes, authority }, - } = this.props; - dispatch({ - type: 'user/fetchCurrent', - }); - dispatch({ - type: 'setting/getSetting', - }); - dispatch({ - type: 'menu/getMenuData', - payload: { routes, authority }, - }); - } - - componentDidUpdate(preProps) { - // After changing to phone mode, - // if collapsed is true, you need to click twice to display - const { collapsed, isMobile } = this.props; - if (isMobile && !preProps.isMobile && !collapsed) { - this.handleMenuCollapse(false); - } - } - - getContext() { - const { location, breadcrumbNameMap } = this.props; - return { - location, - breadcrumbNameMap, - }; - } - - matchParamsPath = (pathname, breadcrumbNameMap) => { - const pathKey = Object.keys(breadcrumbNameMap).find(key => pathToRegexp(key).test(pathname)); - return breadcrumbNameMap[pathKey]; - }; - - getRouterAuthority = (pathname, routeData) => { - let routeAuthority = ['noAuthority']; - const getAuthority = (key, routes) => { - routes.forEach(route => { - if (route.path && pathToRegexp(route.path).test(key)) { - routeAuthority = route.authority; - } else if (route.routes) { - routeAuthority = getAuthority(key, route.routes); - } - return route; - }); - return routeAuthority; - }; - return getAuthority(pathname, routeData); - }; - - getPageTitle = (pathname, breadcrumbNameMap) => { - const currRouterData = this.matchParamsPath(pathname, breadcrumbNameMap); - - if (!currRouterData) { - return title; - } - const pageName = formatMessage({ - id: currRouterData.locale || currRouterData.name, - defaultMessage: currRouterData.name, - }); - - return `${pageName} - ${title}`; - }; - - 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, - route: { routes }, - fixedHeader, - } = this.props; - - const isTop = PropsLayout === 'topmenu'; - const routerConfig = this.getRouterAuthority(pathname, routes); - const contentStyle = !fixedHeader ? { paddingTop: 0 } : {}; - const layout = ( - - {isTop && !isMobile ? null : ( - - )} - - - - }> - {children} - - - - - - ); - return ( - - - - {params => ( - - {layout} - - )} - - - }>{this.renderSettingDrawer()} - - ); - } -} - -export default connect(({ global, setting, menu }) => ({ - collapsed: global.collapsed, - layout: setting.layout, - menuData: menu.menuData, - breadcrumbNameMap: menu.breadcrumbNameMap, - ...setting, -}))(props => ( - - {isMobile => } - -)); diff --git a/src/layouts/BasicLayout.less b/src/layouts/BasicLayout.less deleted file mode 100644 index 60beb60923741967a5e5940d2152778a57243c06..0000000000000000000000000000000000000000 --- a/src/layouts/BasicLayout.less +++ /dev/null @@ -1,6 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.content { - margin: 24px; - padding-top: @layout-header-height; -} diff --git a/src/layouts/BlankLayout.js b/src/layouts/BlankLayout.js deleted file mode 100644 index 505270f87ca54fc4ba3d39b148698eba5e14ddd0..0000000000000000000000000000000000000000 --- a/src/layouts/BlankLayout.js +++ /dev/null @@ -1,3 +0,0 @@ -import React from 'react'; - -export default props => ; diff --git a/src/layouts/Footer.js b/src/layouts/Footer.js deleted file mode 100644 index 693c81721e1c41c93a0de2dee321ea358f9d4455..0000000000000000000000000000000000000000 --- a/src/layouts/Footer.js +++ /dev/null @@ -1,37 +0,0 @@ -import React, { Fragment } from 'react'; -import { Layout, Icon } from 'antd'; -import GlobalFooter from '@/components/GlobalFooter'; - -const { Footer } = Layout; -const FooterView = () => ( - -); -export default FooterView; diff --git a/src/layouts/Header.js b/src/layouts/Header.js deleted file mode 100644 index 3c22510da00ee2317e3140d18474bbcfa20b0fc6..0000000000000000000000000000000000000000 --- a/src/layouts/Header.js +++ /dev/null @@ -1,161 +0,0 @@ -import React, { PureComponent } from 'react'; -import { formatMessage } from 'umi/locale'; -import { Layout, message } from 'antd'; -import Animate from 'rc-animate'; -import { connect } from 'dva'; -import router from 'umi/router'; -import GlobalHeader from '@/components/GlobalHeader'; -import TopNavHeader from '@/components/TopNavHeader'; -import styles from './Header.less'; - -const { Header } = Layout; - -class HeaderView extends PureComponent { - state = { - visible: true, - }; - - static getDerivedStateFromProps(props, state) { - if (!props.autoHideHeader && !state.visible) { - return { - visible: true, - }; - } - return null; - } - - componentDidMount() { - document.addEventListener('scroll', this.handScroll, { passive: true }); - } - - componentWillUnmount() { - document.removeEventListener('scroll', this.handScroll); - } - - getHeadWidth = () => { - const { isMobile, collapsed, setting } = this.props; - const { fixedHeader, layout } = setting; - if (isMobile || !fixedHeader || layout === 'topmenu') { - return '100%'; - } - return collapsed ? 'calc(100% - 80px)' : 'calc(100% - 256px)'; - }; - - handleNoticeClear = type => { - message.success( - `${formatMessage({ id: 'component.noticeIcon.cleared' })} ${formatMessage({ - id: `component.globalHeader.${type}`, - })}` - ); - const { dispatch } = this.props; - dispatch({ - type: 'global/clearNotices', - payload: type, - }); - }; - - handleMenuClick = ({ key }) => { - const { dispatch } = this.props; - if (key === 'userCenter') { - router.push('/account/center'); - return; - } - if (key === 'triggerError') { - router.push('/exception/trigger'); - return; - } - if (key === 'userinfo') { - router.push('/account/settings/base'); - return; - } - if (key === 'logout') { - dispatch({ - type: 'login/logout', - }); - } - }; - - handleNoticeVisibleChange = visible => { - if (visible) { - const { dispatch } = this.props; - dispatch({ - type: 'global/fetchNotices', - }); - } - }; - - handScroll = () => { - const { autoHideHeader } = this.props; - const { visible } = this.state; - if (!autoHideHeader) { - return; - } - const scrollTop = document.body.scrollTop + document.documentElement.scrollTop; - if (!this.ticking) { - this.ticking = true; - requestAnimationFrame(() => { - if (this.oldScrollTop > scrollTop) { - this.setState({ - visible: true, - }); - } else if (scrollTop > 300 && visible) { - this.setState({ - visible: false, - }); - } else if (scrollTop < 300 && !visible) { - this.setState({ - visible: true, - }); - } - this.oldScrollTop = scrollTop; - this.ticking = false; - }); - } - }; - - render() { - const { isMobile, handleMenuCollapse, setting } = this.props; - const { navTheme, layout, fixedHeader } = setting; - const { visible } = this.state; - const isTop = layout === 'topmenu'; - const width = this.getHeadWidth(); - const HeaderDom = visible ? ( - - {isTop && !isMobile ? ( - - ) : ( - - )} - - ) : null; - return ( - - {HeaderDom} - - ); - } -} - -export default connect(({ user, global, setting, loading }) => ({ - currentUser: user.currentUser, - collapsed: global.collapsed, - fetchingMoreNotices: loading.effects['global/fetchMoreNotices'], - fetchingNotices: loading.effects['global/fetchNotices'], - loadedAllNotices: global.loadedAllNotices, - notices: global.notices, - setting, -}))(HeaderView); diff --git a/src/layouts/Header.less b/src/layouts/Header.less deleted file mode 100644 index 394bfda13f7ecddefecd0b14aead860527d832df..0000000000000000000000000000000000000000 --- a/src/layouts/Header.less +++ /dev/null @@ -1,8 +0,0 @@ -.fixedHeader { - position: fixed; - top: 0; - right: 0; - width: 100%; - z-index: 9; - transition: width 0.2s; -} diff --git a/src/layouts/MenuContext.js b/src/layouts/MenuContext.js deleted file mode 100644 index 860f106868159e8d3e1bcd81297acddff826b1c0..0000000000000000000000000000000000000000 --- a/src/layouts/MenuContext.js +++ /dev/null @@ -1,3 +0,0 @@ -import { createContext } from 'react'; - -export default createContext(); diff --git a/src/layouts/UserLayout.js b/src/layouts/UserLayout.js deleted file mode 100644 index 16b70ac77f40e57fc10411f1ff95efc9c8c49205..0000000000000000000000000000000000000000 --- a/src/layouts/UserLayout.js +++ /dev/null @@ -1,72 +0,0 @@ -import React, { Fragment } from 'react'; -import { formatMessage } from 'umi/locale'; -import Link from 'umi/link'; -import { Icon } from 'antd'; -import GlobalFooter from '@/components/GlobalFooter'; -import SelectLang from '@/components/SelectLang'; -import styles from './UserLayout.less'; -import logo from '../assets/logo.svg'; - -const links = [ - { - key: 'help', - title: formatMessage({ id: 'layout.user.link.help' }), - href: '', - }, - { - key: 'privacy', - title: formatMessage({ id: 'layout.user.link.privacy' }), - href: '', - }, - { - key: 'terms', - title: formatMessage({ id: 'layout.user.link.terms' }), - href: '', - }, -]; - -const copyright = ( - - Copyright 2018 蚂蚁金服体验技术部出品 - -); - -class UserLayout extends React.PureComponent { - // @TODO title - // getPageTitle() { - // const { routerData, location } = this.props; - // const { pathname } = location; - // let title = 'Ant Design Pro'; - // if (routerData[pathname] && routerData[pathname].name) { - // title = `${routerData[pathname].name} - Ant Design Pro`; - // } - // return title; - // } - - render() { - const { children } = this.props; - return ( - // @TODO - - - - - - - - - - Ant Design - - - Ant Design 是西湖区最具影响力的 Web 设计规范 - - {children} - - - - ); - } -} - -export default UserLayout; diff --git a/src/layouts/UserLayout.less b/src/layouts/UserLayout.less deleted file mode 100644 index 5eb257a442db44cc5abfbecdb8db76f94d8d08d6..0000000000000000000000000000000000000000 --- a/src/layouts/UserLayout.less +++ /dev/null @@ -1,71 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.container { - display: flex; - flex-direction: column; - height: 100vh; - overflow: auto; - background: @layout-body-background; -} - -.lang { - text-align: right; - width: 100%; - height: 40px; - line-height: 44px; - :global(.ant-dropdown-trigger) { - margin-right: 24px; - } -} - -.content { - padding: 32px 0; - flex: 1; -} - -@media (min-width: @screen-md-min) { - .container { - background-image: url('https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg'); - background-repeat: no-repeat; - background-position: center 110px; - background-size: 100%; - } - - .content { - padding: 32px 0 24px 0; - } -} - -.top { - text-align: center; -} - -.header { - height: 44px; - line-height: 44px; - a { - text-decoration: none; - } -} - -.logo { - height: 44px; - vertical-align: top; - margin-right: 16px; -} - -.title { - font-size: 33px; - color: @heading-color; - font-family: Avenir, 'Helvetica Neue', Arial, Helvetica, sans-serif; - font-weight: 600; - position: relative; - top: 2px; -} - -.desc { - font-size: @font-size-base; - color: @text-color-secondary; - margin-top: 12px; - margin-bottom: 40px; -} diff --git a/src/locales/en-US.js b/src/locales/en-US.js deleted file mode 100644 index fcaffcebaab472855ab6118ce547355bf38b3334..0000000000000000000000000000000000000000 --- a/src/locales/en-US.js +++ /dev/null @@ -1,33 +0,0 @@ -import analysis from './en-US/analysis'; -import exception from './en-US/exception'; -import form from './en-US/form'; -import globalHeader from './en-US/globalHeader'; -import login from './en-US/login'; -import menu from './en-US/menu'; -import monitor from './en-US/monitor'; -import result from './en-US/result'; -import settingDrawer from './en-US/settingDrawer'; -import settings from './en-US/settings'; -import pwa from './en-US/pwa'; - -export default { - 'navBar.lang': 'Languages', - 'layout.user.link.help': 'Help', - 'layout.user.link.privacy': 'Privacy', - 'layout.user.link.terms': 'Terms', - 'app.home.introduce': 'introduce', - 'app.forms.basic.title': 'Basic form', - 'app.forms.basic.description': - 'Form pages are used to collect or verify information to users, and basic forms are common in scenarios where there are fewer data items.', - ...analysis, - ...exception, - ...form, - ...globalHeader, - ...login, - ...menu, - ...monitor, - ...result, - ...settingDrawer, - ...settings, - ...pwa, -}; diff --git a/src/locales/en-US/analysis.js b/src/locales/en-US/analysis.js deleted file mode 100644 index f3005dabda3424afba50571ee59700fea71d825b..0000000000000000000000000000000000000000 --- a/src/locales/en-US/analysis.js +++ /dev/null @@ -1,34 +0,0 @@ -export default { - 'app.analysis.test': 'Gongzhuan No.{no} shop', - 'app.analysis.introduce': 'Introduce', - 'app.analysis.total-sales': 'Total Sales', - 'app.analysis.day-sales': 'Daily Sales', - 'app.analysis.visits': 'Visits', - 'app.analysis.visits-trend': 'Visits Trend', - 'app.analysis.visits-ranking': 'Visits Ranking', - 'app.analysis.day-visits': 'Daily Visits', - 'app.analysis.week': 'WoW Change', - 'app.analysis.day': 'DoD Change', - 'app.analysis.payments': 'Payments', - 'app.analysis.conversion-rate': 'Conversion Rate', - 'app.analysis.operational-effect': 'Operational Effect', - 'app.analysis.sales-trend': 'Stores Sales Trend', - 'app.analysis.sales-ranking': 'Sales Ranking', - 'app.analysis.all-year': 'All Year', - 'app.analysis.all-month': 'All Month', - 'app.analysis.all-week': 'All Week', - 'app.analysis.all-day': 'All day', - 'app.analysis.search-users': 'Search Users', - 'app.analysis.per-capita-search': 'Per Capita Search', - 'app.analysis.online-top-search': 'Online Top Search', - 'app.analysis.the-proportion-of-sales': 'The Proportion Of Sales', - 'app.analysis.channel.all': 'ALL', - 'app.analysis.channel.online': 'Online', - 'app.analysis.channel.stores': 'Stores', - 'app.analysis.sales': 'Sales', - 'app.analysis.traffic': 'Traffic', - 'app.analysis.table.rank': 'Rank', - 'app.analysis.table.search-keyword': 'Keyword', - 'app.analysis.table.users': 'Users', - 'app.analysis.table.weekly-range': 'Weekly Range', -}; diff --git a/src/locales/en-US/exception.js b/src/locales/en-US/exception.js deleted file mode 100644 index 5035552afe58376eee40c3b037bbed408b470952..0000000000000000000000000000000000000000 --- a/src/locales/en-US/exception.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - 'app.exception.back': 'Back to home', - 'app.exception.description.403': "Sorry, you don't have access to this page", - 'app.exception.description.404': 'Sorry, the page you visited does not exist', - 'app.exception.description.500': 'Sorry, the server is reporting an error', -}; diff --git a/src/locales/en-US/form.js b/src/locales/en-US/form.js deleted file mode 100644 index 36e088d3e478f01e6130725e1fa7199f4831e425..0000000000000000000000000000000000000000 --- a/src/locales/en-US/form.js +++ /dev/null @@ -1,38 +0,0 @@ -export default { - 'form.get-captcha': 'Get Captcha', - 'form.captcha.second': 'sec', - 'form.optional': ' (optional) ', - 'form.submit': 'Submit', - 'form.save': 'Save', - 'form.email.placeholder': 'Email', - 'form.password.placeholder': 'Password', - 'form.confirm-password.placeholder': 'Confirm password', - 'form.phone-number.placeholder': 'Phone number', - 'form.verification-code.placeholder': 'Verification code', - 'form.title.label': 'Title', - 'form.title.placeholder': 'Give the target a name', - 'form.date.label': 'Start and end date', - 'form.date.placeholder.start': 'Start date', - 'form.date.placeholder.end': 'End date', - 'form.goal.label': 'Goal description', - 'form.goal.placeholder': 'Please enter your work goals', - 'form.standard.label': 'Metrics', - 'form.standard.placeholder': 'Please enter a metric', - 'form.client.label': 'Client', - 'form.client.label.tooltip': 'Target service object', - 'form.client.placeholder': - 'Please describe your customer service, internal customers directly @ Name / job number', - 'form.invites.label': 'Inviting critics', - 'form.invites.placeholder': 'Please direct @ Name / job number, you can invite up to 5 people', - 'form.weight.label': 'Weight', - 'form.weight.placeholder': 'Please enter weight', - 'form.public.label': 'Target disclosure', - 'form.public.label.help': 'Customers and invitees are shared by default', - 'form.public.radio.public': 'Public', - 'form.public.radio.partially-public': 'Partially public', - 'form.public.radio.private': 'Private', - 'form.publicUsers.placeholder': 'Open to', - 'form.publicUsers.option.A': 'Colleague A', - 'form.publicUsers.option.B': 'Colleague B', - 'form.publicUsers.option.C': 'Colleague C', -}; diff --git a/src/locales/en-US/globalHeader.js b/src/locales/en-US/globalHeader.js deleted file mode 100644 index 29f21d7d264c280642637ee533d762dc92e64423..0000000000000000000000000000000000000000 --- a/src/locales/en-US/globalHeader.js +++ /dev/null @@ -1,18 +0,0 @@ -export default { - 'component.globalHeader.search': 'Search', - 'component.globalHeader.search.example1': 'Search example 1', - 'component.globalHeader.search.example2': 'Search example 2', - 'component.globalHeader.search.example3': 'Search example 3', - 'component.globalHeader.help': 'Help', - 'component.globalHeader.notification': 'Notification', - 'component.globalHeader.notification.empty': 'You have viewed all notifications.', - 'component.globalHeader.message': 'Message', - 'component.globalHeader.message.empty': 'You have viewed all messsages.', - 'component.globalHeader.event': 'Event', - 'component.globalHeader.event.empty': 'You have viewed all events.', - 'component.noticeIcon.clear': 'Clear', - 'component.noticeIcon.cleared': 'Cleared', - 'component.noticeIcon.empty': 'No notifications', - 'component.noticeIcon.loaded': 'Loaded', - 'component.noticeIcon.loading-more': 'Loading more', -}; diff --git a/src/locales/en-US/login.js b/src/locales/en-US/login.js deleted file mode 100644 index 82c1c20f87281c58357e0242b8290d7016e7a4a1..0000000000000000000000000000000000000000 --- a/src/locales/en-US/login.js +++ /dev/null @@ -1,39 +0,0 @@ -export default { - 'app.login.userName': 'userName', - 'app.login.password': 'password', - 'app.login.message-invalid-credentials': 'Invalid username or password(admin/ant.design)', - 'app.login.message-invalid-verification-code': 'Invalid verification code', - 'app.login.tab-login-credentials': 'Credentials', - 'app.login.tab-login-mobile': 'Mobile number', - 'app.login.remember-me': 'Remember me', - 'app.login.forgot-password': 'Forgot your password?', - 'app.login.sign-in-with': 'Sign in with', - 'app.login.signup': 'Sign up', - 'app.login.login': 'Login', - 'app.register.register': 'Register', - 'app.register.get-verification-code': 'Get code', - 'app.register.sign-in': 'Already have an account?', - 'app.register-result.msg': 'Account:registered at {email}', - 'app.register-result.activation-email': - 'The activation email has been sent to your email address and is valid for 24 hours. Please log in to the email in time and click on the link in the email to activate the account.', - 'app.register-result.back-home': 'Back to home', - 'app.register-result.view-mailbox': 'View mailbox', - 'validation.email.required': 'Please enter your email!', - 'validation.email.wrong-format': 'The email address is in the wrong format!', - 'validation.userName.required': 'Please enter your userName!', - 'validation.password.required': 'Please enter your password!', - 'validation.password.twice': 'The passwords entered twice do not match!', - 'validation.password.strength.msg': - "Please enter at least 6 characters and don't use passwords that are easy to guess.", - 'validation.password.strength.strong': 'Strength: strong', - 'validation.password.strength.medium': 'Strength: medium', - 'validation.password.strength.short': 'Strength: too short', - 'validation.confirm-password.required': 'Please confirm your password!', - 'validation.phone-number.required': 'Please enter your phone number!', - 'validation.phone-number.wrong-format': 'Malformed phone number!', - 'validation.verification-code.required': 'Please enter the verification code!', - 'validation.title.required': 'Please enter a title', - 'validation.date.required': 'Please select the start and end date', - 'validation.goal.required': 'Please enter a description of the goal', - 'validation.standard.required': 'Please enter a metric', -}; diff --git a/src/locales/en-US/menu.js b/src/locales/en-US/menu.js deleted file mode 100644 index 3102a60030db2fba1905354de3d1891d1794a72e..0000000000000000000000000000000000000000 --- a/src/locales/en-US/menu.js +++ /dev/null @@ -1,38 +0,0 @@ -export default { - 'menu.home': 'Home', - 'menu.dashboard': 'Dashboard', - 'menu.dashboard.analysis': 'Analysis', - 'menu.dashboard.monitor': 'Monitor', - 'menu.dashboard.workplace': 'Workplace', - 'menu.form': 'Form', - 'menu.form.basicform': 'Basic Form', - 'menu.form.stepform': 'Step Form', - 'menu.form.stepform.info': 'Step Form(write transfer information)', - 'menu.form.stepform.confirm': 'Step Form(confirm transfer information)', - 'menu.form.stepform.result': 'Step Form(finished)', - 'menu.form.advancedform': 'Advanced Form', - 'menu.list': 'List', - 'menu.list.searchtable': 'Search Table', - 'menu.list.basiclist': 'Basic List', - 'menu.list.cardlist': 'Card List', - 'menu.list.searchlist': 'Search List', - 'menu.list.searchlist.articles': 'Search List(articles)', - 'menu.list.searchlist.projects': 'Search List(projects)', - 'menu.list.searchlist.applications': 'Search List(applications)', - 'menu.profile': 'Profile', - 'menu.profile.basic': 'Basic Profile', - 'menu.profile.advanced': 'Advanced Profile', - 'menu.result': 'Result', - 'menu.result.success': 'Success', - 'menu.result.fail': 'Fail', - 'menu.exception': 'Exception', - 'menu.exception.not-permission': '403', - 'menu.exception.not-find': '404', - 'menu.exception.server-error': '500', - 'menu.exception.trigger': 'Trigger', - 'menu.account': 'Account', - 'menu.account.center': 'Account Center', - 'menu.account.settings': 'Account Settings', - 'menu.account.trigger': 'Trigger Error', - 'menu.account.logout': 'Logout', -}; diff --git a/src/locales/en-US/monitor.js b/src/locales/en-US/monitor.js deleted file mode 100644 index dcb570552fc9f283e82221054481a9acd6a96648..0000000000000000000000000000000000000000 --- a/src/locales/en-US/monitor.js +++ /dev/null @@ -1,18 +0,0 @@ -export default { - 'app.monitor.trading-activity': 'Real-Time Trading Activity', - 'app.monitor.total-transactions': 'Total transactions today', - 'app.monitor.sales-target': 'Sales target completion rate', - 'app.monitor.remaining-time': 'Remaining time of activity', - 'app.monitor.total-transactions-per-second': 'Total transactions per second', - 'app.monitor.activity-forecast': 'Activity forecast', - 'app.monitor.efficiency': 'Efficiency', - 'app.monitor.ratio': 'Ratio', - 'app.monitor.proportion-per-category': 'Proportion Per Category', - 'app.monitor.fast-food': 'Fast food', - 'app.monitor.western-food': 'Western food', - 'app.monitor.hot-pot': 'Hot pot', - 'app.monitor.waiting-for-implementation': 'Waiting for implementation', - 'app.monitor.popular-searches': 'Popular Searches', - 'app.monitor.resource-surplus': 'Resource Surplus', - 'app.monitor.fund-surplus': 'Fund Surplus', -}; diff --git a/src/locales/en-US/pwa.js b/src/locales/en-US/pwa.js deleted file mode 100644 index ed8d199ead182b5e0834de03410de2eb19167a88..0000000000000000000000000000000000000000 --- a/src/locales/en-US/pwa.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - 'app.pwa.offline': 'You are offline now', - 'app.pwa.serviceworker.updated': 'New content is available', - 'app.pwa.serviceworker.updated.hint': 'Please press the "Refresh" button to reload current page', - 'app.pwa.serviceworker.updated.ok': 'Refresh', -}; diff --git a/src/locales/en-US/result.js b/src/locales/en-US/result.js deleted file mode 100644 index 23de8b7b7a9c079c5f437c38f2ff569516e38f92..0000000000000000000000000000000000000000 --- a/src/locales/en-US/result.js +++ /dev/null @@ -1,28 +0,0 @@ -export default { - 'app.result.error.title': 'Submission Failed', - 'app.result.error.description': - 'Please check and modify the following information before resubmitting.', - 'app.result.error.hint-title': 'The content you submitted has the following error:', - 'app.result.error.hint-text1': 'Your account has been frozen', - 'app.result.error.hint-btn1': 'Thaw immediately', - 'app.result.error.hint-text2': 'Your account is not yet eligible to apply', - 'app.result.error.hint-btn2': 'Upgrade immediately', - 'app.result.error.btn-text': 'Return to modify', - 'app.result.success.title': 'Submission Success', - 'app.result.success.description': - 'The submission results page is used to feed back the results of a series of operational tasks. If it is a simple operation, use the Message global prompt feedback. This text area can show a simple supplementary explanation. If there is a similar requirement for displaying “documents”, the following gray area can present more complicated content.', - 'app.result.success.operate-title': 'Project Name', - 'app.result.success.operate-id': 'Project ID:', - 'app.result.success.principal': 'Principal:', - 'app.result.success.operate-time': 'Effective time:', - 'app.result.success.step1-title': 'Create project', - 'app.result.success.step1-operator': 'Qu Lili', - 'app.result.success.step2-title': 'Departmental preliminary review', - 'app.result.success.step2-operator': 'Zhou Maomao', - 'app.result.success.step2-extra': 'Urge', - 'app.result.success.step3-title': 'Financial review', - 'app.result.success.step4-title': 'Finish', - 'app.result.success.btn-return': 'Back to list', - 'app.result.success.btn-project': 'View project', - 'app.result.success.btn-print': 'Print', -}; diff --git a/src/locales/en-US/settingDrawer.js b/src/locales/en-US/settingDrawer.js deleted file mode 100644 index a644905e756eb70d4a2677d6979a5895d78ebbbb..0000000000000000000000000000000000000000 --- a/src/locales/en-US/settingDrawer.js +++ /dev/null @@ -1,31 +0,0 @@ -export default { - 'app.setting.pagestyle': 'Page style setting', - 'app.setting.pagestyle.dark': 'Dark style', - 'app.setting.pagestyle.light': 'Light style', - 'app.setting.content-width': 'Content Width', - 'app.setting.content-width.fixed': 'Fixed', - 'app.setting.content-width.fluid': 'Fluid', - 'app.setting.themecolor': 'Theme Color', - 'app.setting.themecolor.dust': 'Dust Red', - 'app.setting.themecolor.volcano': 'Volcano', - 'app.setting.themecolor.sunset': 'Sunset Orange', - 'app.setting.themecolor.cyan': 'Cyan', - 'app.setting.themecolor.green': 'Polar Green', - 'app.setting.themecolor.daybreak': 'Daybreak Blue (default)', - 'app.setting.themecolor.geekblue': 'Geek Glue', - 'app.setting.themecolor.purple': 'Golden Purple', - 'app.setting.navigationmode': 'Navigation Mode', - 'app.setting.sidemenu': 'Side Menu Layout', - 'app.setting.topmenu': 'Top Menu Layout', - 'app.setting.fixedheader': 'Fixed Header', - 'app.setting.fixedsidebar': 'Fixed Sidebar', - 'app.setting.fixedsidebar.hint': 'Works on Side Menu Layout', - 'app.setting.hideheader': 'Hidden Header when scrolling', - 'app.setting.hideheader.hint': 'Works when Hidden Header is enabled', - 'app.setting.othersettings': 'Other Settings', - 'app.setting.weakmode': 'Weak Mode', - 'app.setting.copy': 'Copy Setting', - 'app.setting.copyinfo': 'copy success,please replace defaultSettings in src/models/setting.js', - 'app.setting.production.hint': - 'Setting panel shows in development environment only, please manually modify', -}; diff --git a/src/locales/en-US/settings.js b/src/locales/en-US/settings.js deleted file mode 100644 index e0de686d0bb11785fa065e54e0adbc63b74f4c4f..0000000000000000000000000000000000000000 --- a/src/locales/en-US/settings.js +++ /dev/null @@ -1,60 +0,0 @@ -export default { - 'app.settings.menuMap.basic': 'Basic Settings', - 'app.settings.menuMap.security': 'Security Settings', - 'app.settings.menuMap.binding': 'Account Binding', - 'app.settings.menuMap.notification': 'New Message Notification', - 'app.settings.basic.avatar': 'Avatar', - 'app.settings.basic.change-avatar': 'Change avatar', - 'app.settings.basic.email': 'Email', - 'app.settings.basic.email-message': 'Please input your email!', - 'app.settings.basic.nickname': 'Nickname', - 'app.settings.basic.nickname-message': 'Please input your Nickname!', - 'app.settings.basic.profile': 'Personal profile', - 'app.settings.basic.profile-message': 'Please input your personal profile!', - 'app.settings.basic.profile-placeholder': 'Brief introduction to yourself', - 'app.settings.basic.country': 'Country/Region', - 'app.settings.basic.country-message': 'Please input your country!', - 'app.settings.basic.geographic': 'Province or city', - 'app.settings.basic.geographic-message': 'Please input your geographic info!', - 'app.settings.basic.address': 'Street Address', - 'app.settings.basic.address-message': 'Please input your address!', - 'app.settings.basic.phone': 'Phone Number', - 'app.settings.basic.phone-message': 'Please input your phone!', - 'app.settings.basic.update': 'Update Information', - 'app.settings.security.strong': 'Strong', - 'app.settings.security.medium': 'Medium', - 'app.settings.security.weak': 'Weak', - 'app.settings.security.password': 'Account Password', - 'app.settings.security.password-description': 'Current password strength:', - 'app.settings.security.phone': 'Security Phone', - 'app.settings.security.phone-description': 'Bound phone:', - 'app.settings.security.question': 'Security Question', - 'app.settings.security.question-description': - 'The security question is not set, and the security policy can effectively protect the account security', - 'app.settings.security.email': 'Backup Email', - 'app.settings.security.email-description': 'Bound Email:', - 'app.settings.security.mfa': 'MFA Device', - 'app.settings.security.mfa-description': - 'Unbound MFA device, after binding, can be confirmed twice', - 'app.settings.security.modify': 'Modify', - 'app.settings.security.set': 'Set', - 'app.settings.security.bind': 'Bind', - 'app.settings.binding.taobao': 'Binding Taobao', - 'app.settings.binding.taobao-description': 'Currently unbound Taobao account', - 'app.settings.binding.alipay': 'Binding Alipay', - 'app.settings.binding.alipay-description': 'Currently unbound Alipay account', - 'app.settings.binding.dingding': 'Binding DingTalk', - 'app.settings.binding.dingding-description': 'Currently unbound DingTalk account', - 'app.settings.binding.bind': 'Bind', - 'app.settings.notification.password': 'Account Password', - 'app.settings.notification.password-description': - 'Messages from other users will be notified in the form of a station letter', - 'app.settings.notification.messages': 'System Messages', - 'app.settings.notification.messages-description': - 'System messages will be notified in the form of a station letter', - 'app.settings.notification.todo': 'To-do Notification', - 'app.settings.notification.todo-description': - 'The to-do list will be notified in the form of a letter from the station', - 'app.settings.open': 'Open', - 'app.settings.close': 'Close', -}; diff --git a/src/locales/pt-BR.js b/src/locales/pt-BR.js deleted file mode 100644 index d0fe21b782e66b31cb23ee18a39731d7fd766ac0..0000000000000000000000000000000000000000 --- a/src/locales/pt-BR.js +++ /dev/null @@ -1,33 +0,0 @@ -import analysis from './pt-BR/analysis'; -import exception from './pt-BR/exception'; -import form from './pt-BR/form'; -import globalHeader from './pt-BR/globalHeader'; -import login from './pt-BR/login'; -import menu from './pt-BR/menu'; -import monitor from './pt-BR/monitor'; -import result from './pt-BR/result'; -import settingDrawer from './pt-BR/settingDrawer'; -import settings from './pt-BR/settings'; -import pwa from './pt-BR/pwa'; - -export default { - 'navBar.lang': 'Idiomas', - 'layout.user.link.help': 'ajuda', - 'layout.user.link.privacy': 'política de privacidade', - 'layout.user.link.terms': 'termos de serviços', - 'app.home.introduce': 'introduzir', - 'app.forms.basic.title': 'Basic form', - 'app.forms.basic.description': - 'Páginas de formulário são usadas para coletar e verificar as informações dos usuários e formulários básicos são comuns nos cenários onde existem alguns formatos de informações.', - ...analysis, - ...exception, - ...form, - ...globalHeader, - ...login, - ...menu, - ...monitor, - ...result, - ...settingDrawer, - ...settings, - ...pwa, -}; diff --git a/src/locales/pt-BR/analysis.js b/src/locales/pt-BR/analysis.js deleted file mode 100644 index 96a80adf06aa86119d811b6af6fab06ce9da2edd..0000000000000000000000000000000000000000 --- a/src/locales/pt-BR/analysis.js +++ /dev/null @@ -1,34 +0,0 @@ -export default { - 'app.analysis.test': 'Gongzhuan No.{no} shop', - 'app.analysis.introduce': 'Introduzir', - 'app.analysis.total-sales': 'Vendas Totais', - 'app.analysis.day-sales': 'Vendas do Dia', - 'app.analysis.visits': 'Visitas', - 'app.analysis.visits-trend': 'Tendência de Visitas', - 'app.analysis.visits-ranking': 'Ranking de Visitas', - 'app.analysis.day-visits': 'Visitas do Dia', - 'app.analysis.week': 'Taxa Semanal', - 'app.analysis.day': 'Taxa Diária', - 'app.analysis.payments': 'Pagamentos', - 'app.analysis.conversion-rate': 'Taxa de Conversão', - 'app.analysis.operational-effect': 'Efeito Operacional', - 'app.analysis.sales-trend': 'Tendência de Vendas das Lojas', - 'app.analysis.sales-ranking': 'Ranking de Vendas', - 'app.analysis.all-year': 'Todo ano', - 'app.analysis.all-month': 'Todo mês', - 'app.analysis.all-week': 'Toda semana', - 'app.analysis.all-day': 'Todo dia', - 'app.analysis.search-users': 'Pesquisa de Usuários', - 'app.analysis.per-capita-search': 'Busca Per Capta', - 'app.analysis.online-top-search': 'Mais Buscadas Online', - 'app.analysis.the-proportion-of-sales': 'The Proportion Of Sales', - 'app.analysis.channel.all': 'Tudo', - 'app.analysis.channel.online': 'Online', - 'app.analysis.channel.stores': 'Lojas', - 'app.analysis.sales': 'Vendas', - 'app.analysis.traffic': 'Tráfego', - 'app.analysis.table.rank': 'Rank', - 'app.analysis.table.search-keyword': 'Palavra chave', - 'app.analysis.table.users': 'Usuários', - 'app.analysis.table.weekly-range': 'Faixa Semanal', -}; diff --git a/src/locales/pt-BR/exception.js b/src/locales/pt-BR/exception.js deleted file mode 100644 index ff4f1a8dd90bb9341f2bb45566f26c506786d136..0000000000000000000000000000000000000000 --- a/src/locales/pt-BR/exception.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - 'app.exception.back': 'Voltar para Início', - 'app.exception.description.403': 'Desculpe, você não tem acesso a esta página', - 'app.exception.description.404': 'Desculpe, a página que você visitou não existe', - 'app.exception.description.500': 'Desculpe, o servidor está reportando um erro', -}; diff --git a/src/locales/pt-BR/form.js b/src/locales/pt-BR/form.js deleted file mode 100644 index 8e5b76022d3ee6609ed94590b31014b00ec7f53c..0000000000000000000000000000000000000000 --- a/src/locales/pt-BR/form.js +++ /dev/null @@ -1,39 +0,0 @@ -export default { - 'form.get-captcha': 'Get Captcha', - 'form.captcha.second': 'sec', - 'form.email.placeholder': 'Email', - 'form.password.placeholder': 'Senha', - 'form.confirm-password.placeholder': 'Confirme a senha', - 'form.phone-number.placeholder': 'Telefone', - 'form.verification-code.placeholder': 'Código de verificação', - 'form.optional': ' (opcional) ', - 'form.submit': 'Enviar', - 'form.save': 'Salvar', - 'form.title.label': 'Titulo', - 'form.title.placeholder': 'Dê o nome do input', - 'form.date.label': 'Período', - 'form.date.placeholder.start': 'Data Inicial', - 'form.date.placeholder.end': 'Data Final', - 'form.goal.label': 'Objetivos', - 'form.goal.placeholder': 'Por favor, digite os seus objetivos', - 'form.standard.label': 'Métricas', - 'form.standard.placeholder': 'Por favor, digite suas métricas', - 'form.client.label': 'Cliente', - 'form.client.label.tooltip': 'Target service object', - 'form.client.placeholder': - 'Por favor, descreva seu atendimento ao cliente, clientes internos diretamente @ Nome / número do trabalho', - 'form.invites.label': 'Convidados críticos', - 'form.invites.placeholder': - 'Por favor, dirija @ Nome / número do trabalho, você pode convidar até 5 pessoas', - 'form.weight.label': 'Peso', - 'form.weight.placeholder': 'Por favor, entre com o peso', - 'form.public.label': 'Revelação de objetivo', - 'form.public.label.help': 'Clientes e convidados são compartilhados por padrão', - 'form.public.radio.public': 'Publico', - 'form.public.radio.partially-public': 'Parcialmente publico', - 'form.public.radio.private': 'Privado', - 'form.publicUsers.placeholder': 'Aberto para', - 'form.publicUsers.option.A': 'Colega A', - 'form.publicUsers.option.B': 'Colega B', - 'form.publicUsers.option.C': 'Colega C', -}; diff --git a/src/locales/pt-BR/globalHeader.js b/src/locales/pt-BR/globalHeader.js deleted file mode 100644 index eac034d50bd65844b3d5246011344f7c3fdab008..0000000000000000000000000000000000000000 --- a/src/locales/pt-BR/globalHeader.js +++ /dev/null @@ -1,18 +0,0 @@ -export default { - 'component.globalHeader.search': 'Busca', - 'component.globalHeader.search.example1': 'Exemplo de busca 1', - 'component.globalHeader.search.example2': 'Exemplo de busca 2', - 'component.globalHeader.search.example3': 'Exemplo de busca 3', - 'component.globalHeader.help': 'Ajuda', - 'component.globalHeader.notification': 'Notificação', - 'component.globalHeader.notification.empty': 'Você visualizou todas as notificações.', - 'component.globalHeader.message': 'Mensagem', - 'component.globalHeader.message.empty': 'Você visualizou todas as mensagens.', - 'component.globalHeader.event': 'Evento', - 'component.globalHeader.event.empty': 'Você visualizou todos os eventos.', - 'component.noticeIcon.clear': 'Limpar', - 'component.noticeIcon.cleared': 'Limpo', - 'component.noticeIcon.empty': 'Sem notificações', - 'component.noticeIcon.loaded': 'Carregado', - 'component.noticeIcon.loading-more': 'Carregar mais', -}; diff --git a/src/locales/pt-BR/login.js b/src/locales/pt-BR/login.js deleted file mode 100644 index 453b3dac19c7a73d7776ed8163d27a59bca65de1..0000000000000000000000000000000000000000 --- a/src/locales/pt-BR/login.js +++ /dev/null @@ -1,36 +0,0 @@ -export default { - 'app.login.userName': 'Nome de usuário', - 'app.login.password': 'Sua senha', - 'app.login.message-invalid-credentials': - 'Nome de usuário ou senha inválidosd(admin/ant.design)', - 'app.login.message-invalid-verification-code': 'Código de verificação inválido', - 'app.login.tab-login-credentials': 'Credenciais', - 'app.login.tab-login-mobile': 'Telefone', - 'app.login.remember-me': 'Lembre-me', - 'app.login.forgot-password': 'Esqueceu sua senha?', - 'app.login.sign-in-with': 'Login com', - 'app.login.signup': 'Cadastre-se', - 'app.login.login': 'Login', - 'app.register.register': 'Cadastro', - 'app.register.get-verification-code': 'Recuperar código', - 'app.register.sign-in': 'Já tem uma conta?', - 'app.register-result.msg': 'Conta:registrada em {email}', - 'app.register-result.activation-email': - 'Um email de ativação foi enviado para o seu email e é válido por 24 horas. Por favor entre no seu email e clique no link de ativação da conta.', - 'app.register-result.back-home': 'Voltar ao Início', - 'app.register-result.view-mailbox': 'Visualizar a caixa de email', - 'validation.email.required': 'Por favor insira seu email!', - 'validation.email.wrong-format': 'O email está errado!', - 'validation.userName.required': 'Por favor insira nome de usuário!', - 'validation.password.required': 'Por favor insira sua senha!', - 'validation.password.twice': 'As senhas não estão iguais!', - 'validation.password.strength.msg': - 'Por favor insira pelo menos 6 caracteres e não use senhas fáceis de adivinhar.', - 'validation.password.strength.strong': 'Força: forte', - 'validation.password.strength.medium': 'Força: média', - 'validation.password.strength.short': 'Força: curta', - 'validation.confirm-password.required': 'Por favor confirme sua senha!', - 'validation.phone-number.required': 'Por favor insira seu telefone!', - 'validation.phone-number.wrong-format': 'Formato de telefone errado!', - 'validation.verification-code.required': 'Por favor insira seu código de verificação!', -}; diff --git a/src/locales/pt-BR/menu.js b/src/locales/pt-BR/menu.js deleted file mode 100644 index 257ab0c2fd70cf76979655e7c4f2231f4eaf183d..0000000000000000000000000000000000000000 --- a/src/locales/pt-BR/menu.js +++ /dev/null @@ -1,38 +0,0 @@ -export default { - 'menu.home': 'Início', - 'menu.dashboard': 'Dashboard', - 'menu.dashboard.analysis': 'Análise', - 'menu.dashboard.monitor': 'Monitor', - 'menu.dashboard.workplace': 'Ambiente de Trabalho', - 'menu.form': 'Formulário', - 'menu.form.basicform': 'Formulário Básico', - 'menu.form.stepform': 'Formulário Assistido', - 'menu.form.stepform.info': 'Formulário Assistido(gravar informações de transferência)', - 'menu.form.stepform.confirm': 'Formulário Assistido(confirmar informações de transferência)', - 'menu.form.stepform.result': 'Formulário Assistido(finalizado)', - 'menu.form.advancedform': 'Formulário Avançado', - 'menu.list': 'Lista', - 'menu.list.searchtable': 'Tabela de Busca', - 'menu.list.basiclist': 'Lista Básica', - 'menu.list.cardlist': 'Lista de Card', - 'menu.list.searchlist': 'Lista de Busca', - 'menu.list.searchlist.articles': 'Lista de Busca(artigos)', - 'menu.list.searchlist.projects': 'Lista de Busca(projetos)', - 'menu.list.searchlist.applications': 'Lista de Busca(aplicações)', - 'menu.profile': 'Perfil', - 'menu.profile.basic': 'Perfil Básico', - 'menu.profile.advanced': 'Perfil Avançado', - 'menu.result': 'Resultado', - 'menu.result.success': 'Sucesso', - 'menu.result.fail': 'Falha', - 'menu.exception': 'Exceção', - 'menu.exception.not-permission': '403', - 'menu.exception.not-find': '404', - 'menu.exception.server-error': '500', - 'menu.exception.trigger': 'Disparar', - 'menu.account': 'Conta', - 'menu.account.center': 'Central da Conta', - 'menu.account.settings': 'Configurar Conta', - 'menu.account.trigger': 'Disparar Erro', - 'menu.account.logout': 'Sair', -}; diff --git a/src/locales/pt-BR/monitor.js b/src/locales/pt-BR/monitor.js deleted file mode 100644 index 44a260843eafbb1c394dac5dcd69182b2c44854c..0000000000000000000000000000000000000000 --- a/src/locales/pt-BR/monitor.js +++ /dev/null @@ -1,19 +0,0 @@ -export default { - 'app.monitor.trading-activity': 'Atividade de Trading Real-time', - 'app.monitor.total-transactions': 'Total de transações hoje', - 'app.monitor.sales-target': 'Taxa de conclusão da meta de vendas', - 'app.monitor.remaining-time': 'Tempo restante da atividade', - 'app.monitor.total-transactions-per-second': 'Total de transações por segundo', - 'app.monitor.activity-forecast': 'Previsão atual', - 'app.monitor.efficiency': 'Eficiência', - 'app.monitor.ratio': 'Relação', - 'app.monitor.proportion-per-category': 'Proporção por categoria', - 'app.monitor.fast-food': 'Fast food', - 'app.monitor.western-food': 'Comida Ocidental', - 'app.monitor.hot-pot': 'Hot pot', - 'app.monitor.waiting-for-implementation': 'Aguardando implementação', - 'app.monitor.popular-searches': 'Buscas populares', - 'app.monitor.resource-surplus': 'Excedente de recursos', - 'app.monitor.fund-surplus': 'Excedente do fundo', - 'app.exception.back': 'Voltar a home', -}; diff --git a/src/locales/pt-BR/pwa.js b/src/locales/pt-BR/pwa.js deleted file mode 100644 index 05cc79784227229ec18ed0b7598e6a03db6bb7d7..0000000000000000000000000000000000000000 --- a/src/locales/pt-BR/pwa.js +++ /dev/null @@ -1,7 +0,0 @@ -export default { - 'app.pwa.offline': 'Você está offline agora', - 'app.pwa.serviceworker.updated': 'Novo conteúdo está disponível', - 'app.pwa.serviceworker.updated.hint': - 'Por favor, pressione o botão "Atualizar" para recarregar a página atual', - 'app.pwa.serviceworker.updated.ok': 'Atualizar', -}; diff --git a/src/locales/pt-BR/result.js b/src/locales/pt-BR/result.js deleted file mode 100644 index 2720e07221a7c4119c341e2b919d9145d1043afb..0000000000000000000000000000000000000000 --- a/src/locales/pt-BR/result.js +++ /dev/null @@ -1,28 +0,0 @@ -export default { - 'app.result.error.title': 'A Submissão Falhou', - 'app.result.error.description': - 'Por favor, verifique e modifique as seguintes informações antes de reenviar.', - 'app.result.error.hint-title': 'O conteúdo que você enviou tem o seguinte erro:', - 'app.result.error.hint-text1': 'Sua conta foi congelada', - 'app.result.error.hint-btn1': 'Descongele imediatamente', - 'app.result.error.hint-text2': 'Sua conta ainda não está qualificada para se candidatar', - 'app.result.error.hint-btn2': 'Atualizar imediatamente', - 'app.result.error.btn-text': 'Retornar para modificar', - 'app.result.success.title': 'A Submissão foi um Sucesso', - 'app.result.success.description': - 'A página de resultados de envio é usada para fornecer os resultados de uma série de tarefas operacionais. Se for uma operação simples, use o prompt de feedback de Mensagem global. Esta área de texto pode mostrar uma explicação suplementar simples. Se houver um requisito semelhante para exibir "documentos", a área cinza a seguir pode apresentar um conteúdo mais complicado.', - 'app.result.success.operate-title': 'Nome do Projeto', - 'app.result.success.operate-id': 'ID do Projeto:', - 'app.result.success.principal': 'Principal:', - 'app.result.success.operate-time': 'Tempo efetivo:', - 'app.result.success.step1-title': 'Criar projeto', - 'app.result.success.step1-operator': 'Qu Lili', - 'app.result.success.step2-title': 'Revisão preliminar do departamento', - 'app.result.success.step2-operator': 'Zhou Maomao', - 'app.result.success.step2-extra': 'Urge', - 'app.result.success.step3-title': 'Revisão financeira', - 'app.result.success.step4-title': 'Terminar', - 'app.result.success.btn-return': 'Voltar a lista', - 'app.result.success.btn-project': 'Ver projeto', - 'app.result.success.btn-print': 'imprimir', -}; diff --git a/src/locales/pt-BR/settingDrawer.js b/src/locales/pt-BR/settingDrawer.js deleted file mode 100644 index 8a10b57e2d9ddf2a4de00eba5b4da1bef0ebedb0..0000000000000000000000000000000000000000 --- a/src/locales/pt-BR/settingDrawer.js +++ /dev/null @@ -1,32 +0,0 @@ -export default { - 'app.setting.pagestyle': 'Configuração de estilo da página', - 'app.setting.pagestyle.dark': 'Dark style', - 'app.setting.pagestyle.light': 'Light style', - 'app.setting.content-width': 'Largura do conteúdo', - 'app.setting.content-width.fixed': 'Fixo', - 'app.setting.content-width.fluid': 'Fluido', - 'app.setting.themecolor': 'Cor do Tema', - 'app.setting.themecolor.dust': 'Dust Red', - 'app.setting.themecolor.volcano': 'Volcano', - 'app.setting.themecolor.sunset': 'Sunset Orange', - 'app.setting.themecolor.cyan': 'Cyan', - 'app.setting.themecolor.green': 'Polar Green', - 'app.setting.themecolor.daybreak': 'Daybreak Blue (default)', - 'app.setting.themecolor.geekblue': 'Geek Glue', - 'app.setting.themecolor.purple': 'Golden Purple', - 'app.setting.navigationmode': 'Modo de Navegação', - 'app.setting.sidemenu': 'Layout do Menu Lateral', - 'app.setting.topmenu': 'Layout do Menu Superior', - 'app.setting.fixedheader': 'Cabeçalho fixo', - 'app.setting.fixedsidebar': 'Barra lateral fixa', - 'app.setting.fixedsidebar.hint': 'Funciona no layout do menu lateral', - 'app.setting.hideheader': 'Esconder o cabeçalho quando rolar', - 'app.setting.hideheader.hint': 'Funciona quando o esconder cabeçalho está abilitado', - 'app.setting.othersettings': 'Outras configurações', - 'app.setting.weakmode': 'Weak Mode', - 'app.setting.copy': 'Copiar Configuração', - 'app.setting.copyinfo': - 'copiado com sucesso,por favor trocar o defaultSettings em src/models/setting.js', - 'app.setting.production.hint': - 'O painel de configuração apenas é exibido no ambiente de desenvolvimento, por favor modifique manualmente o', -}; diff --git a/src/locales/pt-BR/settings.js b/src/locales/pt-BR/settings.js deleted file mode 100644 index aad2e3877550777446848c55448075d668b4c64a..0000000000000000000000000000000000000000 --- a/src/locales/pt-BR/settings.js +++ /dev/null @@ -1,60 +0,0 @@ -export default { - 'app.settings.menuMap.basic': 'Configurações Básicas', - 'app.settings.menuMap.security': 'Configurações de Segurança', - 'app.settings.menuMap.binding': 'Vinculação de Conta', - 'app.settings.menuMap.notification': 'Mensagens de Notificação', - 'app.settings.basic.avatar': 'Avatar', - 'app.settings.basic.change-avatar': 'Alterar avatar', - 'app.settings.basic.email': 'Email', - 'app.settings.basic.email-message': 'Por favor insira seu email!', - 'app.settings.basic.nickname': 'Nome de usuário', - 'app.settings.basic.nickname-message': 'Por favor insira seu nome de usuário!', - 'app.settings.basic.profile': 'Perfil pessoal', - 'app.settings.basic.profile-message': 'Por favor insira seu perfil pessoal!', - 'app.settings.basic.profile-placeholder': 'Breve introdução sua', - 'app.settings.basic.country': 'País/Região', - 'app.settings.basic.country-message': 'Por favor insira país!', - 'app.settings.basic.geographic': 'Província, estado ou cidade', - 'app.settings.basic.geographic-message': 'Por favor insira suas informações geográficas!', - 'app.settings.basic.address': 'Endereço', - 'app.settings.basic.address-message': 'Por favor insira seu endereço!', - 'app.settings.basic.phone': 'Número de telefone', - 'app.settings.basic.phone-message': 'Por favor insira seu número de telefone!', - 'app.settings.basic.update': 'Atualizar Informações', - 'app.settings.security.strong': 'Forte', - 'app.settings.security.medium': 'Média', - 'app.settings.security.weak': 'Fraca', - 'app.settings.security.password': 'Senha da Conta', - 'app.settings.security.password-description': 'Força da senha', - 'app.settings.security.phone': 'Telefone de Seguraça', - 'app.settings.security.phone-description': 'Telefone vinculado', - 'app.settings.security.question': 'Pergunta de Segurança', - 'app.settings.security.question-description': - 'A pergunta de segurança não está definida e a política de segurança pode proteger efetivamente a segurança da conta', - 'app.settings.security.email': 'Email de Backup', - 'app.settings.security.email-description': 'Email vinculado', - 'app.settings.security.mfa': 'Dispositivo MFA', - 'app.settings.security.mfa-description': - 'O dispositivo MFA não vinculado, após a vinculação, pode ser confirmado duas vezes', - 'app.settings.security.modify': 'Modificar', - 'app.settings.security.set': 'Atribuir', - 'app.settings.security.bind': 'Vincular', - 'app.settings.binding.taobao': 'Vincular Taobao', - 'app.settings.binding.taobao-description': 'Atualmente não vinculado à conta Taobao', - 'app.settings.binding.alipay': 'Vincular Alipay', - 'app.settings.binding.alipay-description': 'Atualmente não vinculado à conta Alipay', - 'app.settings.binding.dingding': 'Vincular DingTalk', - 'app.settings.binding.dingding-description': 'Atualmente não vinculado à conta DingTalk', - 'app.settings.binding.bind': 'Vincular', - 'app.settings.notification.password': 'Senha da Conta', - 'app.settings.notification.password-description': - 'Mensagens de outros usuários serão notificadas na forma de uma estação de letra', - 'app.settings.notification.messages': 'Mensagens de Sistema', - 'app.settings.notification.messages-description': - 'Mensagens de sistema serão notificadas na forma de uma estação de letra', - 'app.settings.notification.todo': 'Notificação de To-do', - 'app.settings.notification.todo-description': - 'A lista de to-do será notificada na forma de uma estação de letra', - 'app.settings.open': 'Aberto', - 'app.settings.close': 'Fechado', -}; diff --git a/src/locales/zh-CN.js b/src/locales/zh-CN.js deleted file mode 100644 index 4330d60ae6d30bf9a3446b4ad777b9a8077b5a84..0000000000000000000000000000000000000000 --- a/src/locales/zh-CN.js +++ /dev/null @@ -1,33 +0,0 @@ -import analysis from './zh-CN/analysis'; -import exception from './zh-CN/exception'; -import form from './zh-CN/form'; -import globalHeader from './zh-CN/globalHeader'; -import login from './zh-CN/login'; -import menu from './zh-CN/menu'; -import monitor from './zh-CN/monitor'; -import result from './zh-CN/result'; -import settingDrawer from './zh-CN/settingDrawer'; -import settings from './zh-CN/settings'; -import pwa from './zh-CN/pwa'; - -export default { - 'navBar.lang': '语言', - 'layout.user.link.help': '帮助', - 'layout.user.link.privacy': '隐私', - 'layout.user.link.terms': '条款', - 'app.home.introduce': '介绍', - 'app.forms.basic.title': '基础表单', - 'app.forms.basic.description': - '表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。', - ...analysis, - ...exception, - ...form, - ...globalHeader, - ...login, - ...menu, - ...monitor, - ...result, - ...settingDrawer, - ...settings, - ...pwa, -}; diff --git a/src/locales/zh-CN/analysis.js b/src/locales/zh-CN/analysis.js deleted file mode 100644 index 8ed17ed8306d6d1750da1099d509955900a485bb..0000000000000000000000000000000000000000 --- a/src/locales/zh-CN/analysis.js +++ /dev/null @@ -1,34 +0,0 @@ -export default { - 'app.analysis.test': '工专路 {no} 号店', - 'app.analysis.introduce': '指标说明', - 'app.analysis.total-sales': '总销售额', - 'app.analysis.day-sales': '日销售额', - 'app.analysis.visits': '访问量', - 'app.analysis.visits-trend': '访问量趋势', - 'app.analysis.visits-ranking': '门店访问量排名', - 'app.analysis.day-visits': '日访问量', - 'app.analysis.week': '周同比', - 'app.analysis.day': '日同比', - 'app.analysis.payments': '支付笔数', - 'app.analysis.conversion-rate': '转化率', - 'app.analysis.operational-effect': '运营活动效果', - 'app.analysis.sales-trend': '销售趋势', - 'app.analysis.sales-ranking': '门店销售额排名', - 'app.analysis.all-year': '全年', - 'app.analysis.all-month': '本月', - 'app.analysis.all-week': '本周', - 'app.analysis.all-day': '今日', - 'app.analysis.search-users': '搜索用户数', - 'app.analysis.per-capita-search': '人均搜索次数', - 'app.analysis.online-top-search': '线上热门搜索', - 'app.analysis.the-proportion-of-sales': '销售额类别占比', - 'app.analysis.channel.all': '全部渠道', - 'app.analysis.channel.online': '线上', - 'app.analysis.channel.stores': '门店', - 'app.analysis.sales': '销售额', - 'app.analysis.traffic': '客流量', - 'app.analysis.table.rank': '排名', - 'app.analysis.table.search-keyword': '搜索关键词', - 'app.analysis.table.users': '用户数', - 'app.analysis.table.weekly-range': '周涨幅', -}; diff --git a/src/locales/zh-CN/exception.js b/src/locales/zh-CN/exception.js deleted file mode 100644 index 6f645daed63e332c6ad54aa146bdcf4e720c38c8..0000000000000000000000000000000000000000 --- a/src/locales/zh-CN/exception.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - 'app.exception.back': '返回首页', - 'app.exception.description.403': '抱歉,你无权访问该页面', - 'app.exception.description.404': '抱歉,你访问的页面不存在', - 'app.exception.description.500': '抱歉,服务器出错了', -}; diff --git a/src/locales/zh-CN/form.js b/src/locales/zh-CN/form.js deleted file mode 100644 index 7f3bd9525001fc4bacb92890ca2ca5e46de22e6c..0000000000000000000000000000000000000000 --- a/src/locales/zh-CN/form.js +++ /dev/null @@ -1,37 +0,0 @@ -export default { - 'form.get-captcha': '获取验证码', - 'form.captcha.second': '秒', - 'form.optional': '(选填)', - 'form.submit': '提交', - 'form.save': '保存', - 'form.email.placeholder': '邮箱', - 'form.password.placeholder': '至少6位密码,区分大小写', - 'form.confirm-password.placeholder': '确认密码', - 'form.phone-number.placeholder': '手机号', - 'form.verification-code.placeholder': '验证码', - 'form.title.label': '标题', - 'form.title.placeholder': '给目标起个名字', - 'form.date.label': '起止日期', - 'form.date.placeholder.start': '开始日期', - 'form.date.placeholder.end': '结束日期', - 'form.goal.label': '目标描述', - 'form.goal.placeholder': '请输入你的阶段性工作目标', - 'form.standard.label': '衡量标准', - 'form.standard.placeholder': '请输入衡量标准', - 'form.client.label': '客户', - 'form.client.label.tooltip': '目标的服务对象', - 'form.client.placeholder': '请描述你服务的客户,内部客户直接 @姓名/工号', - 'form.invites.label': '邀评人', - 'form.invites.placeholder': '请直接 @姓名/工号,最多可邀请 5 人', - 'form.weight.label': '权重', - 'form.weight.placeholder': '请输入', - 'form.public.label': '目标公开', - 'form.public.label.help': '客户、邀评人默认被分享', - 'form.public.radio.public': '公开', - 'form.public.radio.partially-public': '部分公开', - 'form.public.radio.private': '不公开', - 'form.publicUsers.placeholder': '公开给', - 'form.publicUsers.option.A': '同事甲', - 'form.publicUsers.option.B': '同事乙', - 'form.publicUsers.option.C': '同事丙', -}; diff --git a/src/locales/zh-CN/globalHeader.js b/src/locales/zh-CN/globalHeader.js deleted file mode 100644 index 204538294cedfe4d37dfa7436dadf9dc8f6b73ef..0000000000000000000000000000000000000000 --- a/src/locales/zh-CN/globalHeader.js +++ /dev/null @@ -1,18 +0,0 @@ -export default { - 'component.globalHeader.search': '站内搜索', - 'component.globalHeader.search.example1': '搜索提示一', - 'component.globalHeader.search.example2': '搜索提示二', - 'component.globalHeader.search.example3': '搜索提示三', - 'component.globalHeader.help': '使用文档', - 'component.globalHeader.notification': '通知', - 'component.globalHeader.notification.empty': '你已查看所有通知', - 'component.globalHeader.message': '消息', - 'component.globalHeader.message.empty': '您已读完所有消息', - 'component.globalHeader.event': '待办', - 'component.globalHeader.event.empty': '你已完成所有待办', - 'component.noticeIcon.clear': '清空', - 'component.noticeIcon.cleared': '清空了', - 'component.noticeIcon.empty': '暂无数据', - 'component.noticeIcon.loaded': '加载完毕', - 'component.noticeIcon.loading-more': '加载更多', -}; diff --git a/src/locales/zh-CN/login.js b/src/locales/zh-CN/login.js deleted file mode 100644 index eb227207334ed3ea6e765313fad1f23b3d724dfc..0000000000000000000000000000000000000000 --- a/src/locales/zh-CN/login.js +++ /dev/null @@ -1,38 +0,0 @@ -export default { - 'app.login.userName': '用户名', - 'app.login.password': '密码', - 'app.login.message-invalid-credentials': '账户或密码错误(admin/ant.design)', - 'app.login.message-invalid-verification-code': '验证码错误', - 'app.login.tab-login-credentials': '账户密码登录', - 'app.login.tab-login-mobile': '手机号登录', - 'app.login.remember-me': '自动登录', - 'app.login.forgot-password': '忘记密码', - 'app.login.sign-in-with': '其他登录方式', - 'app.login.signup': '注册账户', - 'app.login.login': '登录', - 'app.register.register': '注册', - 'app.register.get-verification-code': '获取验证码', - 'app.register.sign-in': '使用已有账户登录', - 'app.register-result.msg': '你的账户:{email} 注册成功', - 'app.register-result.activation-email': - '激活邮件已发送到你的邮箱中,邮件有效期为24小时。请及时登录邮箱,点击邮件中的链接激活帐户。', - 'app.register-result.back-home': '返回首页', - 'app.register-result.view-mailbox': '查看邮箱', - 'validation.email.required': '请输入邮箱地址!', - 'validation.email.wrong-format': '邮箱地址格式错误!', - 'validation.userName.required': '请输入用户名!', - 'validation.password.required': '请输入密码!', - 'validation.password.twice': '两次输入的密码不匹配!', - 'validation.password.strength.msg': '请至少输入 6 个字符。请不要使用容易被猜到的密码。', - 'validation.password.strength.strong': '强度:强', - 'validation.password.strength.medium': '强度:中', - 'validation.password.strength.short': '强度:太短', - 'validation.confirm-password.required': '请确认密码!', - 'validation.phone-number.required': '请输入手机号!', - 'validation.phone-number.wrong-format': '手机号格式错误!', - 'validation.verification-code.required': '请输入验证码!', - 'validation.title.required': '请输入标题', - 'validation.date.required': '请选择起止日期', - 'validation.goal.required': '请输入目标描述', - 'validation.standard.required': '请输入衡量标准', -}; diff --git a/src/locales/zh-CN/menu.js b/src/locales/zh-CN/menu.js deleted file mode 100644 index 1383b43ff3ab6c0ad173d967da8386299efe00c6..0000000000000000000000000000000000000000 --- a/src/locales/zh-CN/menu.js +++ /dev/null @@ -1,38 +0,0 @@ -export default { - 'menu.home': '首页', - 'menu.dashboard': 'Dashboard', - 'menu.dashboard.analysis': '分析页', - 'menu.dashboard.monitor': '监控页', - 'menu.dashboard.workplace': '工作台', - 'menu.form': '表单页', - 'menu.form.basicform': '基础表单', - 'menu.form.stepform': '分步表单', - 'menu.form.stepform.info': '分步表单(填写转账信息)', - 'menu.form.stepform.confirm': '分步表单(确认转账信息)', - 'menu.form.stepform.result': '分步表单(完成)', - 'menu.form.advancedform': '高级表单', - 'menu.list': '列表页', - 'menu.list.searchtable': '查询表格', - 'menu.list.basiclist': '标准列表', - 'menu.list.cardlist': '卡片列表', - 'menu.list.searchlist': '搜索列表', - 'menu.list.searchlist.articles': '搜索列表(文章)', - 'menu.list.searchlist.projects': '搜索列表(项目)', - 'menu.list.searchlist.applications': '搜索列表(应用)', - 'menu.profile': '详情页', - 'menu.profile.basic': '基础详情页', - 'menu.profile.advanced': '高级详情页', - 'menu.result': '结果页', - 'menu.result.success': '成功页', - 'menu.result.fail': '失败页', - 'menu.exception': '异常页', - 'menu.exception.not-permission': '403', - 'menu.exception.not-find': '404', - 'menu.exception.server-error': '500', - 'menu.exception.trigger': '触发错误', - 'menu.account': '个人页', - 'menu.account.center': '个人中心', - 'menu.account.settings': '个人设置', - 'menu.account.trigger': '触发报错', - 'menu.account.logout': '退出登录', -}; diff --git a/src/locales/zh-CN/monitor.js b/src/locales/zh-CN/monitor.js deleted file mode 100644 index 3a3e3f0b55e4051cc59085be0eaf1d3b838fea41..0000000000000000000000000000000000000000 --- a/src/locales/zh-CN/monitor.js +++ /dev/null @@ -1,18 +0,0 @@ -export default { - 'app.monitor.trading-activity': '活动实时交易情况', - 'app.monitor.total-transactions': '今日交易总额', - 'app.monitor.sales-target': '销售目标完成率', - 'app.monitor.remaining-time': '活动剩余时间', - 'app.monitor.total-transactions-per-second': '每秒交易总额', - 'app.monitor.activity-forecast': '活动情况预测', - 'app.monitor.efficiency': '券核效率', - 'app.monitor.ratio': '跳出率', - 'app.monitor.proportion-per-category': '各品类占比', - 'app.monitor.fast-food': '中式快餐', - 'app.monitor.western-food': '西餐', - 'app.monitor.hot-pot': '火锅', - 'app.monitor.waiting-for-implementation': 'Waiting for implementation', - 'app.monitor.popular-searches': '热门搜索', - 'app.monitor.resource-surplus': '资源剩余', - 'app.monitor.fund-surplus': '补贴资金剩余', -}; diff --git a/src/locales/zh-CN/pwa.js b/src/locales/zh-CN/pwa.js deleted file mode 100644 index e9504849e7840c963295ac2f732a68136a1e48f0..0000000000000000000000000000000000000000 --- a/src/locales/zh-CN/pwa.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - 'app.pwa.offline': '当前处于离线状态', - 'app.pwa.serviceworker.updated': '有新内容', - 'app.pwa.serviceworker.updated.hint': '请点击“刷新”按钮或者手动刷新页面', - 'app.pwa.serviceworker.updated.ok': '刷新', -}; diff --git a/src/locales/zh-CN/result.js b/src/locales/zh-CN/result.js deleted file mode 100644 index cba0e1c1c50d2e8fa9ad43298e9014e824484718..0000000000000000000000000000000000000000 --- a/src/locales/zh-CN/result.js +++ /dev/null @@ -1,27 +0,0 @@ -export default { - 'app.result.error.title': '提交失败', - 'app.result.error.description': '请核对并修改以下信息后,再重新提交。', - 'app.result.error.hint-title': '您提交的内容有如下错误:', - 'app.result.error.hint-text1': '您的账户已被冻结', - 'app.result.error.hint-btn1': '立即解冻', - 'app.result.error.hint-text2': '您的账户还不具备申请资格', - 'app.result.error.hint-btn2': '立即升级', - 'app.result.error.btn-text': '返回修改', - 'app.result.success.title': '提交成功', - 'app.result.success.description': - '提交结果页用于反馈一系列操作任务的处理结果, 如果仅是简单操作,使用 Message 全局提示反馈即可。 本文字区域可以展示简单的补充说明,如果有类似展示 “单据”的需求,下面这个灰色区域可以呈现比较复杂的内容。', - 'app.result.success.operate-title': '项目名称', - 'app.result.success.operate-id': '项目 ID:', - 'app.result.success.principal': '负责人:', - 'app.result.success.operate-time': '生效时间:', - 'app.result.success.step1-title': '创建项目', - 'app.result.success.step1-operator': '曲丽丽', - 'app.result.success.step2-title': '部门初审', - 'app.result.success.step2-operator': '周毛毛', - 'app.result.success.step2-extra': '催一下', - 'app.result.success.step3-title': '财务复核', - 'app.result.success.step4-title': '完成', - 'app.result.success.btn-return': '返回列表', - 'app.result.success.btn-project': '查看项目', - 'app.result.success.btn-print': '打印', -}; diff --git a/src/locales/zh-CN/settingDrawer.js b/src/locales/zh-CN/settingDrawer.js deleted file mode 100644 index 15685a4055eb61174e39ad8eb6308cca7517af91..0000000000000000000000000000000000000000 --- a/src/locales/zh-CN/settingDrawer.js +++ /dev/null @@ -1,31 +0,0 @@ -export default { - 'app.setting.pagestyle': '整体风格设置', - 'app.setting.pagestyle.dark': '暗色菜单风格', - 'app.setting.pagestyle.light': '亮色菜单风格', - 'app.setting.content-width': '内容区域宽度', - 'app.setting.content-width.fixed': '定宽', - 'app.setting.content-width.fluid': '流式', - 'app.setting.themecolor': '主题色', - 'app.setting.themecolor.dust': '薄暮', - 'app.setting.themecolor.volcano': '火山', - 'app.setting.themecolor.sunset': '日暮', - 'app.setting.themecolor.cyan': '明青', - 'app.setting.themecolor.green': '极光绿', - 'app.setting.themecolor.daybreak': '拂晓蓝(默认)', - 'app.setting.themecolor.geekblue': '极客蓝', - 'app.setting.themecolor.purple': '酱紫', - 'app.setting.navigationmode': '导航模式', - 'app.setting.sidemenu': '侧边菜单布局', - 'app.setting.topmenu': '顶部菜单布局', - 'app.setting.fixedheader': '固定 Header', - 'app.setting.fixedsidebar': '固定侧边菜单', - 'app.setting.fixedsidebar.hint': '侧边菜单布局时可配置', - 'app.setting.hideheader': '下滑时隐藏 Header', - 'app.setting.hideheader.hint': '固定 Header 时可配置', - 'app.setting.othersettings': '其他设置', - 'app.setting.weakmode': '色弱模式', - 'app.setting.copy': '拷贝设置', - 'app.setting.copyinfo': '拷贝成功,请到 src/defaultSettings.js 中替换默认配置', - 'app.setting.production.hint': - '配置栏只在开发环境用于预览,生产环境不会展现,请拷贝后手动修改配置文件', -}; diff --git a/src/locales/zh-CN/settings.js b/src/locales/zh-CN/settings.js deleted file mode 100644 index f664d37b9bb5810f76b158bb9606a5ce099b6ae8..0000000000000000000000000000000000000000 --- a/src/locales/zh-CN/settings.js +++ /dev/null @@ -1,55 +0,0 @@ -export default { - 'app.settings.menuMap.basic': '基本设置', - 'app.settings.menuMap.security': '安全设置', - 'app.settings.menuMap.binding': '账号绑定', - 'app.settings.menuMap.notification': '新消息通知', - 'app.settings.basic.avatar': '头像', - 'app.settings.basic.change-avatar': '更换头像', - 'app.settings.basic.email': '邮箱', - 'app.settings.basic.email-message': '请输入您的邮箱!', - 'app.settings.basic.nickname': '昵称', - 'app.settings.basic.nickname-message': '请输入您的昵称!', - 'app.settings.basic.profile': '个人简介', - 'app.settings.basic.profile-message': '请输入个人简介!', - 'app.settings.basic.profile-placeholder': '个人简介', - 'app.settings.basic.country': '国家/地区', - 'app.settings.basic.country-message': '请输入您的国家或地区!', - 'app.settings.basic.geographic': '所在省市', - 'app.settings.basic.geographic-message': '请输入您的所在省市!', - 'app.settings.basic.address': '街道地址', - 'app.settings.basic.address-message': '请输入您的街道地址!', - 'app.settings.basic.phone': '联系电话', - 'app.settings.basic.phone-message': '请输入您的联系电话!', - 'app.settings.basic.update': '更新基本信息', - 'app.settings.security.strong': '强', - 'app.settings.security.medium': '中', - 'app.settings.security.weak': '弱', - 'app.settings.security.password': '账户密码', - 'app.settings.security.password-description': '当前密码强度:', - 'app.settings.security.phone': '密保手机', - 'app.settings.security.phone-description': '已绑定手机:', - 'app.settings.security.question': '密保问题', - 'app.settings.security.question-description': '未设置密保问题,密保问题可有效保护账户安全', - 'app.settings.security.email': '备用邮箱', - 'app.settings.security.email-description': '已绑定邮箱:', - 'app.settings.security.mfa': 'MFA 设备', - 'app.settings.security.mfa-description': '未绑定 MFA 设备,绑定后,可以进行二次确认', - 'app.settings.security.modify': '修改', - 'app.settings.security.set': '设置', - 'app.settings.security.bind': '绑定', - 'app.settings.binding.taobao': '绑定淘宝', - 'app.settings.binding.taobao-description': '当前未绑定淘宝账号', - 'app.settings.binding.alipay': '绑定支付宝', - 'app.settings.binding.alipay-description': '当前未绑定支付宝账号', - 'app.settings.binding.dingding': '绑定钉钉', - 'app.settings.binding.dingding-description': '当前未绑定钉钉账号', - 'app.settings.binding.bind': '绑定', - 'app.settings.notification.password': '账户密码', - 'app.settings.notification.password-description': '其他用户的消息将以站内信的形式通知', - 'app.settings.notification.messages': '系统消息', - 'app.settings.notification.messages-description': '系统消息将以站内信的形式通知', - 'app.settings.notification.todo': '待办任务', - 'app.settings.notification.todo-description': '待办任务将以站内信的形式通知', - 'app.settings.open': '开', - 'app.settings.close': '关', -}; diff --git a/src/locales/zh-TW.js b/src/locales/zh-TW.js deleted file mode 100644 index 986820ef3af850807cf000d6ed9c1a0e8280a276..0000000000000000000000000000000000000000 --- a/src/locales/zh-TW.js +++ /dev/null @@ -1,33 +0,0 @@ -import analysis from './zh-TW/analysis'; -import exception from './zh-TW/exception'; -import form from './zh-TW/form'; -import globalHeader from './zh-TW/globalHeader'; -import login from './zh-TW/login'; -import menu from './zh-TW/menu'; -import monitor from './zh-TW/monitor'; -import result from './zh-TW/result'; -import settingDrawer from './zh-TW/settingDrawer'; -import settings from './zh-TW/settings'; -import pwa from './zh-TW/pwa'; - -export default { - 'navBar.lang': '語言', - 'layout.user.link.help': '幫助', - 'layout.user.link.privacy': '隱私', - 'layout.user.link.terms': '條款', - 'app.home.introduce': '介紹', - 'app.forms.basic.title': '基礎表單', - 'app.forms.basic.description': - '表單頁用於向用戶收集或驗證信息,基礎表單常見於數據項較少的表單場景。', - ...analysis, - ...exception, - ...form, - ...globalHeader, - ...login, - ...menu, - ...monitor, - ...result, - ...settingDrawer, - ...settings, - ...pwa, -}; diff --git a/src/locales/zh-TW/analysis.js b/src/locales/zh-TW/analysis.js deleted file mode 100644 index 7b2e37cf34f3723f1990e22ed981f12840b171d7..0000000000000000000000000000000000000000 --- a/src/locales/zh-TW/analysis.js +++ /dev/null @@ -1,34 +0,0 @@ -export default { - 'app.analysis.test': '工專路 {no} 號店', - 'app.analysis.introduce': '指標說明', - 'app.analysis.total-sales': '總銷售額', - 'app.analysis.day-sales': '日銷售額', - 'app.analysis.visits': '訪問量', - 'app.analysis.visits-trend': '訪問量趨勢', - 'app.analysis.visits-ranking': '門店訪問量排名', - 'app.analysis.day-visits': '日訪問量', - 'app.analysis.week': '周同比', - 'app.analysis.day': '日同比', - 'app.analysis.payments': '支付筆數', - 'app.analysis.conversion-rate': '轉化率', - 'app.analysis.operational-effect': '運營活動效果', - 'app.analysis.sales-trend': '銷售趨勢', - 'app.analysis.sales-ranking': '門店銷售額排名', - 'app.analysis.all-year': '全年', - 'app.analysis.all-month': '本月', - 'app.analysis.all-week': '本周', - 'app.analysis.all-day': '今日', - 'app.analysis.search-users': '搜索用戶數', - 'app.analysis.per-capita-search': '人均搜索次數', - 'app.analysis.online-top-search': '線上熱門搜索', - 'app.analysis.the-proportion-of-sales': '銷售額類別占比', - 'app.analysis.channel.all': '全部渠道', - 'app.analysis.channel.online': '線上', - 'app.analysis.channel.stores': '門店', - 'app.analysis.sales': '銷售額', - 'app.analysis.traffic': '客流量', - 'app.analysis.table.rank': '排名', - 'app.analysis.table.search-keyword': '搜索關鍵詞', - 'app.analysis.table.users': '用戶數', - 'app.analysis.table.weekly-range': '周漲幅', -}; diff --git a/src/locales/zh-TW/exception.js b/src/locales/zh-TW/exception.js deleted file mode 100644 index 24a266137bb503e4aa6917daebc2240eaa9150aa..0000000000000000000000000000000000000000 --- a/src/locales/zh-TW/exception.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - 'app.exception.back': '返回首頁', - 'app.exception.description.403': '抱歉,妳無權訪問該頁面', - 'app.exception.description.404': '抱歉,妳訪問的頁面不存在', - 'app.exception.description.500': '抱歉,服務器出錯了', -}; diff --git a/src/locales/zh-TW/form.js b/src/locales/zh-TW/form.js deleted file mode 100644 index cf1adf548ed67450802adde1193382e7ea30e6fa..0000000000000000000000000000000000000000 --- a/src/locales/zh-TW/form.js +++ /dev/null @@ -1,37 +0,0 @@ -export default { - 'form.get-captcha': '獲取驗證碼', - 'form.captcha.second': '秒', - 'form.optional': '(選填)', - 'form.submit': '提交', - 'form.save': '保存', - 'form.email.placeholder': '郵箱', - 'form.password.placeholder': '至少6位密碼,區分大小寫', - 'form.confirm-password.placeholder': '確認密碼', - 'form.phone-number.placeholder': '手機號', - 'form.verification-code.placeholder': '驗證碼', - 'form.title.label': '標題', - 'form.title.placeholder': '給目標起個名字', - 'form.date.label': '起止日期', - 'form.date.placeholder.start': '開始日期', - 'form.date.placeholder.end': '結束日期', - 'form.goal.label': '目標描述', - 'form.goal.placeholder': '請輸入妳的階段性工作目標', - 'form.standard.label': '衡量標淮', - 'form.standard.placeholder': '請輸入衡量標淮', - 'form.client.label': '客戶', - 'form.client.label.tooltip': '目標的服務對象', - 'form.client.placeholder': '請描述妳服務的客戶,內部客戶直接 @姓名/工號', - 'form.invites.label': '邀評人', - 'form.invites.placeholder': '請直接 @姓名/工號,最多可邀請 5 人', - 'form.weight.label': '權重', - 'form.weight.placeholder': '請輸入', - 'form.public.label': '目標公開', - 'form.public.label.help': '客戶、邀評人默認被分享', - 'form.public.radio.public': '公開', - 'form.public.radio.partially-public': '部分公開', - 'form.public.radio.private': '不公開', - 'form.publicUsers.placeholder': '公開給', - 'form.publicUsers.option.A': '同事甲', - 'form.publicUsers.option.B': '同事乙', - 'form.publicUsers.option.C': '同事丙', -}; diff --git a/src/locales/zh-TW/globalHeader.js b/src/locales/zh-TW/globalHeader.js deleted file mode 100644 index 0ab49d62770deb384787ddcda4a677efca46d6cd..0000000000000000000000000000000000000000 --- a/src/locales/zh-TW/globalHeader.js +++ /dev/null @@ -1,18 +0,0 @@ -export default { - 'component.globalHeader.search': '站內搜索', - 'component.globalHeader.search.example1': '搜索提示壹', - 'component.globalHeader.search.example2': '搜索提示二', - 'component.globalHeader.search.example3': '搜索提示三', - 'component.globalHeader.help': '使用文檔', - 'component.globalHeader.notification': '通知', - 'component.globalHeader.notification.empty': '妳已查看所有通知', - 'component.globalHeader.message': '消息', - 'component.globalHeader.message.empty': '您已讀完所有消息', - 'component.globalHeader.event': '待辦', - 'component.globalHeader.event.empty': '妳已完成所有待辦', - 'component.noticeIcon.clear': '清空', - 'component.noticeIcon.cleared': '清空了', - 'component.noticeIcon.empty': '暫無數據', - 'component.noticeIcon.loaded': '加載完畢', - 'component.noticeIcon.loading-more': '加載更多', -}; diff --git a/src/locales/zh-TW/login.js b/src/locales/zh-TW/login.js deleted file mode 100644 index ec5706a6c26e40c5029fb80ab2390b54e483cc69..0000000000000000000000000000000000000000 --- a/src/locales/zh-TW/login.js +++ /dev/null @@ -1,38 +0,0 @@ -export default { - 'app.login.userName': '賬戶', - 'app.login.password': '密碼', - 'app.login.message-invalid-credentials': '賬戶或密碼錯誤(admin/ant.design)', - 'app.login.message-invalid-verification-code': '驗證碼錯誤', - 'app.login.tab-login-credentials': '賬戶密碼登錄', - 'app.login.tab-login-mobile': '手機號登錄', - 'app.login.remember-me': '自動登錄', - 'app.login.forgot-password': '忘記密碼', - 'app.login.sign-in-with': '其他登錄方式', - 'app.login.signup': '註冊賬戶', - 'app.login.login': '登錄', - 'app.register.register': '註冊', - 'app.register.get-verification-code': '獲取驗證碼', - 'app.register.sign-in': '使用已有賬戶登錄', - 'app.register-result.msg': '妳的賬戶:{email} 註冊成功', - 'app.register-result.activation-email': - '激活郵件已發送到妳的郵箱中,郵件有效期為24小時。請及時登錄郵箱,點擊郵件中的鏈接激活帳戶。', - 'app.register-result.back-home': '返回首頁', - 'app.register-result.view-mailbox': '查看郵箱', - 'validation.email.required': '請輸入郵箱地址!', - 'validation.email.wrong-format': '郵箱地址格式錯誤!', - 'validation.userName.required': '請輸入賬戶!', - 'validation.password.required': '請輸入密碼!', - 'validation.password.twice': '兩次輸入的密碼不匹配!', - 'validation.password.strength.msg': '請至少輸入 6 個字符。請不要使用容易被猜到的密碼。', - 'validation.password.strength.strong': '強度:強', - 'validation.password.strength.medium': '強度:中', - 'validation.password.strength.short': '強度:太短', - 'validation.confirm-password.required': '請確認密碼!', - 'validation.phone-number.required': '請輸入手機號!', - 'validation.phone-number.wrong-format': '手機號格式錯誤!', - 'validation.verification-code.required': '請輸入驗證碼!', - 'validation.title.required': '請輸入標題', - 'validation.date.required': '請選擇起止日期', - 'validation.goal.required': '請輸入目標描述', - 'validation.standard.required': '請輸入衡量標淮', -}; diff --git a/src/locales/zh-TW/menu.js b/src/locales/zh-TW/menu.js deleted file mode 100644 index 66831e0b8a3155e222b8b1124712675ae076e415..0000000000000000000000000000000000000000 --- a/src/locales/zh-TW/menu.js +++ /dev/null @@ -1,38 +0,0 @@ -export default { - 'menu.home': '首頁', - 'menu.dashboard': 'Dashboard', - 'menu.dashboard.analysis': '分析頁', - 'menu.dashboard.monitor': '監控頁', - 'menu.dashboard.workplace': '工作臺', - 'menu.form': '表單頁', - 'menu.form.basicform': '基礎表單', - 'menu.form.stepform': '分步表單', - 'menu.form.stepform.info': '分步表單(填寫轉賬信息)', - 'menu.form.stepform.confirm': '分步表單(確認轉賬信息)', - 'menu.form.stepform.result': '分步表單(完成)', - 'menu.form.advancedform': '高級表單', - 'menu.list': '列表頁', - 'menu.list.searchtable': '查詢表格', - 'menu.list.basiclist': '標淮列表', - 'menu.list.cardlist': '卡片列表', - 'menu.list.searchlist': '搜索列表', - 'menu.list.searchlist.articles': '搜索列表(文章)', - 'menu.list.searchlist.projects': '搜索列表(項目)', - 'menu.list.searchlist.applications': '搜索列表(應用)', - 'menu.profile': '詳情頁', - 'menu.profile.basic': '基礎詳情頁', - 'menu.profile.advanced': '高級詳情頁', - 'menu.result': '結果頁', - 'menu.result.success': '成功頁', - 'menu.result.fail': '失敗頁', - 'menu.account': '個人頁', - 'menu.account.center': '個人中心', - 'menu.account.settings': '個人設置', - 'menu.account.trigger': '觸發報錯', - 'menu.account.logout': '退出登錄', - 'menu.exception': '异常页', - 'menu.exception.not-permission': '403', - 'menu.exception.not-find': '404', - 'menu.exception.server-error': '500', - 'menu.exception.trigger': '触发错误', -}; diff --git a/src/locales/zh-TW/monitor.js b/src/locales/zh-TW/monitor.js deleted file mode 100644 index d19ac054d2ef12f7e9d626f98ac8c1c1bd6fde7e..0000000000000000000000000000000000000000 --- a/src/locales/zh-TW/monitor.js +++ /dev/null @@ -1,18 +0,0 @@ -export default { - 'app.monitor.trading-activity': '活動實時交易情況', - 'app.monitor.total-transactions': '今日交易總額', - 'app.monitor.sales-target': '銷售目標完成率', - 'app.monitor.remaining-time': '活動剩余時間', - 'app.monitor.total-transactions-per-second': '每秒交易總額', - 'app.monitor.activity-forecast': '活動情況預測', - 'app.monitor.efficiency': '券核效率', - 'app.monitor.ratio': '跳出率', - 'app.monitor.proportion-per-category': '各品類占比', - 'app.monitor.fast-food': '中式快餐', - 'app.monitor.western-food': '西餐', - 'app.monitor.hot-pot': '火鍋', - 'app.monitor.waiting-for-implementation': 'Waiting for implementation', - 'app.monitor.popular-searches': '熱門搜索', - 'app.monitor.resource-surplus': '資源剩余', - 'app.monitor.fund-surplus': '補貼資金剩余', -}; diff --git a/src/locales/zh-TW/pwa.js b/src/locales/zh-TW/pwa.js deleted file mode 100644 index 108a6e489be8e7567ac6d41cd7d81d7715020b3b..0000000000000000000000000000000000000000 --- a/src/locales/zh-TW/pwa.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - 'app.pwa.offline': '當前處於離線狀態', - 'app.pwa.serviceworker.updated': '有新內容', - 'app.pwa.serviceworker.updated.hint': '請點擊“刷新”按鈕或者手動刷新頁面', - 'app.pwa.serviceworker.updated.ok': '刷新', -}; diff --git a/src/locales/zh-TW/result.js b/src/locales/zh-TW/result.js deleted file mode 100644 index a87b96e5c9dc4e53737968996334c4942cb94367..0000000000000000000000000000000000000000 --- a/src/locales/zh-TW/result.js +++ /dev/null @@ -1,27 +0,0 @@ -export default { - 'app.result.error.title': '提交失敗', - 'app.result.error.description': '請核對並修改以下信息後,再重新提交。', - 'app.result.error.hint-title': '您提交的內容有如下錯誤:', - 'app.result.error.hint-text1': '您的賬戶已被凍結', - 'app.result.error.hint-btn1': '立即解凍', - 'app.result.error.hint-text2': '您的賬戶還不具備申請資格', - 'app.result.error.hint-btn2': '立即升級', - 'app.result.error.btn-text': '返回修改', - 'app.result.success.title': '提交成功', - 'app.result.success.description': - '提交結果頁用於反饋壹系列操作任務的處理結果, 如果僅是簡單操作,使用 Message 全局提示反饋即可。 本文字區域可以展示簡單的補充說明,如果有類似展示 “單據”的需求,下面這個灰色區域可以呈現比較復雜的內容。', - 'app.result.success.operate-title': '項目名稱', - 'app.result.success.operate-id': '項目 ID:', - 'app.result.success.principal': '負責人:', - 'app.result.success.operate-time': '生效時間:', - 'app.result.success.step1-title': '創建項目', - 'app.result.success.step1-operator': '曲麗麗', - 'app.result.success.step2-title': '部門初審', - 'app.result.success.step2-operator': '周毛毛', - 'app.result.success.step2-extra': '催壹下', - 'app.result.success.step3-title': '財務復核', - 'app.result.success.step4-title': '完成', - 'app.result.success.btn-return': '返回列表', - 'app.result.success.btn-project': '查看項目', - 'app.result.success.btn-print': '打印', -}; diff --git a/src/locales/zh-TW/settingDrawer.js b/src/locales/zh-TW/settingDrawer.js deleted file mode 100644 index 24dc281fa87e613c41824a78bf6561eaa0152a6d..0000000000000000000000000000000000000000 --- a/src/locales/zh-TW/settingDrawer.js +++ /dev/null @@ -1,31 +0,0 @@ -export default { - 'app.setting.pagestyle': '整體風格設置', - 'app.setting.pagestyle.dark': '暗色菜單風格', - 'app.setting.pagestyle.light': '亮色菜單風格', - 'app.setting.content-width': '內容區域寬度', - 'app.setting.content-width.fixed': '定寬', - 'app.setting.content-width.fluid': '流式', - 'app.setting.themecolor': '主題色', - 'app.setting.themecolor.dust': '薄暮', - 'app.setting.themecolor.volcano': '火山', - 'app.setting.themecolor.sunset': '日暮', - 'app.setting.themecolor.cyan': '明青', - 'app.setting.themecolor.green': '極光綠', - 'app.setting.themecolor.daybreak': '拂曉藍(默認)', - 'app.setting.themecolor.geekblue': '極客藍', - 'app.setting.themecolor.purple': '醬紫', - 'app.setting.navigationmode': '導航模式', - 'app.setting.sidemenu': '側邊菜單布局', - 'app.setting.topmenu': '頂部菜單布局', - 'app.setting.fixedheader': '固定 Header', - 'app.setting.fixedsidebar': '固定側邊菜單', - 'app.setting.fixedsidebar.hint': '側邊菜單布局時可配置', - 'app.setting.hideheader': '下滑時隱藏 Header', - 'app.setting.hideheader.hint': '固定 Header 時可配置', - 'app.setting.othersettings': '其他設置', - 'app.setting.weakmode': '色弱模式', - 'app.setting.copy': '拷貝設置', - 'app.setting.copyinfo': '拷貝成功,請到 src/defaultSettings.js 中替換默認配置', - 'app.setting.production.hint': - '配置欄只在開發環境用於預覽,生產環境不會展現,請拷貝後手動修改配置文件', -}; diff --git a/src/locales/zh-TW/settings.js b/src/locales/zh-TW/settings.js deleted file mode 100644 index 8a94de5c499e5fe32ee63c0073cecdc8c4e2bd06..0000000000000000000000000000000000000000 --- a/src/locales/zh-TW/settings.js +++ /dev/null @@ -1,55 +0,0 @@ -export default { - 'app.settings.menuMap.basic': '基本設置', - 'app.settings.menuMap.security': '安全設置', - 'app.settings.menuMap.binding': '賬號綁定', - 'app.settings.menuMap.notification': '新消息通知', - 'app.settings.basic.avatar': '頭像', - 'app.settings.basic.change-avatar': '更換頭像', - 'app.settings.basic.email': '郵箱', - 'app.settings.basic.email-message': '請輸入您的郵箱!', - 'app.settings.basic.nickname': '昵稱', - 'app.settings.basic.nickname-message': '請輸入您的昵稱!', - 'app.settings.basic.profile': '個人簡介', - 'app.settings.basic.profile-message': '請輸入個人簡介!', - 'app.settings.basic.profile-placeholder': '個人簡介', - 'app.settings.basic.country': '國家/地區', - 'app.settings.basic.country-message': '請輸入您的國家或地區!', - 'app.settings.basic.geographic': '所在省市', - 'app.settings.basic.geographic-message': '請輸入您的所在省市!', - 'app.settings.basic.address': '街道地址', - 'app.settings.basic.address-message': '請輸入您的街道地址!', - 'app.settings.basic.phone': '聯系電話', - 'app.settings.basic.phone-message': '請輸入您的聯系電話!', - 'app.settings.basic.update': '更新基本信息', - 'app.settings.security.strong': '強', - 'app.settings.security.medium': '中', - 'app.settings.security.weak': '弱', - 'app.settings.security.password': '賬戶密碼', - 'app.settings.security.password-description': '當前密碼強度:', - 'app.settings.security.phone': '密保手機', - 'app.settings.security.phone-description': '已綁定手機:', - 'app.settings.security.question': '密保問題', - 'app.settings.security.question-description': '未設置密保問題,密保問題可有效保護賬戶安全', - 'app.settings.security.email': '備用郵箱', - 'app.settings.security.email-description': '已綁定郵箱:', - 'app.settings.security.mfa': 'MFA 設備', - 'app.settings.security.mfa-description': '未綁定 MFA 設備,綁定後,可以進行二次確認', - 'app.settings.security.modify': '修改', - 'app.settings.security.set': '設置', - 'app.settings.security.bind': '綁定', - 'app.settings.binding.taobao': '綁定淘寶', - 'app.settings.binding.taobao-description': '當前未綁定淘寶賬號', - 'app.settings.binding.alipay': '綁定支付寶', - 'app.settings.binding.alipay-description': '當前未綁定支付寶賬號', - 'app.settings.binding.dingding': '綁定釘釘', - 'app.settings.binding.dingding-description': '當前未綁定釘釘賬號', - 'app.settings.binding.bind': '綁定', - 'app.settings.notification.password': '賬戶密碼', - 'app.settings.notification.password-description': '其他用戶的消息將以站內信的形式通知', - 'app.settings.notification.messages': '系統消息', - 'app.settings.notification.messages-description': '系統消息將以站內信的形式通知', - 'app.settings.notification.todo': '待辦任務', - 'app.settings.notification.todo-description': '待辦任務將以站內信的形式通知', - 'app.settings.open': '開', - 'app.settings.close': '關', -}; diff --git a/src/manifest.json b/src/manifest.json deleted file mode 100644 index 839bc5b5e4a561676fca44a61674d3990b5acd48..0000000000000000000000000000000000000000 --- a/src/manifest.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "Ant Design Pro", - "short_name": "Ant Design Pro", - "display": "standalone", - "start_url": "./?utm_source=homescreen", - "theme_color": "#002140", - "background_color": "#001529", - "icons": [ - { - "src": "icons/icon-192x192.png", - "sizes": "192x192" - }, - { - "src": "icons/icon-128x128.png", - "sizes": "128x128" - }, - { - "src": "icons/icon-512x512.png", - "sizes": "512x512" - } - ] -} diff --git a/src/models/global.js b/src/models/global.js deleted file mode 100644 index 42895b5929507c5c31609bc8ef226f25095d648a..0000000000000000000000000000000000000000 --- a/src/models/global.js +++ /dev/null @@ -1,141 +0,0 @@ -import { queryNotices } from '@/services/api'; - -export default { - namespace: 'global', - - state: { - collapsed: false, - notices: [], - loadedAllNotices: false, - }, - - effects: { - *fetchNotices(_, { call, put, select }) { - const data = yield call(queryNotices); - const loadedAllNotices = data && data.length && data[data.length - 1] === null; - yield put({ - type: 'setLoadedStatus', - payload: loadedAllNotices, - }); - yield put({ - type: 'saveNotices', - payload: data.filter(item => item), - }); - const unreadCount = yield select( - state => state.global.notices.filter(item => !item.read).length - ); - yield put({ - type: 'user/changeNotifyCount', - payload: { - totalCount: data.length, - unreadCount, - }, - }); - }, - *fetchMoreNotices({ payload }, { call, put, select }) { - const data = yield call(queryNotices, payload); - const loadedAllNotices = data && data.length && data[data.length - 1] === null; - yield put({ - type: 'setLoadedStatus', - payload: loadedAllNotices, - }); - yield put({ - type: 'pushNotices', - payload: data.filter(item => item), - }); - const unreadCount = yield select( - state => state.global.notices.filter(item => !item.read).length - ); - yield put({ - type: 'user/changeNotifyCount', - payload: { - totalCount: data.length, - unreadCount, - }, - }); - }, - *clearNotices({ payload }, { put, select }) { - yield put({ - type: 'saveClearedNotices', - payload, - }); - const count = yield select(state => state.global.notices.length); - const unreadCount = yield select( - state => state.global.notices.filter(item => !item.read).length - ); - yield put({ - type: 'user/changeNotifyCount', - payload: { - totalCount: count, - unreadCount, - }, - }); - }, - *changeNoticeReadState({ payload }, { put, select }) { - const notices = yield select(state => - state.global.notices.map(item => { - const notice = { ...item }; - if (notice.id === payload) { - notice.read = true; - } - return notice; - }) - ); - yield put({ - type: 'saveNotices', - payload: notices, - }); - yield put({ - type: 'user/changeNotifyCount', - payload: { - totalCount: notices.length, - unreadCount: notices.filter(item => !item.read).length, - }, - }); - }, - }, - - reducers: { - changeLayoutCollapsed(state, { payload }) { - return { - ...state, - collapsed: payload, - }; - }, - saveNotices(state, { payload }) { - return { - ...state, - notices: payload, - }; - }, - saveClearedNotices(state, { payload }) { - return { - ...state, - notices: state.notices.filter(item => item.type !== payload), - }; - }, - pushNotices(state, { payload }) { - return { - ...state, - notices: [...state.notices, ...payload], - }; - }, - setLoadedStatus(state, { payload }) { - return { - ...state, - loadedAllNotices: payload, - }; - }, - }, - - subscriptions: { - setup({ history }) { - // Subscribe history(url) change, trigger `load` action if pathname is `/` - return history.listen(({ pathname, search }) => { - if (typeof window.ga !== 'undefined') { - window.ga('send', 'pageview', pathname + search); - } - }); - }, - }, -}; diff --git a/src/models/menu.js b/src/models/menu.js deleted file mode 100644 index 9cc54fb5d0857d944176c86577b586a0a38b7737..0000000000000000000000000000000000000000 --- a/src/models/menu.js +++ /dev/null @@ -1,118 +0,0 @@ -import memoizeOne from 'memoize-one'; -import isEqual from 'lodash/isEqual'; -import { formatMessage } from 'umi/locale'; -import Authorized from '@/utils/Authorized'; - -const { check } = Authorized; - -// Conversion router to menu. -function formatter(data, parentAuthority, parentName) { - return data - .map(item => { - if (!item.name || !item.path) { - return null; - } - - let locale = 'menu'; - if (parentName) { - locale = `${parentName}.${item.name}`; - } else { - locale = `menu.${item.name}`; - } - - const result = { - ...item, - name: formatMessage({ id: locale, defaultMessage: item.name }), - locale, - authority: item.authority || parentAuthority, - }; - if (item.routes) { - const children = formatter(item.routes, item.authority, locale); - // Reduce memory usage - result.children = children; - } - delete result.routes; - return result; - }) - .filter(item => item); -} - -const memoizeOneFormatter = memoizeOne(formatter, isEqual); - -/** - * get SubMenu or Item - */ -const getSubMenu = item => { - // doc: add hideChildrenInMenu - if (item.children && !item.hideChildrenInMenu && item.children.some(child => child.name)) { - return { - ...item, - children: filterMenuData(item.children), // eslint-disable-line - }; - } - return item; -}; - -/** - * filter menuData - */ -const filterMenuData = menuData => { - if (!menuData) { - return []; - } - return menuData - .filter(item => item.name && !item.hideInMenu) - .map(item => check(item.authority, getSubMenu(item))) - .filter(item => item); -}; -/** - * 获取面包屑映射 - * @param {Object} menuData 菜单配置 - */ -const getBreadcrumbNameMap = menuData => { - const routerMap = {}; - - const flattenMenuData = data => { - data.forEach(menuItem => { - if (menuItem.children) { - flattenMenuData(menuItem.children); - } - // Reduce memory usage - routerMap[menuItem.path] = menuItem; - }); - }; - flattenMenuData(menuData); - return routerMap; -}; - -const memoizeOneGetBreadcrumbNameMap = memoizeOne(getBreadcrumbNameMap, isEqual); - -export default { - namespace: 'menu', - - state: { - menuData: [], - breadcrumbNameMap: {}, - }, - - effects: { - *getMenuData({ payload }, { put }) { - const { routes, authority } = payload; - const menuData = filterMenuData(memoizeOneFormatter(routes, authority)); - const breadcrumbNameMap = memoizeOneGetBreadcrumbNameMap(menuData); - yield put({ - type: 'save', - payload: { menuData, breadcrumbNameMap }, - }); - }, - }, - - reducers: { - save(state, action) { - return { - ...state, - ...action.payload, - }; - }, - }, -}; diff --git a/src/models/project.js b/src/models/project.js deleted file mode 100644 index cf894125d0bdce999f280f6263ab43532318400c..0000000000000000000000000000000000000000 --- a/src/models/project.js +++ /dev/null @@ -1,28 +0,0 @@ -import { queryProjectNotice } from '@/services/api'; - -export default { - namespace: 'project', - - state: { - notice: [], - }, - - effects: { - *fetchNotice(_, { call, put }) { - const response = yield call(queryProjectNotice); - yield put({ - type: 'saveNotice', - payload: Array.isArray(response) ? response : [], - }); - }, - }, - - reducers: { - saveNotice(state, action) { - return { - ...state, - notice: action.payload, - }; - }, - }, -}; diff --git a/src/models/setting.js b/src/models/setting.js deleted file mode 100644 index 171da48d1ef5c3068f256b02ff617dae8e4a5908..0000000000000000000000000000000000000000 --- a/src/models/setting.js +++ /dev/null @@ -1,123 +0,0 @@ -import { message } from 'antd'; -import defaultSettings from '../defaultSettings'; - -let lessNodesAppended; -const updateTheme = primaryColor => { - // Don't compile less in production! - if (APP_TYPE !== 'site') { - return; - } - // Determine if the component is remounted - if (!primaryColor) { - return; - } - const hideMessage = message.loading('正在编译主题!', 0); - function buildIt() { - if (!window.less) { - return; - } - setTimeout(() => { - window.less - .modifyVars({ - '@primary-color': primaryColor, - }) - .then(() => { - hideMessage(); - }) - .catch(() => { - message.error('Failed to update theme'); - hideMessage(); - }); - }, 200); - } - if (!lessNodesAppended) { - // insert less.js and color.less - const lessStyleNode = document.createElement('link'); - const lessConfigNode = document.createElement('script'); - const lessScriptNode = document.createElement('script'); - lessStyleNode.setAttribute('rel', 'stylesheet/less'); - lessStyleNode.setAttribute('href', '/color.less'); - lessConfigNode.innerHTML = ` - window.less = { - async: true, - env: 'production', - javascriptEnabled: true - }; - `; - lessScriptNode.src = 'https://gw.alipayobjects.com/os/lib/less.js/3.8.1/less.min.js'; - lessScriptNode.async = true; - lessScriptNode.onload = () => { - buildIt(); - lessScriptNode.onload = null; - }; - document.body.appendChild(lessStyleNode); - document.body.appendChild(lessConfigNode); - document.body.appendChild(lessScriptNode); - lessNodesAppended = true; - } else { - buildIt(); - } -}; - -const updateColorWeak = colorWeak => { - document.body.className = colorWeak ? 'colorWeak' : ''; -}; - -export default { - namespace: 'setting', - state: defaultSettings, - reducers: { - getSetting(state) { - const setting = {}; - const urlParams = new URL(window.location.href); - Object.keys(state).forEach(key => { - if (urlParams.searchParams.has(key)) { - const value = urlParams.searchParams.get(key); - setting[key] = value === '1' ? true : value; - } - }); - const { primaryColor, colorWeak } = setting; - if (state.primaryColor !== primaryColor) { - updateTheme(primaryColor); - } - updateColorWeak(colorWeak); - return { - ...state, - ...setting, - }; - }, - changeSetting(state, { payload }) { - const urlParams = new URL(window.location.href); - Object.keys(defaultSettings).forEach(key => { - if (urlParams.searchParams.has(key)) { - urlParams.searchParams.delete(key); - } - }); - Object.keys(payload).forEach(key => { - if (key === 'collapse') { - return; - } - let value = payload[key]; - if (value === true) { - value = 1; - } - if (defaultSettings[key] !== value) { - urlParams.searchParams.set(key, value); - } - }); - const { primaryColor, colorWeak, contentWidth } = payload; - if (state.primaryColor !== primaryColor) { - updateTheme(primaryColor); - } - if (state.contentWidth !== contentWidth && window.dispatchEvent) { - window.dispatchEvent(new Event('resize')); - } - updateColorWeak(colorWeak); - window.history.replaceState(null, 'setting', urlParams.href); - return { - ...state, - ...payload, - }; - }, - }, -}; diff --git a/src/pages/404.js b/src/pages/404.js deleted file mode 100644 index 34921c02b789dff7b692f12d6b1ceb9a562ce372..0000000000000000000000000000000000000000 --- a/src/pages/404.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import Link from 'umi/link'; -import { formatMessage } from 'umi/locale'; -import Exception from '@/components/Exception'; - -export default () => ( - -); diff --git a/src/pages/Account/Center/Applications.js b/src/pages/Account/Center/Applications.js deleted file mode 100644 index 031686cd1148c48d8444eec9573776d5185950d3..0000000000000000000000000000000000000000 --- a/src/pages/Account/Center/Applications.js +++ /dev/null @@ -1,88 +0,0 @@ -import React, { PureComponent } from 'react'; -import { List, Card, Icon, Dropdown, Menu, Avatar, Tooltip } from 'antd'; -import numeral from 'numeral'; -import { connect } from 'dva'; -import { formatWan } from '@/utils/utils'; -import stylesApplications from '../../List/Applications.less'; - -@connect(({ list }) => ({ - list, -})) -class Center extends PureComponent { - render() { - const { - list: { list }, - } = this.props; - const itemMenu = ( - - - - 1st menu item - - - - - 2nd menu item - - - - - 3d menu item - - - - ); - const CardInfo = ({ activeUser, newUser }) => ( - - - 活跃用户 - {activeUser} - - - 新增用户 - {newUser} - - - ); - return ( - ( - - - - , - - - , - - - , - - - , - ]} - > - } title={item.title} /> - - - - - - )} - /> - ); - } -} - -export default Center; diff --git a/src/pages/Account/Center/Articles.js b/src/pages/Account/Center/Articles.js deleted file mode 100644 index 9bb5ac309ef1180b5ed7bf53c32720545dc6386a..0000000000000000000000000000000000000000 --- a/src/pages/Account/Center/Articles.js +++ /dev/null @@ -1,59 +0,0 @@ -import React, { PureComponent } from 'react'; -import { List, Icon, Tag } from 'antd'; -import { connect } from 'dva'; -import ArticleListContent from '@/components/ArticleListContent'; -import styles from './Articles.less'; - -@connect(({ list }) => ({ - list, -})) -class Center extends PureComponent { - render() { - const { - list: { list }, - } = this.props; - const IconText = ({ type, text }) => ( - - - {text} - - ); - return ( - ( - , - , - , - ]} - > - - {item.title} - - } - description={ - - Ant Design - 设计语言 - 蚂蚁金服 - - } - /> - - - )} - /> - ); - } -} - -export default Center; diff --git a/src/pages/Account/Center/Articles.less b/src/pages/Account/Center/Articles.less deleted file mode 100644 index 2e51509ba7debe11d9da0981b633d3ffe4b90d20..0000000000000000000000000000000000000000 --- a/src/pages/Account/Center/Articles.less +++ /dev/null @@ -1,12 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.articleList { - :global { - .ant-list-item:first-child { - padding-top: 0; - } - } -} -a.listItemMetaTitle { - color: @heading-color; -} diff --git a/src/pages/Account/Center/Center.js b/src/pages/Account/Center/Center.js deleted file mode 100644 index d2512f95bc430cfbb2bff8f60db89391e21be1f3..0000000000000000000000000000000000000000 --- a/src/pages/Account/Center/Center.js +++ /dev/null @@ -1,216 +0,0 @@ -import React, { PureComponent } from 'react'; -import { connect } from 'dva'; -import Link from 'umi/link'; -import router from 'umi/router'; -import { Card, Row, Col, Icon, Avatar, Tag, Divider, Spin, Input } from 'antd'; -import GridContent from '@/components/PageHeaderWrapper/GridContent'; -import styles from './Center.less'; - -@connect(({ loading, user, project }) => ({ - listLoading: loading.effects['list/fetch'], - currentUser: user.currentUser, - currentUserLoading: loading.effects['user/fetchCurrent'], - project, - projectLoading: loading.effects['project/fetchNotice'], -})) -class Center extends PureComponent { - state = { - newTags: [], - inputVisible: false, - inputValue: '', - }; - - componentDidMount() { - const { dispatch } = this.props; - dispatch({ - type: 'user/fetchCurrent', - }); - dispatch({ - type: 'list/fetch', - payload: { - count: 8, - }, - }); - dispatch({ - type: 'project/fetchNotice', - }); - } - - onTabChange = key => { - const { match } = this.props; - switch (key) { - case 'articles': - router.push(`${match.url}/articles`); - break; - case 'applications': - router.push(`${match.url}/applications`); - break; - case 'projects': - router.push(`${match.url}/projects`); - break; - default: - break; - } - }; - - showInput = () => { - this.setState({ inputVisible: true }, () => this.input.focus()); - }; - - saveInputRef = input => { - this.input = input; - }; - - handleInputChange = e => { - this.setState({ inputValue: e.target.value }); - }; - - handleInputConfirm = () => { - const { state } = this; - const { inputValue } = state; - let { newTags } = state; - if (inputValue && newTags.filter(tag => tag.label === inputValue).length === 0) { - newTags = [...newTags, { key: `new-${newTags.length}`, label: inputValue }]; - } - this.setState({ - newTags, - inputVisible: false, - inputValue: '', - }); - }; - - render() { - const { newTags, inputVisible, inputValue } = this.state; - const { - listLoading, - currentUser, - currentUserLoading, - project: { notice }, - projectLoading, - match, - location, - children, - } = this.props; - - const operationTabList = [ - { - key: 'articles', - tab: ( - - 文章 (8) - - ), - }, - { - key: 'applications', - tab: ( - - 应用 (8) - - ), - }, - { - key: 'projects', - tab: ( - - 项目 (8) - - ), - }, - ]; - - return ( - - - - - {currentUser && Object.keys(currentUser).length ? ( - - - - {currentUser.name} - {currentUser.signature} - - - - - {currentUser.title} - - - - {currentUser.group} - - - - {currentUser.geographic.province.label} - {currentUser.geographic.city.label} - - - - - 标签 - {currentUser.tags.concat(newTags).map(item => ( - {item.label} - ))} - {inputVisible && ( - - )} - {!inputVisible && ( - - - - )} - - - - 团队 - - - {notice.map(item => ( - - - - {item.member} - - - ))} - - - - - ) : ( - 'loading...' - )} - - - - - {children} - - - - - ); - } -} - -export default Center; diff --git a/src/pages/Account/Center/Projects.js b/src/pages/Account/Center/Projects.js deleted file mode 100644 index ac749fdb58a75ab9003660444bcc191a1f83fcda..0000000000000000000000000000000000000000 --- a/src/pages/Account/Center/Projects.js +++ /dev/null @@ -1,52 +0,0 @@ -import React, { PureComponent } from 'react'; -import { List, Card } from 'antd'; -import moment from 'moment'; -import { connect } from 'dva'; -import AvatarList from '@/components/AvatarList'; -import stylesProjects from '../../List/Projects.less'; - -@connect(({ list }) => ({ - list, -})) -class Center extends PureComponent { - render() { - const { - list: { list }, - } = this.props; - return ( - ( - - } - > - {item.title}} description={item.subDescription} /> - - {moment(item.updatedAt).fromNow()} - - - {item.members.map(member => ( - - ))} - - - - - - )} - /> - ); - } -} - -export default Center; diff --git a/src/pages/Account/Settings/Info.js b/src/pages/Account/Settings/Info.js deleted file mode 100644 index ceee506b8bc5c5569d838f95f1d9cb051dbd2f26..0000000000000000000000000000000000000000 --- a/src/pages/Account/Settings/Info.js +++ /dev/null @@ -1,125 +0,0 @@ -import React, { Component } from 'react'; -import { connect } from 'dva'; -import router from 'umi/router'; -import { FormattedMessage } from 'umi/locale'; -import { Menu } from 'antd'; -import GridContent from '@/components/PageHeaderWrapper/GridContent'; -import styles from './Info.less'; - -const { Item } = Menu; - -@connect(({ user }) => ({ - currentUser: user.currentUser, -})) -class Info extends Component { - constructor(props) { - super(props); - const { match, location } = props; - const menuMap = { - base: , - security: ( - - ), - binding: ( - - ), - notification: ( - - ), - }; - const key = location.pathname.replace(`${match.path}/`, ''); - this.state = { - mode: 'inline', - menuMap, - selectKey: menuMap[key] ? key : 'base', - }; - } - - static getDerivedStateFromProps(props, state) { - const { match, location } = props; - let selectKey = location.pathname.replace(`${match.path}/`, ''); - selectKey = state.menuMap[selectKey] ? selectKey : 'base'; - if (selectKey !== state.selectKey) { - return { selectKey }; - } - return null; - } - - componentDidMount() { - window.addEventListener('resize', this.resize); - this.resize(); - } - - componentWillUnmount() { - window.removeEventListener('resize', this.resize); - } - - getmenu = () => { - const { menuMap } = this.state; - return Object.keys(menuMap).map(item => {menuMap[item]}); - }; - - getRightTitle = () => { - const { selectKey, menuMap } = this.state; - return menuMap[selectKey]; - }; - - selectKey = ({ key }) => { - router.push(`/account/settings/${key}`); - this.setState({ - selectKey: key, - }); - }; - - resize = () => { - if (!this.main) { - return; - } - requestAnimationFrame(() => { - let mode = 'inline'; - const { offsetWidth } = this.main; - if (this.main.offsetWidth < 641 && offsetWidth > 400) { - mode = 'horizontal'; - } - if (window.innerWidth < 768 && offsetWidth > 400) { - mode = 'horizontal'; - } - this.setState({ - mode, - }); - }); - }; - - render() { - const { children, currentUser } = this.props; - if (!currentUser.userid) { - return ''; - } - const { mode, selectKey } = this.state; - return ( - - { - this.main = ref; - }} - > - - - {this.getmenu()} - - - - {this.getRightTitle()} - {children} - - - - ); - } -} - -export default Info; diff --git a/src/pages/Authorized.js b/src/pages/Authorized.js deleted file mode 100644 index c29d9610e7b2873c8ca5e0085a865cfc6ab9ffb0..0000000000000000000000000000000000000000 --- a/src/pages/Authorized.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import RenderAuthorized from '@/components/Authorized'; -import { getAuthority } from '@/utils/authority'; -import Redirect from 'umi/redirect'; - -const Authority = getAuthority(); -const Authorized = RenderAuthorized(Authority); - -export default ({ children }) => ( - }> - {children} - -); diff --git a/src/pages/Dashboard/ProportionSales.js b/src/pages/Dashboard/ProportionSales.js deleted file mode 100755 index ff16a7d231751d8311b76078df1f182dbfcce34d..0000000000000000000000000000000000000000 --- a/src/pages/Dashboard/ProportionSales.js +++ /dev/null @@ -1,58 +0,0 @@ -import React, { memo } from 'react'; -import { Card, Radio } from 'antd'; -import { FormattedMessage } from 'umi/locale'; -import styles from './Analysis.less'; -import { Pie } from '@/components/Charts'; -import Yuan from '@/utils/Yuan'; - -const ProportionSales = memo( - ({ dropdownGroup, salesType, loading, salesPieData, handleChangeSalesType }) => ( - - } - bodyStyle={{ padding: 24 }} - extra={ - - {dropdownGroup} - - - - - - - - - - - - - - - } - style={{ marginTop: 24 }} - > - - - - } - total={() => {salesPieData.reduce((pre, now) => now.y + pre, 0)}} - data={salesPieData} - valueFormat={value => {value}} - height={270} - lineWidth={4} - style={{ padding: '8px 0' }} - /> - - ) -); - -export default ProportionSales; diff --git a/src/pages/Exception/403.js b/src/pages/Exception/403.js deleted file mode 100644 index 35e4ca3a12f36701d7120cd2d840c44ebca1b5dc..0000000000000000000000000000000000000000 --- a/src/pages/Exception/403.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; -import { formatMessage } from 'umi/locale'; -import Link from 'umi/link'; -import Exception from '@/components/Exception'; - -const Exception403 = () => ( - -); - -export default Exception403; diff --git a/src/pages/Exception/404.js b/src/pages/Exception/404.js deleted file mode 100644 index 84c986c5e577a141ccc675ce49dd3b9b4399a519..0000000000000000000000000000000000000000 --- a/src/pages/Exception/404.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; -import { formatMessage } from 'umi/locale'; -import Link from 'umi/link'; -import Exception from '@/components/Exception'; - -const Exception404 = () => ( - -); - -export default Exception404; diff --git a/src/pages/Exception/500.js b/src/pages/Exception/500.js deleted file mode 100644 index 9d96f21203ef5466593a674b4b6da89bd6dde39f..0000000000000000000000000000000000000000 --- a/src/pages/Exception/500.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; -import { formatMessage } from 'umi/locale'; -import Link from 'umi/link'; -import Exception from '@/components/Exception'; - -const Exception500 = () => ( - -); - -export default Exception500; diff --git a/src/pages/Exception/TriggerException.js b/src/pages/Exception/TriggerException.js deleted file mode 100644 index 15ace510f674c22a9ab0b35cc624f53ce0ff676b..0000000000000000000000000000000000000000 --- a/src/pages/Exception/TriggerException.js +++ /dev/null @@ -1,50 +0,0 @@ -import React, { PureComponent } from 'react'; -import { Button, Spin, Card } from 'antd'; -import { connect } from 'dva'; -import styles from './style.less'; - -@connect(state => ({ - isloading: state.error.isloading, -})) -class TriggerException extends PureComponent { - state = { - isloading: false, - }; - - triggerError = code => { - this.setState({ - isloading: true, - }); - const { dispatch } = this.props; - dispatch({ - type: 'error/query', - payload: { - code, - }, - }); - }; - - render() { - const { isloading } = this.state; - return ( - - - this.triggerError(401)}> - 触发401 - - this.triggerError(403)}> - 触发403 - - this.triggerError(500)}> - 触发500 - - this.triggerError(404)}> - 触发404 - - - - ); - } -} - -export default TriggerException; diff --git a/src/pages/Exception/models/error.js b/src/pages/Exception/models/error.js deleted file mode 100644 index 1bfd9392139bb91e8a986b0c5878f6cea5d9c45f..0000000000000000000000000000000000000000 --- a/src/pages/Exception/models/error.js +++ /dev/null @@ -1,28 +0,0 @@ -import queryError from '@/services/error'; - -export default { - namespace: 'error', - - state: { - error: '', - isloading: false, - }, - - effects: { - *query({ payload }, { call, put }) { - yield call(queryError, payload.code); - yield put({ - type: 'trigger', - payload: payload.code, - }); - }, - }, - - reducers: { - trigger(state, action) { - return { - error: action.payload, - }; - }, - }, -}; diff --git a/src/pages/Exception/style.less b/src/pages/Exception/style.less deleted file mode 100644 index 91ec7dcf525f63df9853a9a005dcc476bc7318a3..0000000000000000000000000000000000000000 --- a/src/pages/Exception/style.less +++ /dev/null @@ -1,7 +0,0 @@ -.trigger { - background: 'red'; - :global(.ant-btn) { - margin-right: 8px; - margin-bottom: 12px; - } -} diff --git a/src/pages/Forms/StepForm/index.js b/src/pages/Forms/StepForm/index.js deleted file mode 100644 index 98902a0aa4cf63b7207060a2ea62f6680029b994..0000000000000000000000000000000000000000 --- a/src/pages/Forms/StepForm/index.js +++ /dev/null @@ -1,46 +0,0 @@ -import React, { PureComponent, Fragment } from 'react'; -import { Card, Steps } from 'antd'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; -import styles from '../style.less'; - -const { Step } = Steps; - -export default class StepForm extends PureComponent { - getCurrentStep() { - const { location } = this.props; - const { pathname } = location; - const pathList = pathname.split('/'); - switch (pathList[pathList.length - 1]) { - case 'info': - return 0; - case 'confirm': - return 1; - case 'result': - return 2; - default: - return 0; - } - } - - render() { - const { location, children } = this.props; - return ( - - - - - - - - - {children} - - - - ); - } -} diff --git a/src/pages/List/Applications.js b/src/pages/List/Applications.js deleted file mode 100644 index 4f32f8e6637683959f93c6d97d14c849d9d71207..0000000000000000000000000000000000000000 --- a/src/pages/List/Applications.js +++ /dev/null @@ -1,183 +0,0 @@ -import React, { PureComponent } from 'react'; -import numeral from 'numeral'; -import { connect } from 'dva'; -import { Row, Col, Form, Card, Select, Icon, Avatar, List, Tooltip, Dropdown, Menu } from 'antd'; -import TagSelect from '@/components/TagSelect'; -import StandardFormRow from '@/components/StandardFormRow'; - -import { formatWan } from '@/utils/utils'; - -import styles from './Applications.less'; - -const { Option } = Select; -const FormItem = Form.Item; - -@connect(({ list, loading }) => ({ - list, - loading: loading.models.list, -})) -@Form.create({ - onValuesChange({ dispatch }, changedValues, allValues) { - // 表单项变化时请求数据 - // eslint-disable-next-line - console.log(changedValues, allValues); - // 模拟查询表单生效 - dispatch({ - type: 'list/fetch', - payload: { - count: 8, - }, - }); - }, -}) -class FilterCardList extends PureComponent { - componentDidMount() { - const { dispatch } = this.props; - dispatch({ - type: 'list/fetch', - payload: { - count: 8, - }, - }); - } - - render() { - const { - list: { list }, - loading, - form, - } = this.props; - const { getFieldDecorator } = form; - - const CardInfo = ({ activeUser, newUser }) => ( - - - 活跃用户 - {activeUser} - - - 新增用户 - {newUser} - - - ); - - const formItemLayout = { - wrapperCol: { - xs: { span: 24 }, - sm: { span: 16 }, - }, - }; - - const itemMenu = ( - - - - 1st menu item - - - - - 2nd menu item - - - - - 3d menu item - - - - ); - - return ( - - - - - - {getFieldDecorator('category')( - - 类目一 - 类目二 - 类目三 - 类目四 - 类目五 - 类目六 - 类目七 - 类目八 - 类目九 - 类目十 - 类目十一 - 类目十二 - - )} - - - - - - - {getFieldDecorator('author', {})( - - 王昭君 - - )} - - - - - {getFieldDecorator('rate', {})( - - 优秀 - 普通 - - )} - - - - - - - ( - - - - , - - - , - - - , - - - , - ]} - > - } title={item.title} /> - - - - - - )} - /> - - ); - } -} - -export default FilterCardList; diff --git a/src/pages/List/List.js b/src/pages/List/List.js deleted file mode 100644 index d420af59222ab79c24ae894225b6d08437cf095a..0000000000000000000000000000000000000000 --- a/src/pages/List/List.js +++ /dev/null @@ -1,80 +0,0 @@ -import React, { Component } from 'react'; -import router from 'umi/router'; -import { connect } from 'dva'; -import { Input } from 'antd'; -import PageHeaderWrapper from '@/components/PageHeaderWrapper'; - -@connect() -class SearchList extends Component { - handleTabChange = key => { - const { match } = this.props; - switch (key) { - case 'articles': - router.push(`${match.url}/articles`); - break; - case 'applications': - router.push(`${match.url}/applications`); - break; - case 'projects': - router.push(`${match.url}/projects`); - break; - default: - break; - } - }; - - handleFormSubmit = value => { - // eslint-disable-next-line - console.log(value); - }; - - render() { - const tabList = [ - { - key: 'articles', - tab: '文章', - }, - { - key: 'projects', - tab: '项目', - }, - { - key: 'applications', - tab: '应用', - }, - ]; - - const mainSearch = ( - - - - ); - - const { match, children, location } = this.props; - - return ( - - {children} - {/* - {routes.map(item => ( - - ))} - */} - - ); - } -} - -export default SearchList; diff --git a/src/pages/List/Projects.js b/src/pages/List/Projects.js deleted file mode 100644 index 430ca4201803d71f85fb84a98b2ca3fa4bdac9c2..0000000000000000000000000000000000000000 --- a/src/pages/List/Projects.js +++ /dev/null @@ -1,154 +0,0 @@ -import React, { PureComponent } from 'react'; -import moment from 'moment'; -import { connect } from 'dva'; -import { Row, Col, Form, Card, Select, List } from 'antd'; - -import TagSelect from '@/components/TagSelect'; -import AvatarList from '@/components/AvatarList'; -import Ellipsis from '@/components/Ellipsis'; -import StandardFormRow from '@/components/StandardFormRow'; - -import styles from './Projects.less'; - -const { Option } = Select; -const FormItem = Form.Item; - -/* eslint react/no-array-index-key: 0 */ - -@connect(({ list, loading }) => ({ - list, - loading: loading.models.list, -})) -@Form.create({ - onValuesChange({ dispatch }, changedValues, allValues) { - // 表单项变化时请求数据 - // eslint-disable-next-line - console.log(changedValues, allValues); - // 模拟查询表单生效 - dispatch({ - type: 'list/fetch', - payload: { - count: 8, - }, - }); - }, -}) -class CoverCardList extends PureComponent { - componentDidMount() { - const { dispatch } = this.props; - dispatch({ - type: 'list/fetch', - payload: { - count: 8, - }, - }); - } - - render() { - const { - list: { list = [] }, - loading, - form, - } = this.props; - const { getFieldDecorator } = form; - - const cardList = list ? ( - ( - - } - > - {item.title}} - description={{item.subDescription}} - /> - - {moment(item.updatedAt).fromNow()} - - - {item.members.map((member, i) => ( - - ))} - - - - - - )} - /> - ) : null; - - const formItemLayout = { - wrapperCol: { - xs: { span: 24 }, - sm: { span: 16 }, - }, - }; - - return ( - - - - - - {getFieldDecorator('category')( - - 类目一 - 类目二 - 类目三 - 类目四 - 类目五 - 类目六 - 类目七 - 类目八 - 类目九 - 类目十 - 类目十一 - 类目十二 - - )} - - - - - - - {getFieldDecorator('author', {})( - - 王昭君 - - )} - - - - - {getFieldDecorator('rate', {})( - - 优秀 - 普通 - - )} - - - - - - - {cardList} - - ); - } -} - -export default CoverCardList; diff --git a/src/pages/Result/Success.test.js b/src/pages/Result/Success.test.js deleted file mode 100644 index 9bc9b8dffdc39e5db8dbfd5b2c9e5203a4845e26..0000000000000000000000000000000000000000 --- a/src/pages/Result/Success.test.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import { shallow } from 'enzyme'; -import Success from './Success'; - -it('renders with Result', () => { - const wrapper = shallow(); - expect(wrapper.find('Result').length).toBe(1); - expect(wrapper.find('Result').prop('type')).toBe('success'); -}); diff --git a/src/pages/document.ejs b/src/pages/document.ejs deleted file mode 100644 index eca451ca42a17566771387c377ab1e4cc99d1aec..0000000000000000000000000000000000000000 --- a/src/pages/document.ejs +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - Ant Design Pro - - - - - Sorry, we need js to run correctly! - - - diff --git a/src/service-worker.js b/src/service-worker.js deleted file mode 100644 index 48d43c2545b6bd9e92ba6fce550dfbccbc3615f3..0000000000000000000000000000000000000000 --- a/src/service-worker.js +++ /dev/null @@ -1,65 +0,0 @@ -/* globals workbox */ -/* eslint-disable no-restricted-globals */ -workbox.core.setCacheNameDetails({ - prefix: 'antd-pro', - suffix: 'v1', -}); -// Control all opened tabs ASAP -workbox.clientsClaim(); - -/** - * Use precaching list generated by workbox in build process. - * https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.precaching - */ -/* eslint-disable no-underscore-dangle */ -workbox.precaching.precacheAndRoute(self.__precacheManifest || []); - -/** - * Register a navigation route. - * https://developers.google.com/web/tools/workbox/modules/workbox-routing#how_to_register_a_navigation_route - */ -workbox.routing.registerNavigationRoute('/index.html'); - -/** - * Use runtime cache: - * https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.routing#.registerRoute - * - * Workbox provides all common caching strategies including CacheFirst, NetworkFirst etc. - * https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.strategies - */ - -/** - * Handle API requests - */ -workbox.routing.registerRoute(/\/api\//, workbox.strategies.networkFirst()); - -/** - * Handle third party requests - */ -workbox.routing.registerRoute( - /^https:\/\/gw.alipayobjects.com\//, - workbox.strategies.networkFirst() -); -workbox.routing.registerRoute( - /^https:\/\/cdnjs.cloudflare.com\//, - workbox.strategies.networkFirst() -); -workbox.routing.registerRoute(/\/color.less/, workbox.strategies.networkFirst()); - -/** - * Response to client after skipping waiting with MessageChannel - */ -addEventListener('message', event => { - const replyPort = event.ports[0]; - const message = event.data; - if (replyPort && message && message.type === 'skip-waiting') { - event.waitUntil( - self - .skipWaiting() - .then( - () => replyPort.postMessage({ error: null }), - error => replyPort.postMessage({ error }) - ) - ); - } -}); diff --git a/src/services/api.js b/src/services/api.js deleted file mode 100644 index f79cefffb2981a3879608e66eb0a27cea1dd9f58..0000000000000000000000000000000000000000 --- a/src/services/api.js +++ /dev/null @@ -1,126 +0,0 @@ -import { stringify } from 'qs'; -import request from '@/utils/request'; - -export async function queryProjectNotice() { - return request('/api/project/notice'); -} - -export async function queryActivities() { - return request('/api/activities'); -} - -export async function queryRule(params) { - return request(`/api/rule?${stringify(params)}`); -} - -export async function removeRule(params) { - return request('/api/rule', { - method: 'POST', - body: { - ...params, - method: 'delete', - }, - }); -} - -export async function addRule(params) { - return request('/api/rule', { - method: 'POST', - body: { - ...params, - method: 'post', - }, - }); -} - -export async function updateRule(params = {}) { - return request(`/api/rule?${stringify(params.query)}`, { - method: 'POST', - body: { - ...params.body, - method: 'update', - }, - }); -} - -export async function fakeSubmitForm(params) { - return request('/api/forms', { - method: 'POST', - body: params, - }); -} - -export async function fakeChartData() { - return request('/api/fake_chart_data'); -} - -export async function queryTags() { - return request('/api/tags'); -} - -export async function queryBasicProfile() { - return request('/api/profile/basic'); -} - -export async function queryAdvancedProfile() { - return request('/api/profile/advanced'); -} - -export async function queryFakeList(params) { - return request(`/api/fake_list?${stringify(params)}`); -} - -export async function removeFakeList(params) { - const { count = 5, ...restParams } = params; - return request(`/api/fake_list?count=${count}`, { - method: 'POST', - body: { - ...restParams, - method: 'delete', - }, - }); -} - -export async function addFakeList(params) { - const { count = 5, ...restParams } = params; - return request(`/api/fake_list?count=${count}`, { - method: 'POST', - body: { - ...restParams, - method: 'post', - }, - }); -} - -export async function updateFakeList(params) { - const { count = 5, ...restParams } = params; - return request(`/api/fake_list?count=${count}`, { - method: 'POST', - body: { - ...restParams, - method: 'update', - }, - }); -} - -export async function fakeAccountLogin(params) { - return request('/api/login/account', { - method: 'POST', - body: params, - }); -} - -export async function fakeRegister(params) { - return request('/api/register', { - method: 'POST', - body: params, - }); -} - -export async function queryNotices(params = {}) { - return request(`/api/notices?${stringify(params)}`); -} - -export async function getFakeCaptcha(mobile) { - return request(`/api/captcha?mobile=${mobile}`); -} diff --git a/src/services/error.js b/src/services/error.js deleted file mode 100644 index 13f2e942c23377dad424424c0bbce1ebef6871cd..0000000000000000000000000000000000000000 --- a/src/services/error.js +++ /dev/null @@ -1,5 +0,0 @@ -import request from '@/utils/request'; - -export default async function queryError(code) { - return request(`/api/${code}`); -} diff --git a/src/services/geographic.js b/src/services/geographic.js deleted file mode 100644 index a5defd87b941d2c2057050a920f7040ef79a05cc..0000000000000000000000000000000000000000 --- a/src/services/geographic.js +++ /dev/null @@ -1,9 +0,0 @@ -import request from '@/utils/request'; - -export async function queryProvince() { - return request('/api/geographic/province'); -} - -export async function queryCity(province) { - return request(`/api/geographic/city/${province}`); -} diff --git a/src/services/user.js b/src/services/user.js deleted file mode 100644 index 89e03c6f67b2ba505e429b2c9afbcb40142508aa..0000000000000000000000000000000000000000 --- a/src/services/user.js +++ /dev/null @@ -1,9 +0,0 @@ -import request from '@/utils/request'; - -export async function query() { - return request('/api/users'); -} - -export async function queryCurrent() { - return request('/api/currentUser'); -} diff --git a/src/utils/authority.test.js b/src/utils/authority.test.js deleted file mode 100644 index 8a6cd41f37f9c797adaef9304f87fe3afd279123..0000000000000000000000000000000000000000 --- a/src/utils/authority.test.js +++ /dev/null @@ -1,19 +0,0 @@ -import { getAuthority } from './authority'; - -describe('getAuthority should be strong', () => { - it('empty', () => { - expect(getAuthority(null)).toEqual(['admin']); // default value - }); - it('string', () => { - expect(getAuthority('admin')).toEqual(['admin']); - }); - it('array with double quotes', () => { - expect(getAuthority('"admin"')).toEqual(['admin']); - }); - it('array with single item', () => { - expect(getAuthority('["admin"]')).toEqual(['admin']); - }); - it('array with multiple items', () => { - expect(getAuthority('["admin", "guest"]')).toEqual(['admin', 'guest']); - }); -}); diff --git a/src/utils/request.js b/src/utils/request.js deleted file mode 100644 index 398b787f1e5d8cd3381c8fbd9201dd33544ac9d5..0000000000000000000000000000000000000000 --- a/src/utils/request.js +++ /dev/null @@ -1,155 +0,0 @@ -import fetch from 'dva/fetch'; -import { notification } from 'antd'; -import router from 'umi/router'; -import hash from 'hash.js'; -import { isAntdPro } from './utils'; - -const codeMessage = { - 200: '服务器成功返回请求的数据。', - 201: '新建或修改数据成功。', - 202: '一个请求已经进入后台排队(异步任务)。', - 204: '删除数据成功。', - 400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。', - 401: '用户没有权限(令牌、用户名、密码错误)。', - 403: '用户得到授权,但是访问是被禁止的。', - 404: '发出的请求针对的是不存在的记录,服务器没有进行操作。', - 406: '请求的格式不可得。', - 410: '请求的资源被永久删除,且不会再得到的。', - 422: '当创建一个对象时,发生一个验证错误。', - 500: '服务器发生错误,请检查服务器。', - 502: '网关错误。', - 503: '服务不可用,服务器暂时过载或维护。', - 504: '网关超时。', -}; - -const checkStatus = response => { - if (response.status >= 200 && response.status < 300) { - return response; - } - const errortext = codeMessage[response.status] || response.statusText; - notification.error({ - message: `请求错误 ${response.status}: ${response.url}`, - description: errortext, - }); - const error = new Error(errortext); - error.name = response.status; - error.response = response; - throw error; -}; - -const cachedSave = (response, hashcode) => { - /** - * Clone a response data and store it in sessionStorage - * Does not support data other than json, Cache only json - */ - const contentType = response.headers.get('Content-Type'); - if (contentType && contentType.match(/application\/json/i)) { - // All data is saved as text - response - .clone() - .text() - .then(content => { - sessionStorage.setItem(hashcode, content); - sessionStorage.setItem(`${hashcode}:timestamp`, Date.now()); - }); - } - return response; -}; - -/** - * Requests a URL, returning a promise. - * - * @param {string} url The URL we want to request - * @param {object} [option] The options we want to pass to "fetch" - * @return {object} An object containing either "data" or "err" - */ -export default function request(url, option) { - const options = { - expirys: isAntdPro(), - ...option, - }; - /** - * Produce fingerprints based on url and parameters - * Maybe url has the same parameters - */ - const fingerprint = url + (options.body ? JSON.stringify(options.body) : ''); - const hashcode = hash - .sha256() - .update(fingerprint) - .digest('hex'); - - const defaultOptions = { - credentials: 'include', - }; - const newOptions = { ...defaultOptions, ...options }; - if ( - newOptions.method === 'POST' || - newOptions.method === 'PUT' || - newOptions.method === 'DELETE' - ) { - if (!(newOptions.body instanceof FormData)) { - newOptions.headers = { - Accept: 'application/json', - 'Content-Type': 'application/json; charset=utf-8', - ...newOptions.headers, - }; - newOptions.body = JSON.stringify(newOptions.body); - } else { - // newOptions.body is FormData - newOptions.headers = { - Accept: 'application/json', - ...newOptions.headers, - }; - } - } - - const expirys = options.expirys && 60; - // options.expirys !== false, return the cache, - if (options.expirys !== false) { - const cached = sessionStorage.getItem(hashcode); - const whenCached = sessionStorage.getItem(`${hashcode}:timestamp`); - if (cached !== null && whenCached !== null) { - const age = (Date.now() - whenCached) / 1000; - if (age < expirys) { - const response = new Response(new Blob([cached])); - return response.json(); - } - sessionStorage.removeItem(hashcode); - sessionStorage.removeItem(`${hashcode}:timestamp`); - } - } - return fetch(url, newOptions) - .then(checkStatus) - .then(response => cachedSave(response, hashcode)) - .then(response => { - // DELETE and 204 do not return data by default - // using .json will report an error. - if (newOptions.method === 'DELETE' || response.status === 204) { - return response.text(); - } - return response.json(); - }) - .catch(e => { - const status = e.name; - if (status === 401) { - // @HACK - /* eslint-disable no-underscore-dangle */ - window.g_app._store.dispatch({ - type: 'login/logout', - }); - return; - } - // environment should not be used - if (status === 403) { - router.push('/exception/403'); - return; - } - if (status <= 504 && status >= 500) { - router.push('/exception/500'); - return; - } - if (status >= 404 && status < 422) { - router.push('/exception/404'); - } - }); -} diff --git a/src/utils/utils.js b/src/utils/utils.js deleted file mode 100644 index d8d1739f9f8a95ee70b9ab58279ec167852954df..0000000000000000000000000000000000000000 --- a/src/utils/utils.js +++ /dev/null @@ -1,183 +0,0 @@ -import moment from 'moment'; -import React from 'react'; -import nzh from 'nzh/cn'; -import { parse, stringify } from 'qs'; - -export function fixedZero(val) { - return val * 1 < 10 ? `0${val}` : val; -} - -export function getTimeDistance(type) { - const now = new Date(); - const oneDay = 1000 * 60 * 60 * 24; - - if (type === 'today') { - now.setHours(0); - now.setMinutes(0); - now.setSeconds(0); - return [moment(now), moment(now.getTime() + (oneDay - 1000))]; - } - - if (type === 'week') { - let day = now.getDay(); - now.setHours(0); - now.setMinutes(0); - now.setSeconds(0); - - if (day === 0) { - day = 6; - } else { - day -= 1; - } - - const beginTime = now.getTime() - day * oneDay; - - return [moment(beginTime), moment(beginTime + (7 * oneDay - 1000))]; - } - - if (type === 'month') { - const year = now.getFullYear(); - const month = now.getMonth(); - const nextDate = moment(now).add(1, 'months'); - const nextYear = nextDate.year(); - const nextMonth = nextDate.month(); - - return [ - moment(`${year}-${fixedZero(month + 1)}-01 00:00:00`), - moment(moment(`${nextYear}-${fixedZero(nextMonth + 1)}-01 00:00:00`).valueOf() - 1000), - ]; - } - - const year = now.getFullYear(); - return [moment(`${year}-01-01 00:00:00`), moment(`${year}-12-31 23:59:59`)]; -} - -export function getPlainNode(nodeList, parentPath = '') { - const arr = []; - nodeList.forEach(node => { - const item = node; - item.path = `${parentPath}/${item.path || ''}`.replace(/\/+/g, '/'); - item.exact = true; - if (item.children && !item.component) { - arr.push(...getPlainNode(item.children, item.path)); - } else { - if (item.children && item.component) { - item.exact = false; - } - arr.push(item); - } - }); - return arr; -} - -export function digitUppercase(n) { - return nzh.toMoney(n); -} - -function getRelation(str1, str2) { - if (str1 === str2) { - console.warn('Two path are equal!'); // eslint-disable-line - } - const arr1 = str1.split('/'); - const arr2 = str2.split('/'); - if (arr2.every((item, index) => item === arr1[index])) { - return 1; - } - if (arr1.every((item, index) => item === arr2[index])) { - return 2; - } - return 3; -} - -function getRenderArr(routes) { - let renderArr = []; - renderArr.push(routes[0]); - for (let i = 1; i < routes.length; i += 1) { - // 去重 - renderArr = renderArr.filter(item => getRelation(item, routes[i]) !== 1); - // 是否包含 - const isAdd = renderArr.every(item => getRelation(item, routes[i]) === 3); - if (isAdd) { - renderArr.push(routes[i]); - } - } - return renderArr; -} - -/** - * Get router routing configuration - * { path:{name,...param}}=>Array<{name,path ...param}> - * @param {string} path - * @param {routerData} routerData - */ -export function getRoutes(path, routerData) { - let routes = Object.keys(routerData).filter( - routePath => routePath.indexOf(path) === 0 && routePath !== path - ); - // Replace path to '' eg. path='user' /user/name => name - routes = routes.map(item => item.replace(path, '')); - // Get the route to be rendered to remove the deep rendering - const renderArr = getRenderArr(routes); - // Conversion and stitching parameters - const renderRoutes = renderArr.map(item => { - const exact = !routes.some(route => route !== item && getRelation(route, item) === 1); - return { - exact, - ...routerData[`${path}${item}`], - key: `${path}${item}`, - path: `${path}${item}`, - }; - }); - return renderRoutes; -} - -export function getPageQuery() { - return parse(window.location.href.split('?')[1]); -} - -export function getQueryPath(path = '', query = {}) { - const search = stringify(query); - if (search.length) { - return `${path}?${search}`; - } - return path; -} - -/* eslint no-useless-escape:0 */ -const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/; - -export function isUrl(path) { - return reg.test(path); -} - -export function formatWan(val) { - const v = val * 1; - if (!v || Number.isNaN(v)) return ''; - - let result = val; - if (val > 10000) { - result = Math.floor(val / 10000); - result = ( - - {result} - - 万 - - - ); - } - return result; -} - -// 给官方演示站点用,用于关闭真实开发环境不需要使用的特性 -export function isAntdPro() { - return window.location.hostname === 'preview.pro.ant.design'; -} diff --git a/src/utils/utils.test.js b/src/utils/utils.test.js deleted file mode 100644 index c97d3254659abf88b598977027b26af9f94a0ebe..0000000000000000000000000000000000000000 --- a/src/utils/utils.test.js +++ /dev/null @@ -1,62 +0,0 @@ -import { fixedZero, isUrl } from './utils'; - -describe('fixedZero tests', () => { - it('should not pad large numbers', () => { - expect(fixedZero(10)).toEqual(10); - expect(fixedZero(11)).toEqual(11); - expect(fixedZero(15)).toEqual(15); - expect(fixedZero(20)).toEqual(20); - expect(fixedZero(100)).toEqual(100); - expect(fixedZero(1000)).toEqual(1000); - }); - - it('should pad single digit numbers and return them as string', () => { - expect(fixedZero(0)).toEqual('00'); - expect(fixedZero(1)).toEqual('01'); - expect(fixedZero(2)).toEqual('02'); - expect(fixedZero(3)).toEqual('03'); - expect(fixedZero(4)).toEqual('04'); - expect(fixedZero(5)).toEqual('05'); - expect(fixedZero(6)).toEqual('06'); - expect(fixedZero(7)).toEqual('07'); - expect(fixedZero(8)).toEqual('08'); - expect(fixedZero(9)).toEqual('09'); - }); -}); - -describe('isUrl tests', () => { - it('should return false for invalid and corner case inputs', () => { - expect(isUrl([])).toBeFalsy(); - expect(isUrl({})).toBeFalsy(); - expect(isUrl(false)).toBeFalsy(); - expect(isUrl(true)).toBeFalsy(); - expect(isUrl(NaN)).toBeFalsy(); - expect(isUrl(null)).toBeFalsy(); - expect(isUrl(undefined)).toBeFalsy(); - expect(isUrl()).toBeFalsy(); - expect(isUrl('')).toBeFalsy(); - }); - - it('should return false for invalid URLs', () => { - expect(isUrl('foo')).toBeFalsy(); - expect(isUrl('bar')).toBeFalsy(); - expect(isUrl('bar/test')).toBeFalsy(); - expect(isUrl('http:/example.com/')).toBeFalsy(); - expect(isUrl('ttp://example.com/')).toBeFalsy(); - }); - - it('should return true for valid URLs', () => { - expect(isUrl('http://example.com/')).toBeTruthy(); - expect(isUrl('https://example.com/')).toBeTruthy(); - expect(isUrl('http://example.com/test/123')).toBeTruthy(); - expect(isUrl('https://example.com/test/123')).toBeTruthy(); - expect(isUrl('http://example.com/test/123?foo=bar')).toBeTruthy(); - expect(isUrl('https://example.com/test/123?foo=bar')).toBeTruthy(); - expect(isUrl('http://www.example.com/')).toBeTruthy(); - expect(isUrl('https://www.example.com/')).toBeTruthy(); - expect(isUrl('http://www.example.com/test/123')).toBeTruthy(); - expect(isUrl('https://www.example.com/test/123')).toBeTruthy(); - expect(isUrl('http://www.example.com/test/123?foo=bar')).toBeTruthy(); - expect(isUrl('https://www.example.com/test/123?foo=bar')).toBeTruthy(); - }); -}); diff --git a/tests/run-tests.js b/tests/run-tests.js deleted file mode 100644 index 02c42b08ad46779b636edb5ca985d0cd0161e683..0000000000000000000000000000000000000000 --- a/tests/run-tests.js +++ /dev/null @@ -1,43 +0,0 @@ -/* eslint-disable no-console */ -const { spawn } = require('child_process'); -const { kill } = require('cross-port-killer'); - -const env = Object.create(process.env); -env.BROWSER = 'none'; -env.TEST = true; -// flag to prevent multiple test -let once = false; - -const startServer = spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['start'], { - env, -}); - -startServer.stderr.on('data', data => { - // eslint-disable-next-line - console.log(data.toString()); -}); - -startServer.on('exit', () => { - kill(process.env.PORT || 8000); -}); - -console.log('Starting development server for e2e tests...'); -startServer.stdout.on('data', data => { - console.log(data.toString()); - if (!once && data.toString().indexOf('Compiled successfully') >= 0) { - // eslint-disable-next-line - once = true; - console.log('Development server is started, ready to run tests.'); - const testCmd = spawn( - /^win/.test(process.platform) ? 'npm.cmd' : 'npm', - ['test', '--', '--maxWorkers=1', '--runInBand'], - { - stdio: 'inherit', - } - ); - testCmd.on('exit', code => { - startServer.kill(); - process.exit(code); - }); - } -}); diff --git a/tsconfig.json b/tsconfig.json index 5be3083113eb212c29bc33d59b6e73932bbcb0f9..6444ff253126c1bb5ee98785bc67dc42db0ec6a4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,7 @@ "jsx": "react", "allowSyntheticDefaultImports": true, "moduleResolution": "node", - "rootDirs": ["/src", "/test", "/mock","./typings"], + "rootDirs": ["/src", "/test", "/mock", "./typings"], "forceConsistentCasingInFileNames": true, "noImplicitReturns": true, "suppressImplicitAnyIndexErrors": true, @@ -17,10 +17,10 @@ "allowJs": true, "experimentalDecorators": true, "paths": { - "@/*": ["./src/*"] + "@/*": ["./ant-design-pro/*/src/*"] } }, - "include": ["./src"], + "include": ["./ant-design-pro"], "exclude": [ "node_modules", "build",
+ + {currentUser.title} +
+ + {currentUser.group} +
+ + {currentUser.geographic.province.label} + {currentUser.geographic.city.label} +
活跃用户
{activeUser}
新增用户
{newUser}
= - | React.StatelessComponent
- | React.ComponentClass
- | React.ClassicComponentClass
; - -type Secured = ( - authority: authority, - error?: React.ReactNode -) => (target: T) => T; - -type check = ( - authority: authority, - target: T, - Exception: S -) => T | S; - -export interface IAuthorizedProps { - authority: authority; - noMatch?: React.ReactNode; -} - -export class Authorized extends React.Component { - public static Secured: Secured; - public static AuthorizedRoute: typeof AuthorizedRoute; - public static check: check; -} - -declare function renderAuthorize(currentAuthority: string): typeof Authorized; - -export default renderAuthorize; diff --git a/src/components/Authorized/index.js b/src/components/Authorized/index.js deleted file mode 100644 index 22ac664d002844304b316e8c4f1acc79ede572d8..0000000000000000000000000000000000000000 --- a/src/components/Authorized/index.js +++ /dev/null @@ -1,11 +0,0 @@ -import Authorized from './Authorized'; -import AuthorizedRoute from './AuthorizedRoute'; -import Secured from './Secured'; -import check from './CheckPermissions'; -import renderAuthorize from './renderAuthorize'; - -Authorized.Secured = Secured; -Authorized.AuthorizedRoute = AuthorizedRoute; -Authorized.check = check; - -export default renderAuthorize(Authorized); diff --git a/src/components/Authorized/index.md b/src/components/Authorized/index.md deleted file mode 100644 index f3b2f80af5ffa27ecb310b6932dc7dfa7c7945c8..0000000000000000000000000000000000000000 --- a/src/components/Authorized/index.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: - en-US: Authorized - zh-CN: Authorized -subtitle: 权限 -cols: 1 -order: 15 ---- - -权限组件,通过比对现有权限与准入权限,决定相关元素的展示。 - -## API - -### RenderAuthorized - -`RenderAuthorized: (currentAuthority: string | () => string) => Authorized` - -权限组件默认 export RenderAuthorized 函数,它接收当前权限作为参数,返回一个权限对象,该对象提供以下几种使用方式。 - - -### Authorized - -最基础的权限控制。 - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| children | 正常渲染的元素,权限判断通过时展示 | ReactNode | - | -| authority | 准入权限/权限判断 | `string | array | Promise | (currentAuthority) => boolean | Promise` | - | -| noMatch | 权限异常渲染元素,权限判断不通过时展示 | ReactNode | - | - -### Authorized.AuthorizedRoute - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| authority | 准入权限/权限判断 | `string | array | Promise | (currentAuthority) => boolean | Promise` | - | -| redirectPath | 权限异常时重定向的页面路由 | string | - | - -其余参数与 `Route` 相同。 - -### Authorized.Secured - -注解方式,`@Authorized.Secured(authority, error)` - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| authority | 准入权限/权限判断 | `string | Promise | (currentAuthority) => boolean | Promise` | - | -| error | 权限异常时渲染元素 | ReactNode | | - -### Authorized.check - -函数形式的 Authorized,用于某些不能被 HOC 包裹的组件。 `Authorized.check(authority, target, Exception)` -注意:传入一个 Promise 时,无论正确还是错误返回的都是一个 ReactClass。 - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| authority | 准入权限/权限判断 | `string | Promise | (currentAuthority) => boolean | Promise` | - | -| target | 权限判断通过时渲染的元素 | ReactNode | - | -| Exception | 权限异常时渲染元素 | ReactNode | - | diff --git a/src/components/Authorized/renderAuthorize.js b/src/components/Authorized/renderAuthorize.js deleted file mode 100644 index be373d996bb38445af1c6e912bdac32ad594747d..0000000000000000000000000000000000000000 --- a/src/components/Authorized/renderAuthorize.js +++ /dev/null @@ -1,25 +0,0 @@ -/* eslint-disable import/no-mutable-exports */ -let CURRENT = 'NULL'; -/** - * use authority or getAuthority - * @param {string|()=>String} currentAuthority - */ -const renderAuthorize = Authorized => currentAuthority => { - if (currentAuthority) { - if (typeof currentAuthority === 'function') { - CURRENT = currentAuthority(); - } - if ( - Object.prototype.toString.call(currentAuthority) === '[object String]' || - Array.isArray(currentAuthority) - ) { - CURRENT = currentAuthority; - } - } else { - CURRENT = 'NULL'; - } - return Authorized; -}; - -export { CURRENT }; -export default Authorized => renderAuthorize(Authorized); diff --git a/src/components/AvatarList/AvatarItem.d.ts b/src/components/AvatarList/AvatarItem.d.ts deleted file mode 100644 index 5681de77c2b3634ee8a54487fe15d07044fa8ca4..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/AvatarItem.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as React from 'react'; -export interface IAvatarItemProps { - tips: React.ReactNode; - src: string; - style?: React.CSSProperties; -} - -export default class AvatarItem extends React.Component { - constructor(props: IAvatarItemProps); -} diff --git a/src/components/AvatarList/demo/maxLength.md b/src/components/AvatarList/demo/maxLength.md deleted file mode 100644 index 76c6b421cb0b976e2b0752a61522fca1f9a747b6..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/demo/maxLength.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -order: 0 -title: - zh-CN: 要显示的最大项目 - en-US: Max Items to Show ---- - -`maxLength` attribute specifies the maximum number of items to show while `excessItemsStyle` style the excess -item component. - -````jsx -import AvatarList from 'ant-design-pro/lib/AvatarList'; - -ReactDOM.render( - - - - - - - - -, mountNode); -```` diff --git a/src/components/AvatarList/demo/simple.md b/src/components/AvatarList/demo/simple.md deleted file mode 100644 index e941aea9b5d9614c11edb84cc9f7975a6087e455..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/demo/simple.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -order: 0 -title: - zh-CN: 基础样例 - en-US: Basic Usage ---- - -Simplest of usage. - -````jsx -import AvatarList from 'ant-design-pro/lib/AvatarList'; - -ReactDOM.render( - - - - - -, mountNode); -```` diff --git a/src/components/AvatarList/index.d.ts b/src/components/AvatarList/index.d.ts deleted file mode 100644 index f49ca010d9fe19febd4eaed391278012109dd444..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/index.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import * as React from 'react'; -import AvatarItem from './AvatarItem'; - -export interface IAvatarListProps { - size?: 'large' | 'small' | 'mini' | 'default'; - maxLength?: number; - excessItemsStyle?: React.CSSProperties; - style?: React.CSSProperties; - children: React.ReactElement | Array>; -} - -export default class AvatarList extends React.Component { - public static Item: typeof AvatarItem; -} diff --git a/src/components/AvatarList/index.en-US.md b/src/components/AvatarList/index.en-US.md deleted file mode 100644 index 7fc39cc2b72efe91689637bca3603eeb3f2634cf..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/index.en-US.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: AvatarList -order: 1 -cols: 1 ---- - -A list of user's avatar for project or group member list frequently. If a large or small AvatarList is desired, set the `size` property to either `large` or `small` and `mini` respectively. Omit the `size` property for a AvatarList with the default size. - -## API - -### AvatarList - -| Property | Description | Type | Default | -| ---------------- | --------------------- | ---------------------------------- | --------- | -| size | size of list | `large`、`small` 、`mini`, `default` | `default` | -| maxLength | max items to show | number | - | -| excessItemsStyle | the excess item style | CSSProperties | - | - -### AvatarList.Item - -| Property | Description | Type | Default | -| -------- | -------------------------------------------- | --------- | ------- | -| tips | title tips for avatar item | ReactNode | - | -| src | the address of the image for an image avatar | string | - | diff --git a/src/components/AvatarList/index.js b/src/components/AvatarList/index.js deleted file mode 100644 index 9af32bcfdaea12c35cdaabda302be4b57622aafd..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/index.js +++ /dev/null @@ -1,61 +0,0 @@ -import React from 'react'; -import { Tooltip, Avatar } from 'antd'; -import classNames from 'classnames'; - -import styles from './index.less'; - -const avatarSizeToClassName = size => - classNames(styles.avatarItem, { - [styles.avatarItemLarge]: size === 'large', - [styles.avatarItemSmall]: size === 'small', - [styles.avatarItemMini]: size === 'mini', - }); - -const AvatarList = ({ children, size, maxLength, excessItemsStyle, ...other }) => { - const numOfChildren = React.Children.count(children); - const numToShow = maxLength >= numOfChildren ? numOfChildren : maxLength; - - const childrenWithProps = React.Children.toArray(children) - .slice(0, numToShow) - .map(child => - React.cloneElement(child, { - size, - }) - ); - - if (numToShow < numOfChildren) { - const cls = avatarSizeToClassName(size); - - childrenWithProps.push( - - {`+${numOfChildren - maxLength}`} - - ); - } - - return ( - - {childrenWithProps} - - ); -}; - -const Item = ({ src, size, tips, onClick = () => {} }) => { - const cls = avatarSizeToClassName(size); - - return ( - - {tips ? ( - - - - ) : ( - - )} - - ); -}; - -AvatarList.Item = Item; - -export default AvatarList; diff --git a/src/components/AvatarList/index.less b/src/components/AvatarList/index.less deleted file mode 100644 index 31d670565bd82fe8b08138d5dfa1d8082682aaa8..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/index.less +++ /dev/null @@ -1,50 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.avatarList { - display: inline-block; - ul { - display: inline-block; - margin-left: 8px; - font-size: 0; - } -} - -.avatarItem { - display: inline-block; - font-size: @font-size-base; - margin-left: -8px; - width: @avatar-size-base; - height: @avatar-size-base; - :global { - .ant-avatar { - border: 1px solid #fff; - } - } -} - -.avatarItemLarge { - width: @avatar-size-lg; - height: @avatar-size-lg; -} - -.avatarItemSmall { - width: @avatar-size-sm; - height: @avatar-size-sm; -} - -.avatarItemMini { - width: 20px; - height: 20px; - :global { - .ant-avatar { - width: 20px; - height: 20px; - line-height: 20px; - - .ant-avatar-string { - font-size: 12px; - line-height: 18px; - } - } - } -} diff --git a/src/components/AvatarList/index.test.js b/src/components/AvatarList/index.test.js deleted file mode 100644 index 2b5bc438d882fc608a1e25869118e01c38a4484c..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/index.test.js +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; -import range from 'lodash/range'; -import { mount } from 'enzyme'; -import AvatarList from './index'; - -const renderItems = numItems => - range(numItems).map(i => ( - - )); - -describe('AvatarList', () => { - it('renders all items', () => { - const wrapper = mount({renderItems(4)}); - expect(wrapper.find('AvatarList').length).toBe(1); - expect(wrapper.find('Item').length).toBe(4); - expect(wrapper.findWhere(node => node.key() === 'exceed').length).toBe(0); - }); - - it('renders max of 3 items', () => { - const wrapper = mount({renderItems(4)}); - expect(wrapper.find('AvatarList').length).toBe(1); - expect(wrapper.find('Item').length).toBe(3); - expect(wrapper.findWhere(node => node.key() === 'exceed').length).toBe(1); - }); -}); diff --git a/src/components/AvatarList/index.zh-CN.md b/src/components/AvatarList/index.zh-CN.md deleted file mode 100644 index bdab181ce0ed6f1ff8d07422672085410033a815..0000000000000000000000000000000000000000 --- a/src/components/AvatarList/index.zh-CN.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: AvatarList -subtitle: 用户头像列表 -order: 1 -cols: 1 ---- - -一组用户头像,常用在项目/团队成员列表。可通过设置 `size` 属性来指定头像大小。 - -## API - -### AvatarList - -| 参数 | 说明 | 类型 | 默认值 | -| ---------------- | -------- | ---------------------------------- | --------- | -| size | 头像大小 | `large`、`small` 、`mini`, `default` | `default` | -| maxLength | 要显示的最大项目 | number | - | -| excessItemsStyle | 多余的项目风格 | CSSProperties | - | - -### AvatarList.Item - -| 参数 | 说明 | 类型 | 默认值 | -| ---- | ------ | --------- | --- | -| tips | 头像展示文案 | ReactNode | - | -| src | 头像图片连接 | string | - | diff --git a/src/components/Charts/Bar/index.d.ts b/src/components/Charts/Bar/index.d.ts deleted file mode 100644 index 4899082509dacb84701bb2e02fbe69ba1d06e149..0000000000000000000000000000000000000000 --- a/src/components/Charts/Bar/index.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from 'react'; -export interface IBarProps { - title: React.ReactNode; - color?: string; - padding?: [number, number, number, number]; - height: number; - data: Array<{ - x: string; - y: number; - }>; - autoLabel?: boolean; - style?: React.CSSProperties; -} - -export default class Bar extends React.Component {} diff --git a/src/components/Charts/Bar/index.js b/src/components/Charts/Bar/index.js deleted file mode 100644 index f0cb65ffee74014dafdb286d2dcc42043ec13c08..0000000000000000000000000000000000000000 --- a/src/components/Charts/Bar/index.js +++ /dev/null @@ -1,113 +0,0 @@ -import React, { Component } from 'react'; -import { Chart, Axis, Tooltip, Geom } from 'bizcharts'; -import Debounce from 'lodash-decorators/debounce'; -import Bind from 'lodash-decorators/bind'; -import autoHeight from '../autoHeight'; -import styles from '../index.less'; - -@autoHeight() -class Bar extends Component { - state = { - autoHideXLabels: false, - }; - - componentDidMount() { - window.addEventListener('resize', this.resize, { passive: true }); - } - - componentWillUnmount() { - window.removeEventListener('resize', this.resize); - } - - handleRoot = n => { - this.root = n; - }; - - handleRef = n => { - this.node = n; - }; - - @Bind() - @Debounce(400) - resize() { - if (!this.node) { - return; - } - const canvasWidth = this.node.parentNode.clientWidth; - const { data = [], autoLabel = true } = this.props; - if (!autoLabel) { - return; - } - const minWidth = data.length * 30; - const { autoHideXLabels } = this.state; - - if (canvasWidth <= minWidth) { - if (!autoHideXLabels) { - this.setState({ - autoHideXLabels: true, - }); - } - } else if (autoHideXLabels) { - this.setState({ - autoHideXLabels: false, - }); - } - } - - render() { - const { - height, - title, - forceFit = true, - data, - color = 'rgba(24, 144, 255, 0.85)', - padding, - } = this.props; - - const { autoHideXLabels } = this.state; - - const scale = { - x: { - type: 'cat', - }, - y: { - min: 0, - }, - }; - - const tooltip = [ - 'x*y', - (x, y) => ({ - name: x, - value: y, - }), - ]; - - return ( - - - {title && {title}} - - - - - - - - - ); - } -} - -export default Bar; diff --git a/src/components/Charts/ChartCard/index.d.ts b/src/components/Charts/ChartCard/index.d.ts deleted file mode 100644 index 0437c0c857d7f1c63c506c5eb238583a251714d0..0000000000000000000000000000000000000000 --- a/src/components/Charts/ChartCard/index.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { CardProps } from 'antd/lib/card'; -import * as React from 'react'; - -export interface IChartCardProps extends CardProps { - title: React.ReactNode; - action?: React.ReactNode; - total?: React.ReactNode | number | (() => React.ReactNode | number); - footer?: React.ReactNode; - contentHeight?: number; - avatar?: React.ReactNode; - style?: React.CSSProperties; -} - -export default class ChartCard extends React.Component {} diff --git a/src/components/Charts/ChartCard/index.js b/src/components/Charts/ChartCard/index.js deleted file mode 100644 index ca6bcb2e6d85a657e399ea39fa31df53aaadd608..0000000000000000000000000000000000000000 --- a/src/components/Charts/ChartCard/index.js +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react'; -import { Card } from 'antd'; -import classNames from 'classnames'; - -import styles from './index.less'; - -const renderTotal = total => { - let totalDom; - switch (typeof total) { - case 'undefined': - totalDom = null; - break; - case 'function': - totalDom = {total()}; - break; - default: - totalDom = {total}; - } - return totalDom; -}; - -class ChartCard extends React.PureComponent { - renderConnet = () => { - const { contentHeight, title, avatar, action, total, footer, children, loading } = this.props; - if (loading) { - return false; - } - return ( - - - {avatar} - - - {title} - {action} - - {renderTotal(total)} - - - {children && ( - - {children} - - )} - {footer && ( - - {footer} - - )} - - ); - }; - - render() { - const { - loading = false, - contentHeight, - title, - avatar, - action, - total, - footer, - children, - ...rest - } = this.props; - return ( - - {this.renderConnet()} - - ); - } -} - -export default ChartCard; diff --git a/src/components/Charts/ChartCard/index.less b/src/components/Charts/ChartCard/index.less deleted file mode 100644 index 0ddc486b9433457b83cc8813d6f02a100ec2d58f..0000000000000000000000000000000000000000 --- a/src/components/Charts/ChartCard/index.less +++ /dev/null @@ -1,75 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.chartCard { - position: relative; - .chartTop { - position: relative; - overflow: hidden; - width: 100%; - } - .chartTopMargin { - margin-bottom: 12px; - } - .chartTopHasMargin { - margin-bottom: 20px; - } - .metaWrap { - float: left; - } - .avatar { - position: relative; - top: 4px; - float: left; - margin-right: 20px; - img { - border-radius: 100%; - } - } - .meta { - color: @text-color-secondary; - font-size: @font-size-base; - line-height: 22px; - height: 22px; - } - .action { - cursor: pointer; - position: absolute; - top: 4px; - right: 0; - line-height: 1; - } - .total { - overflow: hidden; - text-overflow: ellipsis; - word-break: break-all; - white-space: nowrap; - color: @heading-color; - margin-top: 4px; - margin-bottom: 0; - font-size: 30px; - line-height: 38px; - height: 38px; - } - .content { - margin-bottom: 12px; - position: relative; - width: 100%; - } - .contentFixed { - position: absolute; - left: 0; - bottom: 0; - width: 100%; - } - .footer { - border-top: 1px solid @border-color-split; - padding-top: 9px; - margin-top: 8px; - & > * { - position: relative; - } - } - .footerMargin { - margin-top: 20px; - } -} diff --git a/src/components/Charts/Field/index.d.ts b/src/components/Charts/Field/index.d.ts deleted file mode 100644 index 975fb667d8db178c1154162f4803e20f1c72a8e4..0000000000000000000000000000000000000000 --- a/src/components/Charts/Field/index.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import * as React from 'react'; -export interface IFieldProps { - label: React.ReactNode; - value: React.ReactNode; - style?: React.CSSProperties; -} - -export default class Field extends React.Component {} diff --git a/src/components/Charts/Field/index.js b/src/components/Charts/Field/index.js deleted file mode 100644 index 22dca86c0dd6ede80de52ca7c124afa12fda4a13..0000000000000000000000000000000000000000 --- a/src/components/Charts/Field/index.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react'; - -import styles from './index.less'; - -const Field = ({ label, value, ...rest }) => ( - - {label} - {value} - -); - -export default Field; diff --git a/src/components/Charts/Field/index.less b/src/components/Charts/Field/index.less deleted file mode 100644 index 170ddc1d85fd4f1e6dd9f909e481341408269c94..0000000000000000000000000000000000000000 --- a/src/components/Charts/Field/index.less +++ /dev/null @@ -1,17 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.field { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - margin: 0; - .label, - .number { - font-size: @font-size-base; - line-height: 22px; - } - .number { - color: @heading-color; - margin-left: 8px; - } -} diff --git a/src/components/Charts/Gauge/index.d.ts b/src/components/Charts/Gauge/index.d.ts deleted file mode 100644 index 66e3c003a957581d88a06e63b32a7a3e76c5cd3a..0000000000000000000000000000000000000000 --- a/src/components/Charts/Gauge/index.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as React from 'react'; -export interface IGaugeProps { - title: React.ReactNode; - color?: string; - height: number; - bgColor?: number; - percent: number; - style?: React.CSSProperties; -} - -export default class Gauge extends React.Component {} diff --git a/src/components/Charts/Gauge/index.js b/src/components/Charts/Gauge/index.js deleted file mode 100644 index 2249211aeaad53652d578c8dc050a60795129b68..0000000000000000000000000000000000000000 --- a/src/components/Charts/Gauge/index.js +++ /dev/null @@ -1,167 +0,0 @@ -import React from 'react'; -import { Chart, Geom, Axis, Coord, Guide, Shape } from 'bizcharts'; -import autoHeight from '../autoHeight'; - -const { Arc, Html, Line } = Guide; - -const defaultFormatter = val => { - switch (val) { - case '2': - return '差'; - case '4': - return '中'; - case '6': - return '良'; - case '8': - return '优'; - default: - return ''; - } -}; - -Shape.registerShape('point', 'pointer', { - drawShape(cfg, group) { - let point = cfg.points[0]; - point = this.parsePoint(point); - const center = this.parsePoint({ - x: 0, - y: 0, - }); - group.addShape('line', { - attrs: { - x1: center.x, - y1: center.y, - x2: point.x, - y2: point.y, - stroke: cfg.color, - lineWidth: 2, - lineCap: 'round', - }, - }); - return group.addShape('circle', { - attrs: { - x: center.x, - y: center.y, - r: 6, - stroke: cfg.color, - lineWidth: 3, - fill: '#fff', - }, - }); - }, -}); - -@autoHeight() -class Gauge extends React.Component { - render() { - const { - title, - height, - percent, - forceFit = true, - formatter = defaultFormatter, - color = '#2F9CFF', - bgColor = '#F0F2F5', - } = this.props; - const cols = { - value: { - type: 'linear', - min: 0, - max: 10, - tickCount: 6, - nice: true, - }, - }; - const data = [{ value: percent / 10 }]; - return ( - - - - - - - - - - - ` - - ${title} - - ${data[0].value * 10}% - - `} - /> - - - - ); - } -} - -export default Gauge; diff --git a/src/components/Charts/MiniArea/index.d.ts b/src/components/Charts/MiniArea/index.d.ts deleted file mode 100644 index b223b68ca097e01f1c76e4e2cb4e95e9db4dc39b..0000000000000000000000000000000000000000 --- a/src/components/Charts/MiniArea/index.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from 'react'; - -// g2已经更新到3.0 -// 不带的写了 - -export interface IAxis { - title: any; - line: any; - gridAlign: any; - labels: any; - tickLine: any; - grid: any; -} - -export interface IMiniAreaProps { - color?: string; - height: number; - borderColor?: string; - line?: boolean; - animate?: boolean; - xAxis?: IAxis; - yAxis?: IAxis; - data: Array<{ - x: number | string; - y: number; - }>; -} - -export default class MiniArea extends React.Component {} diff --git a/src/components/Charts/MiniArea/index.js b/src/components/Charts/MiniArea/index.js deleted file mode 100644 index d3209becaeed2f3069267b08c16cf9bbb3672be0..0000000000000000000000000000000000000000 --- a/src/components/Charts/MiniArea/index.js +++ /dev/null @@ -1,108 +0,0 @@ -import React from 'react'; -import { Chart, Axis, Tooltip, Geom } from 'bizcharts'; -import autoHeight from '../autoHeight'; -import styles from '../index.less'; - -@autoHeight() -class MiniArea extends React.PureComponent { - render() { - const { - height, - data = [], - forceFit = true, - color = 'rgba(24, 144, 255, 0.2)', - borderColor = '#1089ff', - scale = {}, - borderWidth = 2, - line, - xAxis, - yAxis, - animate = true, - } = this.props; - - const padding = [36, 5, 30, 5]; - - const scaleProps = { - x: { - type: 'cat', - range: [0, 1], - ...scale.x, - }, - y: { - min: 0, - ...scale.y, - }, - }; - - const tooltip = [ - 'x*y', - (x, y) => ({ - name: x, - value: y, - }), - ]; - - const chartHeight = height + 54; - - return ( - - - {height > 0 && ( - - - - - - {line ? ( - - ) : ( - - )} - - )} - - - ); - } -} - -export default MiniArea; diff --git a/src/components/Charts/MiniBar/index.d.ts b/src/components/Charts/MiniBar/index.d.ts deleted file mode 100644 index 0c4bd6cce558f4b948691c553c65d76c8c34fc6b..0000000000000000000000000000000000000000 --- a/src/components/Charts/MiniBar/index.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import * as React from 'react'; -export interface IMiniBarProps { - color?: string; - height: number; - data: Array<{ - x: number | string; - y: number; - }>; - style?: React.CSSProperties; -} - -export default class MiniBar extends React.Component {} diff --git a/src/components/Charts/MiniBar/index.js b/src/components/Charts/MiniBar/index.js deleted file mode 100644 index 18e4d8c6fba2322b9ee75a9522fa40cd8315463d..0000000000000000000000000000000000000000 --- a/src/components/Charts/MiniBar/index.js +++ /dev/null @@ -1,51 +0,0 @@ -import React from 'react'; -import { Chart, Tooltip, Geom } from 'bizcharts'; -import autoHeight from '../autoHeight'; -import styles from '../index.less'; - -@autoHeight() -class MiniBar extends React.Component { - render() { - const { height, forceFit = true, color = '#1890FF', data = [] } = this.props; - - const scale = { - x: { - type: 'cat', - }, - y: { - min: 0, - }, - }; - - const padding = [36, 5, 30, 5]; - - const tooltip = [ - 'x*y', - (x, y) => ({ - name: x, - value: y, - }), - ]; - - // for tooltip not to be hide - const chartHeight = height + 54; - - return ( - - - - - - - - - ); - } -} -export default MiniBar; diff --git a/src/components/Charts/MiniProgress/index.d.ts b/src/components/Charts/MiniProgress/index.d.ts deleted file mode 100644 index aaeb7261d7ea06dfad935faf7c00238035ea921d..0000000000000000000000000000000000000000 --- a/src/components/Charts/MiniProgress/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as React from 'react'; -export interface IMiniProgressProps { - target: number; - color?: string; - strokeWidth?: number; - percent?: number; - style?: React.CSSProperties; -} - -export default class MiniProgress extends React.Component {} diff --git a/src/components/Charts/MiniProgress/index.js b/src/components/Charts/MiniProgress/index.js deleted file mode 100644 index 795c79b15951e2bdde85c0a6fa1427ba46c8df1c..0000000000000000000000000000000000000000 --- a/src/components/Charts/MiniProgress/index.js +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; -import { Tooltip } from 'antd'; - -import styles from './index.less'; - -const MiniProgress = ({ target, color = 'rgb(19, 194, 194)', strokeWidth, percent }) => ( - - - - - - - - - - - -); - -export default MiniProgress; diff --git a/src/components/Charts/MiniProgress/index.less b/src/components/Charts/MiniProgress/index.less deleted file mode 100644 index e5f148cbf532e6a0715364009f5a2c2c085d1d43..0000000000000000000000000000000000000000 --- a/src/components/Charts/MiniProgress/index.less +++ /dev/null @@ -1,35 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.miniProgress { - padding: 5px 0; - position: relative; - width: 100%; - .progressWrap { - background-color: @background-color-base; - position: relative; - } - .progress { - transition: all 0.4s cubic-bezier(0.08, 0.82, 0.17, 1) 0s; - border-radius: 1px 0 0 1px; - background-color: @primary-color; - width: 0; - height: 100%; - } - .target { - position: absolute; - top: 0; - bottom: 0; - span { - border-radius: 100px; - position: absolute; - top: 0; - left: 0; - height: 4px; - width: 2px; - } - span:last-child { - top: auto; - bottom: 0; - } - } -} diff --git a/src/components/Charts/Pie/index.d.ts b/src/components/Charts/Pie/index.d.ts deleted file mode 100644 index 66c93eeb5d856928697335530c090c68492e81a5..0000000000000000000000000000000000000000 --- a/src/components/Charts/Pie/index.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react'; -export interface IPieProps { - animate?: boolean; - color?: string; - colors?: string[]; - height: number; - hasLegend?: boolean; - padding?: [number, number, number, number]; - percent?: number; - data?: Array<{ - x: string | string; - y: number; - }>; - total?: React.ReactNode | number | (() => React.ReactNode | number); - title?: React.ReactNode; - tooltip?: boolean; - valueFormat?: (value: string) => string | React.ReactNode; - subTitle?: React.ReactNode; -} - -export default class Pie extends React.Component {} diff --git a/src/components/Charts/Pie/index.js b/src/components/Charts/Pie/index.js deleted file mode 100644 index 7dff5123f30d1937550e0c042953aee5392ee1fe..0000000000000000000000000000000000000000 --- a/src/components/Charts/Pie/index.js +++ /dev/null @@ -1,271 +0,0 @@ -import React, { Component } from 'react'; -import { Chart, Tooltip, Geom, Coord } from 'bizcharts'; -import { DataView } from '@antv/data-set'; -import { Divider } from 'antd'; -import classNames from 'classnames'; -import ReactFitText from 'react-fittext'; -import Debounce from 'lodash-decorators/debounce'; -import Bind from 'lodash-decorators/bind'; -import autoHeight from '../autoHeight'; - -import styles from './index.less'; - -/* eslint react/no-danger:0 */ -@autoHeight() -class Pie extends Component { - state = { - legendData: [], - legendBlock: false, - }; - - componentDidMount() { - window.addEventListener( - 'resize', - () => { - this.requestRef = requestAnimationFrame(() => this.resize()); - }, - { passive: true } - ); - } - - componentDidUpdate(preProps) { - const { data } = this.props; - if (data !== preProps.data) { - // because of charts data create when rendered - // so there is a trick for get rendered time - this.getLegendData(); - } - } - - componentWillUnmount() { - window.cancelAnimationFrame(this.requestRef); - window.removeEventListener('resize', this.resize); - this.resize.cancel(); - } - - getG2Instance = chart => { - this.chart = chart; - requestAnimationFrame(() => { - this.getLegendData(); - this.resize(); - }); - }; - - // for custom lengend view - getLegendData = () => { - if (!this.chart) return; - const geom = this.chart.getAllGeoms()[0]; // 获取所有的图形 - if (!geom) return; - const items = geom.get('dataArray') || []; // 获取图形对应的 - - const legendData = items.map(item => { - /* eslint no-underscore-dangle:0 */ - const origin = item[0]._origin; - origin.color = item[0].color; - origin.checked = true; - return origin; - }); - - this.setState({ - legendData, - }); - }; - - handleRoot = n => { - this.root = n; - }; - - handleLegendClick = (item, i) => { - const newItem = item; - newItem.checked = !newItem.checked; - - const { legendData } = this.state; - legendData[i] = newItem; - - const filteredLegendData = legendData.filter(l => l.checked).map(l => l.x); - - if (this.chart) { - this.chart.filter('x', val => filteredLegendData.indexOf(val) > -1); - } - - this.setState({ - legendData, - }); - }; - - // for window resize auto responsive legend - @Bind() - @Debounce(300) - resize() { - const { hasLegend } = this.props; - const { legendBlock } = this.state; - if (!hasLegend || !this.root) { - window.removeEventListener('resize', this.resize); - return; - } - if (this.root.parentNode.clientWidth <= 380) { - if (!legendBlock) { - this.setState({ - legendBlock: true, - }); - } - } else if (legendBlock) { - this.setState({ - legendBlock: false, - }); - } - } - - render() { - const { - valueFormat, - subTitle, - total, - hasLegend = false, - className, - style, - height, - forceFit = true, - percent, - color, - inner = 0.75, - animate = true, - colors, - lineWidth = 1, - } = this.props; - - const { legendData, legendBlock } = this.state; - const pieClassName = classNames(styles.pie, className, { - [styles.hasLegend]: !!hasLegend, - [styles.legendBlock]: legendBlock, - }); - - const { - data: propsData, - selected: propsSelected = true, - tooltip: propsTooltip = true, - } = this.props; - - let data = propsData || []; - let selected = propsSelected; - let tooltip = propsTooltip; - - const defaultColors = colors; - data = data || []; - selected = selected || true; - tooltip = tooltip || true; - let formatColor; - - const scale = { - x: { - type: 'cat', - range: [0, 1], - }, - y: { - min: 0, - }, - }; - - if (percent || percent === 0) { - selected = false; - tooltip = false; - formatColor = value => { - if (value === '占比') { - return color || 'rgba(24, 144, 255, 0.85)'; - } - return '#F0F2F5'; - }; - - data = [ - { - x: '占比', - y: parseFloat(percent), - }, - { - x: '反比', - y: 100 - parseFloat(percent), - }, - ]; - } - - const tooltipFormat = [ - 'x*percent', - (x, p) => ({ - name: x, - value: `${(p * 100).toFixed(2)}%`, - }), - ]; - - const padding = [12, 0, 12, 0]; - - const dv = new DataView(); - dv.source(data).transform({ - type: 'percent', - field: 'y', - dimension: 'x', - as: 'percent', - }); - - return ( - - - - - {!!tooltip && } - - - - - {(subTitle || total) && ( - - {subTitle && {subTitle}} - {/* eslint-disable-next-line */} - {total && ( - {typeof total === 'function' ? total() : total} - )} - - )} - - - - {hasLegend && ( - - {legendData.map((item, i) => ( - this.handleLegendClick(item, i)}> - - {item.x} - - - {`${(Number.isNaN(item.percent) ? 0 : item.percent * 100).toFixed(2)}%`} - - {valueFormat ? valueFormat(item.y) : item.y} - - ))} - - )} - - ); - } -} - -export default Pie; diff --git a/src/components/Charts/Pie/index.less b/src/components/Charts/Pie/index.less deleted file mode 100644 index 7249d0930905d4bd6d15e08f5cfdd69237717cd4..0000000000000000000000000000000000000000 --- a/src/components/Charts/Pie/index.less +++ /dev/null @@ -1,94 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.pie { - position: relative; - .chart { - position: relative; - } - &.hasLegend .chart { - width: ~'calc(100% - 240px)'; - } - .legend { - position: absolute; - right: 0; - min-width: 200px; - top: 50%; - transform: translateY(-50%); - margin: 0 20px; - list-style: none; - padding: 0; - li { - cursor: pointer; - margin-bottom: 16px; - height: 22px; - line-height: 22px; - &:last-child { - margin-bottom: 0; - } - } - } - .dot { - border-radius: 8px; - display: inline-block; - margin-right: 8px; - position: relative; - top: -1px; - height: 8px; - width: 8px; - } - .line { - background-color: @border-color-split; - display: inline-block; - margin-right: 8px; - width: 1px; - height: 16px; - } - .legendTitle { - color: @text-color; - } - .percent { - color: @text-color-secondary; - } - .value { - position: absolute; - right: 0; - } - .title { - margin-bottom: 8px; - } - .total { - position: absolute; - left: 50%; - top: 50%; - text-align: center; - max-height: 62px; - transform: translate(-50%, -50%); - & > h4 { - color: @text-color-secondary; - font-size: 14px; - line-height: 22px; - height: 22px; - margin-bottom: 8px; - font-weight: normal; - } - & > p { - color: @heading-color; - display: block; - font-size: 1.2em; - height: 32px; - line-height: 32px; - white-space: nowrap; - } - } -} - -.legendBlock { - &.hasLegend .chart { - width: 100%; - margin: 0 0 32px 0; - } - .legend { - position: relative; - transform: none; - } -} diff --git a/src/components/Charts/Radar/index.d.ts b/src/components/Charts/Radar/index.d.ts deleted file mode 100644 index 963ac8c37c112c360cd399b039d790e53b83a2a3..0000000000000000000000000000000000000000 --- a/src/components/Charts/Radar/index.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from 'react'; -export interface IRadarProps { - title?: React.ReactNode; - height: number; - padding?: [number, number, number, number]; - hasLegend?: boolean; - data: Array<{ - name: string; - label: string; - value: string; - }>; - style?: React.CSSProperties; -} - -export default class Radar extends React.Component {} diff --git a/src/components/Charts/Radar/index.js b/src/components/Charts/Radar/index.js deleted file mode 100644 index a0aa7fab6ea82dde0e9202d5315d9df80e18e806..0000000000000000000000000000000000000000 --- a/src/components/Charts/Radar/index.js +++ /dev/null @@ -1,184 +0,0 @@ -import React, { Component } from 'react'; -import { Chart, Tooltip, Geom, Coord, Axis } from 'bizcharts'; -import { Row, Col } from 'antd'; -import autoHeight from '../autoHeight'; -import styles from './index.less'; - -/* eslint react/no-danger:0 */ -@autoHeight() -class Radar extends Component { - state = { - legendData: [], - }; - - componentDidMount() { - this.getLegendData(); - } - - componentDidUpdate(preProps) { - const { data } = this.props; - if (data !== preProps.data) { - this.getLegendData(); - } - } - - getG2Instance = chart => { - this.chart = chart; - }; - - // for custom lengend view - getLegendData = () => { - if (!this.chart) return; - const geom = this.chart.getAllGeoms()[0]; // 获取所有的图形 - if (!geom) return; - const items = geom.get('dataArray') || []; // 获取图形对应的 - - const legendData = items.map(item => { - // eslint-disable-next-line - const origins = item.map(t => t._origin); - const result = { - name: origins[0].name, - color: item[0].color, - checked: true, - value: origins.reduce((p, n) => p + n.value, 0), - }; - - return result; - }); - - this.setState({ - legendData, - }); - }; - - handleRef = n => { - this.node = n; - }; - - handleLegendClick = (item, i) => { - const newItem = item; - newItem.checked = !newItem.checked; - - const { legendData } = this.state; - legendData[i] = newItem; - - const filteredLegendData = legendData.filter(l => l.checked).map(l => l.name); - - if (this.chart) { - this.chart.filter('name', val => filteredLegendData.indexOf(val) > -1); - this.chart.repaint(); - } - - this.setState({ - legendData, - }); - }; - - render() { - const defaultColors = [ - '#1890FF', - '#FACC14', - '#2FC25B', - '#8543E0', - '#F04864', - '#13C2C2', - '#fa8c16', - '#a0d911', - ]; - - const { - data = [], - height = 0, - title, - hasLegend = false, - forceFit = true, - tickCount = 5, - padding = [35, 30, 16, 30], - animate = true, - colors = defaultColors, - } = this.props; - - const { legendData } = this.state; - - const scale = { - value: { - min: 0, - tickCount, - }, - }; - - const chartHeight = height - (hasLegend ? 80 : 22); - - return ( - - {title && {title}} - - - - - - - - - {hasLegend && ( - - {legendData.map((item, i) => ( - this.handleLegendClick(item, i)} - > - - - - {item.name} - - {item.value} - - - ))} - - )} - - ); - } -} - -export default Radar; diff --git a/src/components/Charts/Radar/index.less b/src/components/Charts/Radar/index.less deleted file mode 100644 index 15b8725ca7f084bb7cd662fd3cd44138fe928d81..0000000000000000000000000000000000000000 --- a/src/components/Charts/Radar/index.less +++ /dev/null @@ -1,46 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.radar { - .legend { - margin-top: 16px; - .legendItem { - position: relative; - text-align: center; - cursor: pointer; - color: @text-color-secondary; - line-height: 22px; - p { - margin: 0; - } - h6 { - color: @heading-color; - padding-left: 16px; - font-size: 24px; - line-height: 32px; - margin-top: 4px; - margin-bottom: 0; - } - &:after { - background-color: @border-color-split; - position: absolute; - top: 8px; - right: 0; - height: 40px; - width: 1px; - content: ''; - } - } - > :last-child .legendItem:after { - display: none; - } - .dot { - border-radius: 6px; - display: inline-block; - margin-right: 6px; - position: relative; - top: -1px; - height: 6px; - width: 6px; - } - } -} diff --git a/src/components/Charts/TagCloud/index.d.ts b/src/components/Charts/TagCloud/index.d.ts deleted file mode 100644 index 462650c4dbb7532670d200141f7cbebc52525808..0000000000000000000000000000000000000000 --- a/src/components/Charts/TagCloud/index.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as React from 'react'; -export interface ITagCloudProps { - data: Array<{ - name: string; - value: number; - }>; - height: number; - style?: React.CSSProperties; -} - -export default class TagCloud extends React.Component {} diff --git a/src/components/Charts/TagCloud/index.js b/src/components/Charts/TagCloud/index.js deleted file mode 100644 index d94699bd551c0c33319bd3d61eac2c4edb613bbe..0000000000000000000000000000000000000000 --- a/src/components/Charts/TagCloud/index.js +++ /dev/null @@ -1,182 +0,0 @@ -import React, { Component } from 'react'; -import { Chart, Geom, Coord, Shape, Tooltip } from 'bizcharts'; -import DataSet from '@antv/data-set'; -import Debounce from 'lodash-decorators/debounce'; -import Bind from 'lodash-decorators/bind'; -import classNames from 'classnames'; -import autoHeight from '../autoHeight'; -import styles from './index.less'; - -/* eslint no-underscore-dangle: 0 */ -/* eslint no-param-reassign: 0 */ - -const imgUrl = 'https://gw.alipayobjects.com/zos/rmsportal/gWyeGLCdFFRavBGIDzWk.png'; - -@autoHeight() -class TagCloud extends Component { - state = { - dv: null, - }; - - componentDidMount() { - requestAnimationFrame(() => { - this.initTagCloud(); - this.renderChart(); - }); - window.addEventListener('resize', this.resize, { passive: true }); - } - - componentDidUpdate(preProps) { - const { data } = this.props; - if (JSON.stringify(preProps.data) !== JSON.stringify(data)) { - this.renderChart(this.props); - } - } - - componentWillUnmount() { - this.isUnmount = true; - window.cancelAnimationFrame(this.requestRef); - window.removeEventListener('resize', this.resize); - } - - resize = () => { - this.requestRef = requestAnimationFrame(() => { - this.renderChart(); - }); - }; - - saveRootRef = node => { - this.root = node; - }; - - initTagCloud = () => { - function getTextAttrs(cfg) { - return Object.assign( - {}, - { - fillOpacity: cfg.opacity, - fontSize: cfg.origin._origin.size, - rotate: cfg.origin._origin.rotate, - text: cfg.origin._origin.text, - textAlign: 'center', - fontFamily: cfg.origin._origin.font, - fill: cfg.color, - textBaseline: 'Alphabetic', - }, - cfg.style - ); - } - - // 给point注册一个词云的shape - Shape.registerShape('point', 'cloud', { - drawShape(cfg, container) { - const attrs = getTextAttrs(cfg); - return container.addShape('text', { - attrs: Object.assign(attrs, { - x: cfg.x, - y: cfg.y, - }), - }); - }, - }); - }; - - @Bind() - @Debounce(500) - renderChart(nextProps) { - // const colors = ['#1890FF', '#41D9C7', '#2FC25B', '#FACC14', '#9AE65C']; - const { data, height } = nextProps || this.props; - - if (data.length < 1 || !this.root) { - return; - } - - const h = height; - const w = this.root.offsetWidth; - - const onload = () => { - const dv = new DataSet.View().source(data); - const range = dv.range('value'); - const [min, max] = range; - dv.transform({ - type: 'tag-cloud', - fields: ['name', 'value'], - imageMask: this.imageMask, - font: 'Verdana', - size: [w, h], // 宽高设置最好根据 imageMask 做调整 - padding: 0, - timeInterval: 5000, // max execute time - rotate() { - return 0; - }, - fontSize(d) { - // eslint-disable-next-line - return Math.pow((d.value - min) / (max - min), 2) * (17.5 - 5) + 5; - }, - }); - - if (this.isUnmount) { - return; - } - - this.setState({ - dv, - w, - h, - }); - }; - - if (!this.imageMask) { - this.imageMask = new Image(); - this.imageMask.crossOrigin = ''; - this.imageMask.src = imgUrl; - - this.imageMask.onload = onload; - } else { - onload(); - } - } - - render() { - const { className, height } = this.props; - const { dv, w, h } = this.state; - - return ( - - {dv && ( - - - - - - )} - - ); - } -} - -export default TagCloud; diff --git a/src/components/Charts/TagCloud/index.less b/src/components/Charts/TagCloud/index.less deleted file mode 100644 index db8e4dabfdd3f1fd4566ff22f55962648c369c49..0000000000000000000000000000000000000000 --- a/src/components/Charts/TagCloud/index.less +++ /dev/null @@ -1,6 +0,0 @@ -.tagCloud { - overflow: hidden; - canvas { - transform-origin: 0 0; - } -} diff --git a/src/components/Charts/TimelineChart/index.d.ts b/src/components/Charts/TimelineChart/index.d.ts deleted file mode 100644 index 40b94325a9833e9479846b323387e6515160fb7e..0000000000000000000000000000000000000000 --- a/src/components/Charts/TimelineChart/index.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import * as React from 'react'; -export interface ITimelineChartProps { - data: Array<{ - x: number; - y1: number; - y2?: number; - }>; - titleMap: { y1: string; y2?: string }; - padding?: [number, number, number, number]; - height?: number; - style?: React.CSSProperties; -} - -export default class TimelineChart extends React.Component {} diff --git a/src/components/Charts/TimelineChart/index.js b/src/components/Charts/TimelineChart/index.js deleted file mode 100644 index d82623c5805d6df526e3ab40f42ece7202ca20ff..0000000000000000000000000000000000000000 --- a/src/components/Charts/TimelineChart/index.js +++ /dev/null @@ -1,120 +0,0 @@ -import React from 'react'; -import { Chart, Tooltip, Geom, Legend, Axis } from 'bizcharts'; -import DataSet from '@antv/data-set'; -import Slider from 'bizcharts-plugin-slider'; -import autoHeight from '../autoHeight'; -import styles from './index.less'; - -@autoHeight() -class TimelineChart extends React.Component { - render() { - const { - title, - height = 400, - padding = [60, 20, 40, 40], - titleMap = { - y1: 'y1', - y2: 'y2', - }, - borderWidth = 2, - data: sourceData, - } = this.props; - - const data = Array.isArray(sourceData) ? sourceData : [{ x: 0, y1: 0, y2: 0 }]; - - data.sort((a, b) => a.x - b.x); - - let max; - if (data[0] && data[0].y1 && data[0].y2) { - max = Math.max( - [...data].sort((a, b) => b.y1 - a.y1)[0].y1, - [...data].sort((a, b) => b.y2 - a.y2)[0].y2 - ); - } - - const ds = new DataSet({ - state: { - start: data[0].x, - end: data[data.length - 1].x, - }, - }); - - const dv = ds.createView(); - dv.source(data) - .transform({ - type: 'filter', - callback: obj => { - const date = obj.x; - return date <= ds.state.end && date >= ds.state.start; - }, - }) - .transform({ - type: 'map', - callback(row) { - const newRow = { ...row }; - newRow[titleMap.y1] = row.y1; - newRow[titleMap.y2] = row.y2; - return newRow; - }, - }) - .transform({ - type: 'fold', - fields: [titleMap.y1, titleMap.y2], // 展开字段集 - key: 'key', // key字段 - value: 'value', // value字段 - }); - - const timeScale = { - type: 'time', - tickInterval: 60 * 60 * 1000, - mask: 'HH:mm', - range: [0, 1], - }; - - const cols = { - x: timeScale, - value: { - max, - min: 0, - }, - }; - - const SliderGen = () => ( - { - ds.setState('start', startValue); - ds.setState('end', endValue); - }} - /> - ); - - return ( - - - {title && {title}} - - - - - - - - - - - - ); - } -} - -export default TimelineChart; diff --git a/src/components/Charts/TimelineChart/index.less b/src/components/Charts/TimelineChart/index.less deleted file mode 100644 index 1751975692135769eebdcaf89ffafcf6b3037cb8..0000000000000000000000000000000000000000 --- a/src/components/Charts/TimelineChart/index.less +++ /dev/null @@ -1,3 +0,0 @@ -.timelineChart { - background: #fff; -} diff --git a/src/components/Charts/WaterWave/index.d.ts b/src/components/Charts/WaterWave/index.d.ts deleted file mode 100644 index 8f5588d29f29baa7a5409eded24fb2cbe82e1c53..0000000000000000000000000000000000000000 --- a/src/components/Charts/WaterWave/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as React from 'react'; -export interface IWaterWaveProps { - title: React.ReactNode; - color?: string; - height: number; - percent: number; - style?: React.CSSProperties; -} - -export default class WaterWave extends React.Component {} diff --git a/src/components/Charts/WaterWave/index.js b/src/components/Charts/WaterWave/index.js deleted file mode 100644 index 055f7c734643eee007f6c2d96fcdc5261a206426..0000000000000000000000000000000000000000 --- a/src/components/Charts/WaterWave/index.js +++ /dev/null @@ -1,213 +0,0 @@ -import React, { PureComponent } from 'react'; -import autoHeight from '../autoHeight'; -import styles from './index.less'; - -/* eslint no-return-assign: 0 */ -/* eslint no-mixed-operators: 0 */ -// riddle: https://riddle.alibaba-inc.com/riddles/2d9a4b90 - -@autoHeight() -class WaterWave extends PureComponent { - state = { - radio: 1, - }; - - componentDidMount() { - this.renderChart(); - this.resize(); - window.addEventListener( - 'resize', - () => { - requestAnimationFrame(() => this.resize()); - }, - { passive: true } - ); - } - - componentDidUpdate(props) { - const { percent } = this.props; - if (props.percent !== percent) { - // 不加这个会造成绘制缓慢 - this.renderChart('update'); - } - } - - componentWillUnmount() { - cancelAnimationFrame(this.timer); - if (this.node) { - this.node.innerHTML = ''; - } - window.removeEventListener('resize', this.resize); - } - - resize = () => { - if (this.root) { - const { height } = this.props; - const { offsetWidth } = this.root.parentNode; - this.setState({ - radio: offsetWidth < height ? offsetWidth / height : 1, - }); - } - }; - - renderChart(type) { - const { percent, color = '#1890FF' } = this.props; - const data = percent / 100; - const self = this; - cancelAnimationFrame(this.timer); - - if (!this.node || (data !== 0 && !data)) { - return; - } - - const canvas = this.node; - const ctx = canvas.getContext('2d'); - const canvasWidth = canvas.width; - const canvasHeight = canvas.height; - const radius = canvasWidth / 2; - const lineWidth = 2; - const cR = radius - lineWidth; - - ctx.beginPath(); - ctx.lineWidth = lineWidth * 2; - - const axisLength = canvasWidth - lineWidth; - const unit = axisLength / 8; - const range = 0.2; // 振幅 - let currRange = range; - const xOffset = lineWidth; - let sp = 0; // 周期偏移量 - let currData = 0; - const waveupsp = 0.005; // 水波上涨速度 - - let arcStack = []; - const bR = radius - lineWidth; - const circleOffset = -(Math.PI / 2); - let circleLock = true; - - for (let i = circleOffset; i < circleOffset + 2 * Math.PI; i += 1 / (8 * Math.PI)) { - arcStack.push([radius + bR * Math.cos(i), radius + bR * Math.sin(i)]); - } - - const cStartPoint = arcStack.shift(); - ctx.strokeStyle = color; - ctx.moveTo(cStartPoint[0], cStartPoint[1]); - - function drawSin() { - ctx.beginPath(); - ctx.save(); - - const sinStack = []; - for (let i = xOffset; i <= xOffset + axisLength; i += 20 / axisLength) { - const x = sp + (xOffset + i) / unit; - const y = Math.sin(x) * currRange; - const dx = i; - const dy = 2 * cR * (1 - currData) + (radius - cR) - unit * y; - - ctx.lineTo(dx, dy); - sinStack.push([dx, dy]); - } - - const startPoint = sinStack.shift(); - - ctx.lineTo(xOffset + axisLength, canvasHeight); - ctx.lineTo(xOffset, canvasHeight); - ctx.lineTo(startPoint[0], startPoint[1]); - - const gradient = ctx.createLinearGradient(0, 0, 0, canvasHeight); - gradient.addColorStop(0, '#ffffff'); - gradient.addColorStop(1, color); - ctx.fillStyle = gradient; - ctx.fill(); - ctx.restore(); - } - - function render() { - ctx.clearRect(0, 0, canvasWidth, canvasHeight); - if (circleLock && type !== 'update') { - if (arcStack.length) { - const temp = arcStack.shift(); - ctx.lineTo(temp[0], temp[1]); - ctx.stroke(); - } else { - circleLock = false; - ctx.lineTo(cStartPoint[0], cStartPoint[1]); - ctx.stroke(); - arcStack = null; - - ctx.globalCompositeOperation = 'destination-over'; - ctx.beginPath(); - ctx.lineWidth = lineWidth; - ctx.arc(radius, radius, bR, 0, 2 * Math.PI, 1); - - ctx.beginPath(); - ctx.save(); - ctx.arc(radius, radius, radius - 3 * lineWidth, 0, 2 * Math.PI, 1); - - ctx.restore(); - ctx.clip(); - ctx.fillStyle = color; - } - } else { - if (data >= 0.85) { - if (currRange > range / 4) { - const t = range * 0.01; - currRange -= t; - } - } else if (data <= 0.1) { - if (currRange < range * 1.5) { - const t = range * 0.01; - currRange += t; - } - } else { - if (currRange <= range) { - const t = range * 0.01; - currRange += t; - } - if (currRange >= range) { - const t = range * 0.01; - currRange -= t; - } - } - if (data - currData > 0) { - currData += waveupsp; - } - if (data - currData < 0) { - currData -= waveupsp; - } - - sp += 0.07; - drawSin(); - } - self.timer = requestAnimationFrame(render); - } - render(); - } - - render() { - const { radio } = this.state; - const { percent, title, height } = this.props; - return ( - (this.root = n)} - style={{ transform: `scale(${radio})` }} - > - - (this.node = n)} - width={height * 2} - height={height * 2} - /> - - - {title && {title}} - {percent}% - - - ); - } -} - -export default WaterWave; diff --git a/src/components/Charts/WaterWave/index.less b/src/components/Charts/WaterWave/index.less deleted file mode 100644 index 43ba05cabd9526fa5d795b8ef840dd8b58e70afc..0000000000000000000000000000000000000000 --- a/src/components/Charts/WaterWave/index.less +++ /dev/null @@ -1,28 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.waterWave { - display: inline-block; - position: relative; - transform-origin: left; - .text { - position: absolute; - left: 0; - top: 32px; - text-align: center; - width: 100%; - span { - color: @text-color-secondary; - font-size: 14px; - line-height: 22px; - } - h4 { - color: @heading-color; - line-height: 32px; - font-size: 24px; - } - } - .waterWaveCanvasWrapper { - transform: scale(0.5); - transform-origin: 0 0; - } -} diff --git a/src/components/Charts/autoHeight.js b/src/components/Charts/autoHeight.js deleted file mode 100644 index 6ee9e098d3d926650f0f4ce6bfcd0cb3483c26ed..0000000000000000000000000000000000000000 --- a/src/components/Charts/autoHeight.js +++ /dev/null @@ -1,62 +0,0 @@ -/* eslint eqeqeq: 0 */ -import React from 'react'; - -function computeHeight(node) { - const totalHeight = parseInt(getComputedStyle(node).height, 10); - const padding = - parseInt(getComputedStyle(node).paddingTop, 10) + - parseInt(getComputedStyle(node).paddingBottom, 10); - return totalHeight - padding; -} - -function getAutoHeight(n) { - if (!n) { - return 0; - } - - let node = n; - - let height = computeHeight(node); - - while (!height) { - node = node.parentNode; - if (node) { - height = computeHeight(node); - } else { - break; - } - } - - return height; -} - -const autoHeight = () => WrappedComponent => - class extends React.Component { - state = { - computedHeight: 0, - }; - - componentDidMount() { - const { height } = this.props; - if (!height) { - const h = getAutoHeight(this.root); - // eslint-disable-next-line - this.setState({ computedHeight: h }); - } - } - - handleRoot = node => { - this.root = node; - }; - - render() { - const { height } = this.props; - const { computedHeight } = this.state; - const h = height || computedHeight; - return ( - {h > 0 && } - ); - } - }; - -export default autoHeight; diff --git a/src/components/Charts/bizcharts.d.ts b/src/components/Charts/bizcharts.d.ts deleted file mode 100644 index 0815ffeeffcacd0ac9710977ab3d4419d078491c..0000000000000000000000000000000000000000 --- a/src/components/Charts/bizcharts.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import * as BizChart from 'bizcharts'; - -export = BizChart; diff --git a/src/components/Charts/bizcharts.js b/src/components/Charts/bizcharts.js deleted file mode 100644 index e08db8d6d2dca240451bdf6ab8a30be077a3fd9d..0000000000000000000000000000000000000000 --- a/src/components/Charts/bizcharts.js +++ /dev/null @@ -1,3 +0,0 @@ -import * as BizChart from 'bizcharts'; - -export default BizChart; diff --git a/src/components/Charts/demo/bar.md b/src/components/Charts/demo/bar.md deleted file mode 100644 index 955f44e076192f6b4536fbb79cfd5a7660354f66..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/bar.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -order: 4 -title: 柱状图 ---- - -通过设置 `x`,`y` 属性,可以快速的构建出一个漂亮的柱状图,各种纬度的关系则是通过自定义的数据展现。 - -````jsx -import { Bar } from 'ant-design-pro/lib/Charts'; - -const salesData = []; -for (let i = 0; i < 12; i += 1) { - salesData.push({ - x: `${i + 1}月`, - y: Math.floor(Math.random() * 1000) + 200, - }); -} - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Charts/demo/chart-card.md b/src/components/Charts/demo/chart-card.md deleted file mode 100644 index 4da852b71442785b17d0ce07b149e4bef343dd20..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/chart-card.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -order: 1 -title: 图表卡片 ---- - -用于展示图表的卡片容器,可以方便的配合其它图表套件展示丰富信息。 - -```jsx -import { ChartCard, yuan, Field } from 'ant-design-pro/lib/Charts'; -import Trend from 'ant-design-pro/lib/Trend'; -import { Row, Col, Icon, Tooltip } from 'antd'; -import numeral from 'numeral'; - -ReactDOM.render( - - - - - - } - total={() => ( - - )} - footer={ - - } - contentHeight={46} - > - - 周同比 - - 12% - - - - 日环比 - - 11% - - - - - - - } - action={ - - - - } - total={() => ( - - )} - footer={ - - } - /> - - - - } - action={ - - - - } - total={() => ( - - )} - /> - - , - mountNode, -); -``` diff --git a/src/components/Charts/demo/gauge.md b/src/components/Charts/demo/gauge.md deleted file mode 100644 index f53465d88175446a9479e0b415f1cb816a1a00b1..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/gauge.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -order: 7 -title: 仪表盘 ---- - -仪表盘是一种进度展示方式,可以更直观的展示当前的进展情况,通常也可表示占比。 - -````jsx -import { Gauge } from 'ant-design-pro/lib/Charts'; - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Charts/demo/mini-area.md b/src/components/Charts/demo/mini-area.md deleted file mode 100644 index 2b9bfb4778fdc71f0efa25d89d64ac142a0aa079..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/mini-area.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -order: 2 -col: 2 -title: 迷你区域图 ---- - -````jsx -import { MiniArea } from 'ant-design-pro/lib/Charts'; -import moment from 'moment'; - -const visitData = []; -const beginDay = new Date().getTime(); -for (let i = 0; i < 20; i += 1) { - visitData.push({ - x: moment(new Date(beginDay + (1000 * 60 * 60 * 24 * i))).format('YYYY-MM-DD'), - y: Math.floor(Math.random() * 100) + 10, - }); -} - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Charts/demo/mini-bar.md b/src/components/Charts/demo/mini-bar.md deleted file mode 100644 index fef301bcaa537d74506b87ad6d8b75eb06d391ff..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/mini-bar.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -order: 2 -col: 2 -title: 迷你柱状图 ---- - -迷你柱状图更适合展示简单的区间数据,简洁的表现方式可以很好的减少大数据量的视觉展现压力。 - -````jsx -import { MiniBar } from 'ant-design-pro/lib/Charts'; -import moment from 'moment'; - -const visitData = []; -const beginDay = new Date().getTime(); -for (let i = 0; i < 20; i += 1) { - visitData.push({ - x: moment(new Date(beginDay + (1000 * 60 * 60 * 24 * i))).format('YYYY-MM-DD'), - y: Math.floor(Math.random() * 100) + 10, - }); -} - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Charts/demo/mini-pie.md b/src/components/Charts/demo/mini-pie.md deleted file mode 100644 index 9b1abf05912171411b13c8eeae4ec17644a6ddca..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/mini-pie.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -order: 6 -title: 迷你饼状图 ---- - -通过简化 `Pie` 属性的设置,可以快速的实现极简的饼状图,可配合 `ChartCard` 组合展 -现更多业务场景。 - -```jsx -import { Pie } from 'ant-design-pro/lib/Charts'; - -ReactDOM.render( - , - mountNode -); -``` diff --git a/src/components/Charts/demo/mini-progress.md b/src/components/Charts/demo/mini-progress.md deleted file mode 100644 index 6308a8faedb90224d50a2aee0a9f97a28dabb793..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/mini-progress.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -order: 3 -title: 迷你进度条 ---- - -````jsx -import { MiniProgress } from 'ant-design-pro/lib/Charts'; - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Charts/demo/mix.md b/src/components/Charts/demo/mix.md deleted file mode 100644 index fc64110ae4b9b16126409d51d0e8ad5afc423fd2..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/mix.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -order: 0 -title: 图表套件组合展示 ---- - -利用 Ant Design Pro 提供的图表套件,可以灵活组合符合设计规范的图表来满足复杂的业务需求。 - -````jsx -import { ChartCard, Field, MiniArea, MiniBar, MiniProgress } from 'ant-design-pro/lib/Charts'; -import Trend from 'ant-design-pro/lib/Trend'; -import NumberInfo from 'ant-design-pro/lib/NumberInfo'; -import { Row, Col, Icon, Tooltip } from 'antd'; -import numeral from 'numeral'; -import moment from 'moment'; - -const visitData = []; -const beginDay = new Date().getTime(); -for (let i = 0; i < 20; i += 1) { - visitData.push({ - x: moment(new Date(beginDay + (1000 * 60 * 60 * 24 * i))).format('YYYY-MM-DD'), - y: Math.floor(Math.random() * 100) + 10, - }); -} - -ReactDOM.render( - - - - 本周访问} - total={numeral(12321).format('0,0')} - status="up" - subTotal={17.1} - /> - - - - - } - total={numeral(8846).format('0,0')} - footer={} - contentHeight={46} - > - - - - - } - total="78%" - footer={ - - - 周同比 - 12% - - - 日环比 - 11% - - - } - contentHeight={46} - > - - - - -, mountNode); -```` diff --git a/src/components/Charts/demo/pie.md b/src/components/Charts/demo/pie.md deleted file mode 100644 index 9c87161a27e1adb1adeb0ffeff38ff01f41b8230..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/pie.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -order: 5 -title: 饼状图 ---- - -```jsx -import { Pie, yuan } from 'ant-design-pro/lib/Charts'; - -const salesPieData = [ - { - x: '家用电器', - y: 4544, - }, - { - x: '食用酒水', - y: 3321, - }, - { - x: '个护健康', - y: 3113, - }, - { - x: '服饰箱包', - y: 2341, - }, - { - x: '母婴产品', - y: 1231, - }, - { - x: '其他', - y: 1231, - }, -]; - -ReactDOM.render( - ( - now.y + pre, 0)) - }} - /> - )} - data={salesPieData} - valueFormat={val => } - height={294} - />, - mountNode, -); -``` diff --git a/src/components/Charts/demo/radar.md b/src/components/Charts/demo/radar.md deleted file mode 100644 index 584344aa3ed5dbc52d796d5043e8711c21d5650d..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/radar.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -order: 7 -title: 雷达图 ---- - -````jsx -import { Radar, ChartCard } from 'ant-design-pro/lib/Charts'; - -const radarOriginData = [ - { - name: '个人', - ref: 10, - koubei: 8, - output: 4, - contribute: 5, - hot: 7, - }, - { - name: '团队', - ref: 3, - koubei: 9, - output: 6, - contribute: 3, - hot: 1, - }, - { - name: '部门', - ref: 4, - koubei: 1, - output: 6, - contribute: 5, - hot: 7, - }, -]; -const radarData = []; -const radarTitleMap = { - ref: '引用', - koubei: '口碑', - output: '产量', - contribute: '贡献', - hot: '热度', -}; -radarOriginData.forEach((item) => { - Object.keys(item).forEach((key) => { - if (key !== 'name') { - radarData.push({ - name: item.name, - label: radarTitleMap[key], - value: item[key], - }); - } - }); -}); - -ReactDOM.render( - - - -, mountNode); -```` diff --git a/src/components/Charts/demo/tag-cloud.md b/src/components/Charts/demo/tag-cloud.md deleted file mode 100644 index c66f6fe6bf8bdafb8e31d359a9cabe401568480e..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/tag-cloud.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -order: 9 -title: 标签云 ---- - -标签云是一套相关的标签以及与此相应的权重展示方式,一般典型的标签云有 30 至 150 个标签,而权重影响使用的字体大小或其他视觉效果。 - -````jsx -import { TagCloud } from 'ant-design-pro/lib/Charts'; - -const tags = []; -for (let i = 0; i < 50; i += 1) { - tags.push({ - name: `TagClout-Title-${i}`, - value: Math.floor((Math.random() * 50)) + 20, - }); -} - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Charts/demo/timeline-chart.md b/src/components/Charts/demo/timeline-chart.md deleted file mode 100644 index 60773b575f84ce50b401a599da03c93bc7fefec2..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/timeline-chart.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -order: 9 -title: 带有时间轴的图表 ---- - -使用 `TimelineChart` 组件可以实现带有时间轴的柱状图展现,而其中的 `x` 属性,则是时间值的指向,默认最多支持同时展现两个指标,分别是 `y1` 和 `y2`。 - -````jsx -import { TimelineChart } from 'ant-design-pro/lib/Charts'; - -const chartData = []; -for (let i = 0; i < 20; i += 1) { - chartData.push({ - x: (new Date().getTime()) + (1000 * 60 * 30 * i), - y1: Math.floor(Math.random() * 100) + 1000, - y2: Math.floor(Math.random() * 100) + 10, - }); -} - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Charts/demo/waterwave.md b/src/components/Charts/demo/waterwave.md deleted file mode 100644 index 74d290f5449adb8bd3f9bf7c7202826a5b9b6b97..0000000000000000000000000000000000000000 --- a/src/components/Charts/demo/waterwave.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -order: 8 -title: 水波图 ---- - -水波图是一种比例的展示方式,可以更直观的展示关键值的占比。 - -````jsx -import { WaterWave } from 'ant-design-pro/lib/Charts'; - -ReactDOM.render( - - - -, mountNode); -```` diff --git a/src/components/Charts/g2.js b/src/components/Charts/g2.js deleted file mode 100644 index 21e22c28e70c29ecc445fcd1c1f38bde7c82311e..0000000000000000000000000000000000000000 --- a/src/components/Charts/g2.js +++ /dev/null @@ -1,15 +0,0 @@ -// 全局 G2 设置 -import { track, setTheme } from 'bizcharts'; - -track(false); - -const config = { - defaultColor: '#1089ff', - shape: { - interval: { - fillOpacity: 1, - }, - }, -}; - -setTheme(config); diff --git a/src/components/Charts/index.d.ts b/src/components/Charts/index.d.ts deleted file mode 100644 index 1ff27af291472f887b334b7eeed96d3914ff4362..0000000000000000000000000000000000000000 --- a/src/components/Charts/index.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import * as numeral from 'numeral'; -export { default as ChartCard } from './ChartCard'; -export { default as Bar } from './Bar'; -export { default as Pie } from './Pie'; -export { default as Radar } from './Radar'; -export { default as Gauge } from './Gauge'; -export { default as MiniArea } from './MiniArea'; -export { default as MiniBar } from './MiniBar'; -export { default as MiniProgress } from './MiniProgress'; -export { default as Field } from './Field'; -export { default as WaterWave } from './WaterWave'; -export { default as TagCloud } from './TagCloud'; -export { default as TimelineChart } from './TimelineChart'; - -declare const yuan: (value: number | string) => string; - -export { yuan }; diff --git a/src/components/Charts/index.js b/src/components/Charts/index.js deleted file mode 100644 index 78863fabdb7615138baf2063f1c4ed13285abade..0000000000000000000000000000000000000000 --- a/src/components/Charts/index.js +++ /dev/null @@ -1,49 +0,0 @@ -import numeral from 'numeral'; -import './g2'; -import ChartCard from './ChartCard'; -import Bar from './Bar'; -import Pie from './Pie'; -import Radar from './Radar'; -import Gauge from './Gauge'; -import MiniArea from './MiniArea'; -import MiniBar from './MiniBar'; -import MiniProgress from './MiniProgress'; -import Field from './Field'; -import WaterWave from './WaterWave'; -import TagCloud from './TagCloud'; -import TimelineChart from './TimelineChart'; - -const yuan = val => `¥ ${numeral(val).format('0,0')}`; - -const Charts = { - yuan, - Bar, - Pie, - Gauge, - Radar, - MiniBar, - MiniArea, - MiniProgress, - ChartCard, - Field, - WaterWave, - TagCloud, - TimelineChart, -}; - -export { - Charts as default, - yuan, - Bar, - Pie, - Gauge, - Radar, - MiniBar, - MiniArea, - MiniProgress, - ChartCard, - Field, - WaterWave, - TagCloud, - TimelineChart, -}; diff --git a/src/components/Charts/index.less b/src/components/Charts/index.less deleted file mode 100644 index 190428bc80d7cd7f6f22d51fd48fa37b2d44eb10..0000000000000000000000000000000000000000 --- a/src/components/Charts/index.less +++ /dev/null @@ -1,19 +0,0 @@ -.miniChart { - position: relative; - width: 100%; - .chartContent { - position: absolute; - bottom: -28px; - width: 100%; - > div { - margin: 0 -5px; - overflow: hidden; - } - } - .chartLoading { - position: absolute; - top: 16px; - left: 50%; - margin-left: -7px; - } -} diff --git a/src/components/Charts/index.md b/src/components/Charts/index.md deleted file mode 100644 index cb7c9c96e191d47fe2dac084c25cb194f3c169c0..0000000000000000000000000000000000000000 --- a/src/components/Charts/index.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: - en-US: Charts - zh-CN: Charts -subtitle: 图表 -order: 2 -cols: 2 ---- - -Ant Design Pro 提供的业务中常用的图表类型,都是基于 [G2](https://antv.alipay.com/g2/doc/index.html) 按照 Ant Design 图表规范封装,需要注意的是 Ant Design Pro 的图表组件以套件形式提供,可以任意组合实现复杂的业务需求。 - -因为结合了 Ant Design 的标准设计,本着极简的设计思想以及开箱即用的理念,简化了大量 API 配置,所以如果需要灵活定制图表,可以参考 Ant Design Pro 图表实现,自行基于 [G2](https://antv.alipay.com/g2/doc/index.html) 封装图表组件使用。 - -## API - -### ChartCard - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| title | 卡片标题 | ReactNode\|string | - | -| action | 卡片操作 | ReactNode | - | -| total | 数据总量 | ReactNode \| number \| function | - | -| footer | 卡片底部 | ReactNode | - | -| contentHeight | 内容区域高度 | number | - | -| avatar | 右侧图标 | React.ReactNode | - | -### MiniBar - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| color | 图表颜色 | string | `#1890FF` | -| height | 图表高度 | number | - | -| data | 数据 | array<{x, y}> | - | - -### MiniArea - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| color | 图表颜色 | string | `rgba(24, 144, 255, 0.2)` | -| borderColor | 图表边颜色 | string | `#1890FF` | -| height | 图表高度 | number | - | -| line | 是否显示描边 | boolean | false | -| animate | 是否显示动画 | boolean | true | -| xAxis | [x 轴配置](http://antvis.github.io/g2/doc/tutorial/start/axis.html) | object | - | -| yAxis | [y 轴配置](http://antvis.github.io/g2/doc/tutorial/start/axis.html) | object | - | -| data | 数据 | array<{x, y}> | - | - -### MiniProgress - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| target | 目标比例 | number | - | -| color | 进度条颜色 | string | - | -| strokeWidth | 进度条高度 | number | - | -| percent | 进度比例 | number | - | - -### Bar - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| title | 图表标题 | ReactNode\|string | - | -| color | 图表颜色 | string | `rgba(24, 144, 255, 0.85)` | -| padding | 图表内部间距 | [array](https://github.com/alibaba/BizCharts/blob/master/doc/api/chart.md#7padding-object--number--array-) | `'auto'` | -| height | 图表高度 | number | - | -| data | 数据 | array<{x, y}> | - | -| autoLabel | 在宽度不足时,自动隐藏 x 轴的 label | boolean | `true` | - -### Pie - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| animate | 是否显示动画 | boolean | true | -| color | 图表颜色 | string | `rgba(24, 144, 255, 0.85)` | -| height | 图表高度 | number | - | -| hasLegend | 是否显示 legend | boolean | `false` | -| padding | 图表内部间距 | [array](https://github.com/alibaba/BizCharts/blob/master/doc/api/chart.md#7padding-object--number--array-) | `'auto'` | -| percent | 占比 | number | - | -| tooltip | 是否显示 tooltip | boolean | true | -| valueFormat | 显示值的格式化函数 | function | - | -| title | 图表标题 | ReactNode\|string | - | -| subTitle | 图表子标题 | ReactNode\|string | - | -| total | 图标中央的总数 | string | function | - | - -### Radar - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| title | 图表标题 | ReactNode\|string | - | -| height | 图表高度 | number | - | -| hasLegend | 是否显示 legend | boolean | `false` | -| padding | 图表内部间距 | [array](https://github.com/alibaba/BizCharts/blob/master/doc/api/chart.md#7padding-object--number--array-) | `'auto'` | -| data | 图标数据 | array<{name,label,value}> | - | - -### Gauge - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| title | 图表标题 | ReactNode\|string | - | -| height | 图表高度 | number | - | -| color | 图表颜色 | string | `#2F9CFF` | -| bgColor | 图表背景颜色 | string | `#F0F2F5` | -| percent | 进度比例 | number | - | - -### WaterWave - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| title | 图表标题 | ReactNode\|string | - | -| height | 图表高度 | number | - | -| color | 图表颜色 | string | `#1890FF` | -| percent | 进度比例 | number | - | - -### TagCloud - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| data | 标题 | Array | - | -| height | 高度值 | number | - | - -### TimelineChart - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| data | 标题 | Array | - | -| titleMap | 指标别名 | Object{y1: '客流量', y2: '支付笔数'} | - | -| height | 高度值 | number | 400 | - -### Field - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| label | 标题 | ReactNode\|string | - | -| value | 值 | ReactNode\|string | - | diff --git a/src/components/CountDown/demo/simple.md b/src/components/CountDown/demo/simple.md deleted file mode 100644 index e42cbf1d99caab99f7c986600717ed08d5df63e3..0000000000000000000000000000000000000000 --- a/src/components/CountDown/demo/simple.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -order: 0 -title: - zh-CN: 基本 - en-US: Basic ---- - -## zh-CN - -简单的倒计时组件使用。 - -## en-US - -The simplest usage. - -````jsx -import CountDown from 'ant-design-pro/lib/CountDown'; - -const targetTime = new Date().getTime() + 3900000; - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/CountDown/index.d.ts b/src/components/CountDown/index.d.ts deleted file mode 100644 index d39a2e951830d5cddca08c8becbdb500847448b3..0000000000000000000000000000000000000000 --- a/src/components/CountDown/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import * as React from 'react'; -export interface ICountDownProps { - format?: (time: number) => void; - target: Date | number; - onEnd?: () => void; - style?: React.CSSProperties; -} - -export default class CountDown extends React.Component {} diff --git a/src/components/CountDown/index.en-US.md b/src/components/CountDown/index.en-US.md deleted file mode 100644 index 7b452406b3528ccfb14fe3bdecb0ead9a2df4e6f..0000000000000000000000000000000000000000 --- a/src/components/CountDown/index.en-US.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: CountDown -cols: 1 -order: 3 ---- - -Simple CountDown Component. - -## API - -| Property | Description | Type | Default | -|----------|------------------------------------------|-------------|-------| -| format | Formatter of time | Function(time) | | -| target | Target time | Date | - | -| onEnd | Countdown to the end callback | funtion | -| diff --git a/src/components/CountDown/index.js b/src/components/CountDown/index.js deleted file mode 100644 index 7565bd82da8c6331840861a1dc7bc3b49fad947f..0000000000000000000000000000000000000000 --- a/src/components/CountDown/index.js +++ /dev/null @@ -1,121 +0,0 @@ -import React, { Component } from 'react'; - -function fixedZero(val) { - return val * 1 < 10 ? `0${val}` : val; -} -const initTime = props => { - let lastTime = 0; - let targetTime = 0; - try { - if (Object.prototype.toString.call(props.target) === '[object Date]') { - targetTime = props.target.getTime(); - } else { - targetTime = new Date(props.target).getTime(); - } - } catch (e) { - throw new Error('invalid target prop', e); - } - - lastTime = targetTime - new Date().getTime(); - return { - lastTime: lastTime < 0 ? 0 : lastTime, - }; -}; - -class CountDown extends Component { - timer = 0; - - interval = 1000; - - constructor(props) { - super(props); - const { lastTime } = initTime(props); - this.state = { - lastTime, - }; - } - - static getDerivedStateFromProps(nextProps, preState) { - const { lastTime } = initTime(nextProps); - if (preState.lastTime !== lastTime) { - return { - lastTime, - }; - } - return null; - } - - componentDidMount() { - this.tick(); - } - - componentDidUpdate(prevProps) { - const { target } = this.props; - if (target !== prevProps.target) { - clearTimeout(this.timer); - this.tick(); - } - } - - componentWillUnmount() { - clearTimeout(this.timer); - } - - // defaultFormat = time => ( - // {moment(time).format('hh:mm:ss')} - // ); - defaultFormat = time => { - const hours = 60 * 60 * 1000; - const minutes = 60 * 1000; - - const h = Math.floor(time / hours); - const m = Math.floor((time - h * hours) / minutes); - const s = Math.floor((time - h * hours - m * minutes) / 1000); - return ( - - {fixedZero(h)}:{fixedZero(m)}:{fixedZero(s)} - - ); - }; - - tick = () => { - const { onEnd } = this.props; - let { lastTime } = this.state; - - this.timer = setTimeout(() => { - if (lastTime < this.interval) { - clearTimeout(this.timer); - this.setState( - { - lastTime: 0, - }, - () => { - if (onEnd) { - onEnd(); - } - } - ); - } else { - lastTime -= this.interval; - this.setState( - { - lastTime, - }, - () => { - this.tick(); - } - ); - } - }, this.interval); - }; - - render() { - const { format = this.defaultFormat, onEnd, ...rest } = this.props; - const { lastTime } = this.state; - const result = format(lastTime); - - return {result}; - } -} - -export default CountDown; diff --git a/src/components/CountDown/index.zh-CN.md b/src/components/CountDown/index.zh-CN.md deleted file mode 100644 index 7e00ba1da5f3ed633dd2d2dc9c81b5acfc30c3fa..0000000000000000000000000000000000000000 --- a/src/components/CountDown/index.zh-CN.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: CountDown -subtitle: 倒计时 -cols: 1 -order: 3 ---- - -倒计时组件。 - -## API - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| format | 时间格式化显示 | Function(time) | | -| target | 目标时间 | Date | - | -| onEnd | 倒计时结束回调 | funtion | -| diff --git a/src/components/DescriptionList/Description.d.ts b/src/components/DescriptionList/Description.d.ts deleted file mode 100644 index 2a17be374accc8e2a1ffa9812327398a6c3f7173..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/Description.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import * as React from 'react'; - -export default class Description extends React.Component< - { - term: React.ReactNode; - style?: React.CSSProperties; - }, - any -> {} diff --git a/src/components/DescriptionList/Description.js b/src/components/DescriptionList/Description.js deleted file mode 100644 index fce9fd3cb7debf4551bae22dcfc48eefb176d959..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/Description.js +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { Col } from 'antd'; -import styles from './index.less'; -import responsive from './responsive'; - -const Description = ({ term, column, children, ...restProps }) => ( - - {term && {term}} - {children !== null && children !== undefined && {children}} - -); - -Description.defaultProps = { - term: '', -}; - -Description.propTypes = { - term: PropTypes.node, -}; - -export default Description; diff --git a/src/components/DescriptionList/DescriptionList.js b/src/components/DescriptionList/DescriptionList.js deleted file mode 100644 index 84bdbd79d3dd52c62833c16783010825ecdbd0c1..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/DescriptionList.js +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; -import classNames from 'classnames'; -import { Row } from 'antd'; -import styles from './index.less'; - -const DescriptionList = ({ - className, - title, - col = 3, - layout = 'horizontal', - gutter = 32, - children, - size, - ...restProps -}) => { - const clsString = classNames(styles.descriptionList, styles[layout], className, { - [styles.small]: size === 'small', - [styles.large]: size === 'large', - }); - const column = col > 4 ? 4 : col; - return ( - - {title ? {title} : null} - - {React.Children.map(children, child => - child ? React.cloneElement(child, { column }) : child - )} - - - ); -}; - -export default DescriptionList; diff --git a/src/components/DescriptionList/demo/basic.md b/src/components/DescriptionList/demo/basic.md deleted file mode 100644 index 87954551e6fa564d56d327d4ca330f43f5e6c1b7..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/demo/basic.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -order: 0 -title: - zh-CN: 基本 - en-US: Basic ---- - -## zh-CN - -基本描述列表。 - -## en-US - -Basic DescriptionList. - -````jsx -import DescriptionList from 'ant-design-pro/lib/DescriptionList'; - -const { Description } = DescriptionList; - -ReactDOM.render( - - - A free, open source, cross-platform, - graphical web browser developed by the - Mozilla Corporation and hundreds of - volunteers. - - - A free, open source, cross-platform, - graphical web browser developed by the - Mozilla Corporation and hundreds of - volunteers. - - - A free, open source, cross-platform, - graphical web browser developed by the - Mozilla Corporation and hundreds of - volunteers. - - -, mountNode); -```` diff --git a/src/components/DescriptionList/demo/vertical.md b/src/components/DescriptionList/demo/vertical.md deleted file mode 100644 index 2742f7c9f6b0a907570617ab422b5341a2151a4b..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/demo/vertical.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -order: 1 -title: - zh-CN: 垂直型 - en-US: Vertical ---- - -## zh-CN - -垂直布局。 - -## en-US - -Vertical layout. - -````jsx -import DescriptionList from 'ant-design-pro/lib/DescriptionList'; - -const { Description } = DescriptionList; - -ReactDOM.render( - - - A free, open source, cross-platform, - graphical web browser developed by the - Mozilla Corporation and hundreds of - volunteers. - - - A free, open source, cross-platform, - graphical web browser developed by the - Mozilla Corporation and hundreds of - volunteers. - - - A free, open source, cross-platform, - graphical web browser developed by the - Mozilla Corporation and hundreds of - volunteers. - - -, mountNode); -```` diff --git a/src/components/DescriptionList/index.d.ts b/src/components/DescriptionList/index.d.ts deleted file mode 100644 index 96ccfa7da3a21d790e3348a65603488303780669..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/index.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from 'react'; -import Description from './Description'; - -export interface IDescriptionListProps { - layout?: 'horizontal' | 'vertical'; - col?: number; - title: React.ReactNode; - gutter?: number; - size?: 'large' | 'small'; - style?: React.CSSProperties; -} - -export default class DescriptionList extends React.Component { - public static Description: typeof Description; -} diff --git a/src/components/DescriptionList/index.en-US.md b/src/components/DescriptionList/index.en-US.md deleted file mode 100644 index 089f30b1a1502bd6bfd8754821870e5db5df55ac..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/index.en-US.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: DescriptionList -cols: 1 -order: 4 ---- - -Groups display multiple read-only fields, which are common to informational displays on detail pages. - -## API - -### DescriptionList - -| Property | Description | Type | Default | -|----------|------------------------------------------|-------------|---------| -| layout | type of layout | Enum{'horizontal', 'vertical'} | 'horizontal' | -| col | specify the maximum number of columns to display, the final columns number is determined by col setting combined with [Responsive Rules](/components/DescriptionList#Responsive-Rules) | number(0 < col <= 4) | 3 | -| title | title | ReactNode | - | -| gutter | specify the distance between two items, unit is `px` | number | 32 | -| size | size of list | Enum{'large', 'small'} | - | - -#### Responsive Rules - -| Window Width | Columns Number | -|---------------------|---------------------------------------------| -| `≥768px` | `col` | -| `≥576px` | `col < 2 ? col : 2` | -| `<576px` | `1` | - -### DescriptionList.Description - -| Property | Description | Type | Default | -|----------|------------------------------------------|-------------|-------| -| term | item title | ReactNode | - | diff --git a/src/components/DescriptionList/index.js b/src/components/DescriptionList/index.js deleted file mode 100644 index 357f479fd5b279ad9e6141c8c70ae73310e373c3..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import DescriptionList from './DescriptionList'; -import Description from './Description'; - -DescriptionList.Description = Description; -export default DescriptionList; diff --git a/src/components/DescriptionList/index.less b/src/components/DescriptionList/index.less deleted file mode 100644 index bfb33fcc3f14e47bf03549f3e68dc11f86f184f2..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/index.less +++ /dev/null @@ -1,77 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.descriptionList { - // offset the padding-bottom of last row - :global { - .ant-row { - margin-bottom: -16px; - overflow: hidden; - } - } - - .title { - font-size: 14px; - color: @heading-color; - font-weight: 500; - margin-bottom: 16px; - } - - .term { - // Line-height is 22px IE dom height will calculate error - line-height: 20px; - padding-bottom: 16px; - margin-right: 8px; - color: @heading-color; - white-space: nowrap; - display: table-cell; - - &:after { - content: ':'; - margin: 0 8px 0 2px; - position: relative; - top: -0.5px; - } - } - - .detail { - line-height: 20px; - width: 100%; - padding-bottom: 16px; - color: @text-color; - display: table-cell; - } - - &.small { - // offset the padding-bottom of last row - :global { - .ant-row { - margin-bottom: -8px; - } - } - .title { - margin-bottom: 12px; - color: @text-color; - } - .term, - .detail { - padding-bottom: 8px; - } - } - - &.large { - .title { - font-size: 16px; - } - } - - &.vertical { - .term { - padding-bottom: 8px; - display: block; - } - - .detail { - display: block; - } - } -} diff --git a/src/components/DescriptionList/index.zh-CN.md b/src/components/DescriptionList/index.zh-CN.md deleted file mode 100644 index b16a7fe76907bdffb1fa20c53ac1ba72552f19d3..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/index.zh-CN.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: DescriptionList -subtitle: 描述列表 -cols: 1 -order: 4 ---- - -成组展示多个只读字段,常见于详情页的信息展示。 - -## API - -### DescriptionList - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| layout | 布局方式 | Enum{'horizontal', 'vertical'} | 'horizontal' | -| col | 指定信息最多分几列展示,最终一行几列由 col 配置结合[响应式规则](/components/DescriptionList#响应式规则)决定 | number(0 < col <= 4) | 3 | -| title | 列表标题 | ReactNode | - | -| gutter | 列表项间距,单位为 `px` | number | 32 | -| size | 列表型号 | Enum{'large', 'small'} | - | - -#### 响应式规则 - -| 窗口宽度 | 展示列数 | -|---------------------|---------------------------------------------| -| `≥768px` | `col` | -| `≥576px` | `col < 2 ? col : 2` | -| `<576px` | `1` | - -### DescriptionList.Description - -| 参数 | 说明 | 类型 | 默认值 | -|----------|------------------------------------------|-------------|-------| -| term | 列表项标题 | ReactNode | - | - - - diff --git a/src/components/DescriptionList/responsive.js b/src/components/DescriptionList/responsive.js deleted file mode 100644 index a5aa73f781e3eccdbae4dffd656e201589575554..0000000000000000000000000000000000000000 --- a/src/components/DescriptionList/responsive.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - 1: { xs: 24 }, - 2: { xs: 24, sm: 12 }, - 3: { xs: 24, sm: 12, md: 8 }, - 4: { xs: 24, sm: 12, md: 6 }, -}; diff --git a/src/components/EditableItem/index.js b/src/components/EditableItem/index.js deleted file mode 100644 index 40034d0ac9d870967f9248dc34986fb085229278..0000000000000000000000000000000000000000 --- a/src/components/EditableItem/index.js +++ /dev/null @@ -1,50 +0,0 @@ -import React, { PureComponent } from 'react'; -import { Input, Icon } from 'antd'; -import styles from './index.less'; - -export default class EditableItem extends PureComponent { - constructor(props) { - super(props); - this.state = { - value: props.value, - editable: false, - }; - } - - handleChange = e => { - const { value } = e.target; - this.setState({ value }); - }; - - check = () => { - this.setState({ editable: false }); - const { value } = this.state; - const { onChange } = this.props; - if (onChange) { - onChange(value); - } - }; - - edit = () => { - this.setState({ editable: true }); - }; - - render() { - const { value, editable } = this.state; - return ( - - {editable ? ( - - - - - ) : ( - - {value || ' '} - - - )} - - ); - } -} diff --git a/src/components/EditableItem/index.less b/src/components/EditableItem/index.less deleted file mode 100644 index 457a18bd4b9b4775a5eb5619c8f80f212d1467f7..0000000000000000000000000000000000000000 --- a/src/components/EditableItem/index.less +++ /dev/null @@ -1,25 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.editableItem { - line-height: @input-height-base; - display: table; - width: 100%; - margin-top: (@font-size-base * @line-height-base - @input-height-base) / 2; - - .wrapper { - display: table-row; - - & > * { - display: table-cell; - } - - & > *:first-child { - width: 85%; - } - - .icon { - cursor: pointer; - text-align: right; - } - } -} diff --git a/src/components/Ellipsis/demo/line.md b/src/components/Ellipsis/demo/line.md deleted file mode 100644 index bc31170dc317f3f9a942fd041fd16350aba60858..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/demo/line.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -order: 1 -title: - zh-CN: 按照行数省略 - en-US: Truncate according to the number of rows ---- - -## zh-CN - -通过设置 `lines` 属性指定最大行数,如果超过这个行数的文本会自动截取。但是在这种模式下所有 `children` 将会被转换成纯文本。 - -并且注意在这种模式下,外容器需要有指定的宽度(或设置自身宽度)。 - -## en-US - -`lines` attribute specifies the maximum number of rows where the text will automatically be truncated when exceeded. In this mode, all children will be converted to plain text. - -Also note that, in this mode, the outer container needs to have a specified width (or set its own width). - - -````jsx -import Ellipsis from 'ant-design-pro/lib/Ellipsis'; - -const article = There were injuries alleged in three cases in 2015, and a fourth incident in September, according to the safety recall report. After meeting with US regulators in October, the firm decided to issue a voluntary recall.; - -ReactDOM.render( - - {article} - -, mountNode); -```` diff --git a/src/components/Ellipsis/demo/number.md b/src/components/Ellipsis/demo/number.md deleted file mode 100644 index 0bc1a0ff7847711f27ac85aa98ae222d14904be4..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/demo/number.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -order: 0 -title: - zh-CN: 按照字符数省略 - en-US: Truncate according to the number of character ---- - -## zh-CN - -通过设置 `length` 属性指定文本最长长度,如果超过这个长度会自动截取。 - -## en-US - -`length` attribute specifies the maximum length where the text will automatically be truncated when exceeded. - -````jsx -import Ellipsis from 'ant-design-pro/lib/Ellipsis'; - -const article = 'There were injuries alleged in three cases in 2015, and a fourth incident in September, according to the safety recall report. After meeting with US regulators in October, the firm decided to issue a voluntary recall.'; - -ReactDOM.render( - - {article} - Show Tooltip - {article} - -, mountNode); -```` diff --git a/src/components/Ellipsis/index.d.ts b/src/components/Ellipsis/index.d.ts deleted file mode 100644 index 37d508d77335048de87287fc52fb9f457e89dc33..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/index.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from 'react'; -import { TooltipProps } from 'antd/lib/tooltip'; - -export interface IEllipsisTooltipProps extends TooltipProps { - title?: undefined; - overlayStyle?: undefined; -} - -export interface IEllipsisProps { - tooltip?: boolean | IEllipsisTooltipProps; - length?: number; - lines?: number; - style?: React.CSSProperties; - className?: string; - fullWidthRecognition?: boolean; -} - -export function getStrFullLength(str: string): number; -export function cutStrByFullLength(str: string, maxLength: number): string; - -export default class Ellipsis extends React.Component {} diff --git a/src/components/Ellipsis/index.en-US.md b/src/components/Ellipsis/index.en-US.md deleted file mode 100644 index 15139cc9dc13e1f0db7c50f942d884761ed82fec..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/index.en-US.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Ellipsis -cols: 1 -order: 10 ---- - -When the text is too long, the Ellipsis automatically shortens it according to its length or the maximum number of lines. - -## API - -Property | Description | Type | Default -----|------|-----|------ -tooltip | tooltip for showing the full text content when hovering over | boolean | - -length | maximum number of characters in the text before being truncated | number | - -lines | maximum number of rows in the text before being truncated | number | `1` -fullWidthRecognition | whether consider full-width character length as 2 when calculate string length | boolean | - diff --git a/src/components/Ellipsis/index.js b/src/components/Ellipsis/index.js deleted file mode 100644 index de700b74b192b5c634ee88a0fc5533f59a504ab5..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/index.js +++ /dev/null @@ -1,270 +0,0 @@ -import React, { Component } from 'react'; -import { Tooltip } from 'antd'; -import classNames from 'classnames'; -import styles from './index.less'; - -/* eslint react/no-did-mount-set-state: 0 */ -/* eslint no-param-reassign: 0 */ - -const isSupportLineClamp = document.body.style.webkitLineClamp !== undefined; - -const TooltipOverlayStyle = { - overflowWrap: 'break-word', - wordWrap: 'break-word', -}; - -export const getStrFullLength = (str = '') => - str.split('').reduce((pre, cur) => { - const charCode = cur.charCodeAt(0); - if (charCode >= 0 && charCode <= 128) { - return pre + 1; - } - return pre + 2; - }, 0); - -export const cutStrByFullLength = (str = '', maxLength) => { - let showLength = 0; - return str.split('').reduce((pre, cur) => { - const charCode = cur.charCodeAt(0); - if (charCode >= 0 && charCode <= 128) { - showLength += 1; - } else { - showLength += 2; - } - if (showLength <= maxLength) { - return pre + cur; - } - return pre; - }, ''); -}; - -const getTooltip = ({ tooltip, overlayStyle, title, children }) => { - if (tooltip) { - const props = tooltip === true ? { overlayStyle, title } : { ...tooltip, overlayStyle, title }; - return {children}; - } - return children; -}; - -const EllipsisText = ({ text, length, tooltip, fullWidthRecognition, ...other }) => { - if (typeof text !== 'string') { - throw new Error('Ellipsis children must be string.'); - } - const textLength = fullWidthRecognition ? getStrFullLength(text) : text.length; - if (textLength <= length || length < 0) { - return {text}; - } - const tail = '...'; - let displayText; - if (length - tail.length <= 0) { - displayText = ''; - } else { - displayText = fullWidthRecognition ? cutStrByFullLength(text, length) : text.slice(0, length); - } - - const spanAttrs = tooltip ? {} : { ...other }; - return getTooltip({ - tooltip, - overlayStyle: TooltipOverlayStyle, - title: text, - children: ( - - {displayText} - {tail} - - ), - }); -}; - -export default class Ellipsis extends Component { - state = { - text: '', - targetCount: 0, - }; - - componentDidMount() { - if (this.node) { - this.computeLine(); - } - } - - componentDidUpdate(perProps) { - const { lines } = this.props; - if (lines !== perProps.lines) { - this.computeLine(); - } - } - - computeLine = () => { - const { lines } = this.props; - if (lines && !isSupportLineClamp) { - const text = this.shadowChildren.innerText || this.shadowChildren.textContent; - const lineHeight = parseInt(getComputedStyle(this.root).lineHeight, 10); - const targetHeight = lines * lineHeight; - this.content.style.height = `${targetHeight}px`; - const totalHeight = this.shadowChildren.offsetHeight; - const shadowNode = this.shadow.firstChild; - - if (totalHeight <= targetHeight) { - this.setState({ - text, - targetCount: text.length, - }); - return; - } - - // bisection - const len = text.length; - const mid = Math.ceil(len / 2); - - const count = this.bisection(targetHeight, mid, 0, len, text, shadowNode); - - this.setState({ - text, - targetCount: count, - }); - } - }; - - bisection = (th, m, b, e, text, shadowNode) => { - const suffix = '...'; - let mid = m; - let end = e; - let begin = b; - shadowNode.innerHTML = text.substring(0, mid) + suffix; - let sh = shadowNode.offsetHeight; - - if (sh <= th) { - shadowNode.innerHTML = text.substring(0, mid + 1) + suffix; - sh = shadowNode.offsetHeight; - if (sh > th || mid === begin) { - return mid; - } - begin = mid; - if (end - begin === 1) { - mid = 1 + begin; - } else { - mid = Math.floor((end - begin) / 2) + begin; - } - return this.bisection(th, mid, begin, end, text, shadowNode); - } - if (mid - 1 < 0) { - return mid; - } - shadowNode.innerHTML = text.substring(0, mid - 1) + suffix; - sh = shadowNode.offsetHeight; - if (sh <= th) { - return mid - 1; - } - end = mid; - mid = Math.floor((end - begin) / 2) + begin; - return this.bisection(th, mid, begin, end, text, shadowNode); - }; - - handleRoot = n => { - this.root = n; - }; - - handleContent = n => { - this.content = n; - }; - - handleNode = n => { - this.node = n; - }; - - handleShadow = n => { - this.shadow = n; - }; - - handleShadowChildren = n => { - this.shadowChildren = n; - }; - - render() { - const { text, targetCount } = this.state; - const { - children, - lines, - length, - className, - tooltip, - fullWidthRecognition, - ...restProps - } = this.props; - - const cls = classNames(styles.ellipsis, className, { - [styles.lines]: lines && !isSupportLineClamp, - [styles.lineClamp]: lines && isSupportLineClamp, - }); - - if (!lines && !length) { - return ( - - {children} - - ); - } - - // length - if (!lines) { - return ( - - ); - } - - const id = `antd-pro-ellipsis-${`${new Date().getTime()}${Math.floor(Math.random() * 100)}`}`; - - // support document.body.style.webkitLineClamp - if (isSupportLineClamp) { - const style = `#${id}{-webkit-line-clamp:${lines};-webkit-box-orient: vertical;}`; - - const node = ( - - - {children} - - ); - - return getTooltip({ - tooltip, - overlayStyle: TooltipOverlayStyle, - title: children, - children: node, - }); - } - - const childNode = ( - - {targetCount > 0 && text.substring(0, targetCount)} - {targetCount > 0 && targetCount < text.length && '...'} - - ); - - return ( - - - {getTooltip({ - tooltip, - overlayStyle: TooltipOverlayStyle, - title: text, - children: childNode, - })} - - {children} - - - {text} - - - - ); - } -} diff --git a/src/components/Ellipsis/index.less b/src/components/Ellipsis/index.less deleted file mode 100644 index 2c4a867c1582a6725004510656729ece8167f0b1..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/index.less +++ /dev/null @@ -1,24 +0,0 @@ -.ellipsis { - overflow: hidden; - display: inline-block; - word-break: break-all; - width: 100%; -} - -.lines { - position: relative; - .shadow { - display: block; - position: absolute; - color: transparent; - opacity: 0; - z-index: -999; - } -} - -.lineClamp { - position: relative; - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; -} diff --git a/src/components/Ellipsis/index.test.js b/src/components/Ellipsis/index.test.js deleted file mode 100644 index 4d057b24e7f726f25165dcae7ec9cd064f577f11..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/index.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import { getStrFullLength, cutStrByFullLength } from './index'; - -describe('test calculateShowLength', () => { - it('get full length', () => { - expect(getStrFullLength('一二,a,')).toEqual(8); - }); - it('cut str by full length', () => { - expect(cutStrByFullLength('一二,a,', 7)).toEqual('一二,a'); - }); - it('cut str when length small', () => { - expect(cutStrByFullLength('一22三', 5)).toEqual('一22'); - }); -}); diff --git a/src/components/Ellipsis/index.zh-CN.md b/src/components/Ellipsis/index.zh-CN.md deleted file mode 100644 index f7a70eadd41a8251e76dbe4bcebdb909cdafbc43..0000000000000000000000000000000000000000 --- a/src/components/Ellipsis/index.zh-CN.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Ellipsis -subtitle: 文本自动省略号 -cols: 1 -order: 10 ---- - -文本过长自动处理省略号,支持按照文本长度和最大行数两种方式截取。 - -## API - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -tooltip | 移动到文本展示完整内容的提示 | boolean | - -length | 在按照长度截取下的文本最大字符数,超过则截取省略 | number | - -lines | 在按照行数截取下最大的行数,超过则截取省略 | number | `1` -fullWidthRecognition | 是否将全角字符的长度视为2来计算字符串长度 | boolean | - diff --git a/src/components/Exception/demo/403.md b/src/components/Exception/demo/403.md deleted file mode 100644 index bb46037fea8daa2732c466c26c54f45a47d0fe22..0000000000000000000000000000000000000000 --- a/src/components/Exception/demo/403.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -order: 2 -title: - zh-CN: 403 - en-US: 403 ---- - -## zh-CN - -403 页面,配合自定义操作。 - -## en-US - -403 page with custom operations. - -````jsx -import Exception from 'ant-design-pro/lib/Exception'; -import { Button } from 'antd'; - -const actions = ( - - Home - Detail - -); -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Exception/demo/404.md b/src/components/Exception/demo/404.md deleted file mode 100644 index db50de653eb2acb08c5ed4a0aa83ee3ff73e3180..0000000000000000000000000000000000000000 --- a/src/components/Exception/demo/404.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -order: 0 -title: - zh-CN: 404 - en-US: 404 ---- - -## zh-CN - -404 页面。 - -## en-US - -404 page. - -````jsx -import Exception from 'ant-design-pro/lib/Exception'; - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Exception/demo/500.md b/src/components/Exception/demo/500.md deleted file mode 100644 index 096ca8e511d2b19c952a68a9d1c8da606e747b28..0000000000000000000000000000000000000000 --- a/src/components/Exception/demo/500.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -order: 1 -title: - zh-CN: 500 - en-US: 500 ---- - -## zh-CN - -500 页面。 - -## en-US - -500 page. - -````jsx -import Exception from 'ant-design-pro/lib/Exception'; - -ReactDOM.render( - -, mountNode); -```` diff --git a/src/components/Exception/index.d.ts b/src/components/Exception/index.d.ts deleted file mode 100644 index a74abb1fa6334cb2b8ef987aab5a1b5dc1f0d531..0000000000000000000000000000000000000000 --- a/src/components/Exception/index.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as React from 'react'; -export interface IExceptionProps { - type?: '403' | '404' | '500'; - title?: React.ReactNode; - desc?: React.ReactNode; - img?: string; - actions?: React.ReactNode; - linkElement?: string | React.ComponentType; - style?: React.CSSProperties; - className?: string; - backText?: React.ReactNode; - redirect?: string; -} - -export default class Exception extends React.Component {} diff --git a/src/components/Exception/index.en-US.md b/src/components/Exception/index.en-US.md deleted file mode 100644 index 37e7e80756fb7517239658775e4ce5ef170dcb21..0000000000000000000000000000000000000000 --- a/src/components/Exception/index.en-US.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Exception -cols: 1 -order: 5 ---- - -Exceptions page is used to provide feedback on specific abnormal state. Usually, it contains an explanation of the error status, and provides users with suggestions or operations, to prevent users from feeling lost and confused. - -## API - -Property | Description | Type | Default ----------|-------------|------|-------- -| backText | default return button text | ReactNode | back to home | -type | type of exception, the corresponding default `title`, `desc`, `img` will be given if set, which can be overridden by explicit setting of `title`, `desc`, `img` | Enum {'403', '404', '500'} | - -title | title | ReactNode | - -desc | supplementary description | ReactNode | - -img | the url of background image | string | - -actions | suggested operations, a default 'Home' link will show if not set | ReactNode | - -linkElement | to specify the element of link | string\|ReactElement | 'a' -redirect | redirect path | string | '/' \ No newline at end of file diff --git a/src/components/Exception/index.js b/src/components/Exception/index.js deleted file mode 100644 index 2c7223cc7655ce457ef1c597dc3fe8ef86b49c49..0000000000000000000000000000000000000000 --- a/src/components/Exception/index.js +++ /dev/null @@ -1,61 +0,0 @@ -import React, { createElement } from 'react'; -import classNames from 'classnames'; -import { Button } from 'antd'; -import config from './typeConfig'; -import styles from './index.less'; - -class Exception extends React.PureComponent { - static defaultProps = { - backText: 'back to home', - redirect: '/', - }; - - constructor(props) { - super(props); - this.state = {}; - } - - render() { - const { - className, - backText, - linkElement = 'a', - type, - title, - desc, - img, - actions, - redirect, - ...rest - } = this.props; - const pageType = type in config ? type : '404'; - const clsString = classNames(styles.exception, className); - return ( - - - - - - {title || config[pageType].title} - {desc || config[pageType].desc} - - {actions || - createElement( - linkElement, - { - to: redirect, - href: redirect, - }, - {backText} - )} - - - - ); - } -} - -export default Exception; diff --git a/src/components/Exception/index.less b/src/components/Exception/index.less deleted file mode 100644 index b55fe3a928020e82b2c80f0adb7ebc4fb55eecec..0000000000000000000000000000000000000000 --- a/src/components/Exception/index.less +++ /dev/null @@ -1,89 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.exception { - display: flex; - align-items: center; - height: 80%; - min-height: 500px; - - .imgBlock { - flex: 0 0 62.5%; - width: 62.5%; - padding-right: 152px; - zoom: 1; - &:before, - &:after { - content: ' '; - display: table; - } - &:after { - clear: both; - visibility: hidden; - font-size: 0; - height: 0; - } - } - - .imgEle { - height: 360px; - width: 100%; - max-width: 430px; - float: right; - background-repeat: no-repeat; - background-position: 50% 50%; - background-size: contain; - } - - .content { - flex: auto; - - h1 { - color: #434e59; - font-size: 72px; - font-weight: 600; - line-height: 72px; - margin-bottom: 24px; - } - - .desc { - color: @text-color-secondary; - font-size: 20px; - line-height: 28px; - margin-bottom: 16px; - } - - .actions { - button:not(:last-child) { - margin-right: 8px; - } - } - } -} - -@media screen and (max-width: @screen-xl) { - .exception { - .imgBlock { - padding-right: 88px; - } - } -} - -@media screen and (max-width: @screen-sm) { - .exception { - display: block; - text-align: center; - .imgBlock { - padding-right: 0; - margin: 0 auto 24px; - } - } -} - -@media screen and (max-width: @screen-xs) { - .exception { - .imgBlock { - margin-bottom: -24px; - overflow: hidden; - } - } -} diff --git a/src/components/Exception/index.zh-CN.md b/src/components/Exception/index.zh-CN.md deleted file mode 100644 index 2e64399fcbe4fe2c0eca7b9c4cb7742ccef3ed9a..0000000000000000000000000000000000000000 --- a/src/components/Exception/index.zh-CN.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Exception -subtitle: 异常 -cols: 1 -order: 5 ---- - -异常页用于对页面特定的异常状态进行反馈。通常,它包含对错误状态的阐述,并向用户提供建议或操作,避免用户感到迷失和困惑。 - -## API - -| 参数 | 说明| 类型 | 默认值 | -|-------------|------------------------------------------|-------------|-------| -| backText| 默认的返回按钮文本 | ReactNode| back to home | -| type| 页面类型,若配置,则自带对应类型默认的 `title`,`desc`,`img`,此默认设置可以被 `title`,`desc`,`img` 覆盖 | Enum {'403', '404', '500'} | - | -| title | 标题 | ReactNode| -| -| desc| 补充描述| ReactNode| -| -| img | 背景图片地址 | string| -| -| actions | 建议操作,配置此属性时默认的『返回首页』按钮不生效| ReactNode| -| -| linkElement | 定义链接的元素 | string\|ReactElement | 'a' | -| redirect | 返回按钮的跳转地址 | string | '/' diff --git a/src/components/Exception/typeConfig.js b/src/components/Exception/typeConfig.js deleted file mode 100644 index b6e1ee5a9bd7ac2990b9c319ccceeb9040632798..0000000000000000000000000000000000000000 --- a/src/components/Exception/typeConfig.js +++ /dev/null @@ -1,19 +0,0 @@ -const config = { - 403: { - img: 'https://gw.alipayobjects.com/zos/rmsportal/wZcnGqRDyhPOEYFcZDnb.svg', - title: '403', - desc: '抱歉,你无权访问该页面', - }, - 404: { - img: 'https://gw.alipayobjects.com/zos/rmsportal/KpnpchXsobRgLElEozzI.svg', - title: '404', - desc: '抱歉,你访问的页面不存在', - }, - 500: { - img: 'https://gw.alipayobjects.com/zos/rmsportal/RVRUAYdCGeYNBWoKiIwB.svg', - title: '500', - desc: '抱歉,服务器出错了', - }, -}; - -export default config; diff --git a/src/components/FooterToolbar/demo/basic.md b/src/components/FooterToolbar/demo/basic.md deleted file mode 100644 index 3043dbf74e8b2927c50821a583a49b7c9c75f3c0..0000000000000000000000000000000000000000 --- a/src/components/FooterToolbar/demo/basic.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -order: 0 -title: - zh-CN: 演示 - en-US: demo -iframe: 400 ---- - -## zh-CN - -浮动固定页脚。 - -## en-US - -Fixed to the footer. - -````jsx -import FooterToolbar from 'ant-design-pro/lib/FooterToolbar'; -import { Button } from 'antd'; - -ReactDOM.render( - - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - Content Content Content Content - - Cancel - Submit - - -, mountNode); -```` \ No newline at end of file diff --git a/src/components/FooterToolbar/index.d.ts b/src/components/FooterToolbar/index.d.ts deleted file mode 100644 index 9c6ac5b4cad95ade8f24a1b02e6de72f4770bfeb..0000000000000000000000000000000000000000 --- a/src/components/FooterToolbar/index.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import * as React from 'react'; -export interface IFooterToolbarProps { - extra: React.ReactNode; - style?: React.CSSProperties; -} - -export default class FooterToolbar extends React.Component {} diff --git a/src/components/FooterToolbar/index.en-US.md b/src/components/FooterToolbar/index.en-US.md deleted file mode 100644 index 69fd80bda80723c118f8fa1abdbc53372303305c..0000000000000000000000000000000000000000 --- a/src/components/FooterToolbar/index.en-US.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: FooterToolbar -cols: 1 -order: 6 ---- - -A toolbar fixed at the bottom. - -## Usage - -It is fixed at the bottom of the content area and does not move along with the scroll bar, which is usually used for data collection and submission for long pages. - -## API - -Property | Description | Type | Default ----------|-------------|------|-------- -children | toolbar content, align to the right | ReactNode | - -extra | extra information, align to the left | ReactNode | - \ No newline at end of file diff --git a/src/components/FooterToolbar/index.js b/src/components/FooterToolbar/index.js deleted file mode 100644 index d43f72fb45315521f9b5cd5a71589228f8d66de8..0000000000000000000000000000000000000000 --- a/src/components/FooterToolbar/index.js +++ /dev/null @@ -1,47 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import classNames from 'classnames'; -import styles from './index.less'; - -export default class FooterToolbar extends Component { - static contextTypes = { - isMobile: PropTypes.bool, - }; - - state = { - width: undefined, - }; - - componentDidMount() { - window.addEventListener('resize', this.resizeFooterToolbar); - this.resizeFooterToolbar(); - } - - componentWillUnmount() { - window.removeEventListener('resize', this.resizeFooterToolbar); - } - - resizeFooterToolbar = () => { - const sider = document.querySelector('.ant-layout-sider'); - if (sider == null) { - return; - } - const { isMobile } = this.context; - const width = isMobile ? null : `calc(100% - ${sider.style.width})`; - const { width: stateWidth } = this.state; - if (stateWidth !== width) { - this.setState({ width }); - } - }; - - render() { - const { children, className, extra, ...restProps } = this.props; - const { width } = this.state; - return ( - - {extra} - {children} - - ); - } -} diff --git a/src/components/FooterToolbar/index.less b/src/components/FooterToolbar/index.less deleted file mode 100644 index de6606bd43cc46ce191dada6117d13b37f32603a..0000000000000000000000000000000000000000 --- a/src/components/FooterToolbar/index.less +++ /dev/null @@ -1,33 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.toolbar { - position: fixed; - width: 100%; - bottom: 0; - right: 0; - height: 56px; - line-height: 56px; - box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.03); - background: #fff; - border-top: 1px solid @border-color-split; - padding: 0 24px; - z-index: 9; - - &:after { - content: ''; - display: block; - clear: both; - } - - .left { - float: left; - } - - .right { - float: right; - } - - button + button { - margin-left: 8px; - } -} diff --git a/src/components/FooterToolbar/index.zh-CN.md b/src/components/FooterToolbar/index.zh-CN.md deleted file mode 100644 index 421ac08e70782ec3fb19eb6b96dc8e6d58fd51be..0000000000000000000000000000000000000000 --- a/src/components/FooterToolbar/index.zh-CN.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: FooterToolbar -subtitle: 底部工具栏 -cols: 1 -order: 6 ---- - -固定在底部的工具栏。 - -## 何时使用 - -固定在内容区域的底部,不随滚动条移动,常用于长页面的数据搜集和提交工作。 - -## API - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -children | 工具栏内容,向右对齐 | ReactNode | - -extra | 额外信息,向左对齐 | ReactNode | - diff --git a/src/components/GlobalFooter/demo/basic.md b/src/components/GlobalFooter/demo/basic.md deleted file mode 100644 index 9a06bade622c4657dd9b39fa97c2e267c119d14c..0000000000000000000000000000000000000000 --- a/src/components/GlobalFooter/demo/basic.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -order: 0 -title: 演示 -iframe: 400 ---- - -基本页脚。 - -````jsx -import GlobalFooter from 'ant-design-pro/lib/GlobalFooter'; -import { Icon } from 'antd'; - -const links = [{ - key: '帮助', - title: '帮助', - href: '', -}, { - key: 'github', - title: , - href: 'https://github.com/ant-design/ant-design-pro', - blankTarget: true, -}, { - key: '条款', - title: '条款', - href: '', - blankTarget: true, -}]; - -const copyright = Copyright 2017 蚂蚁金服体验技术部出品; - -ReactDOM.render( - - - - -, mountNode); -```` diff --git a/src/components/GlobalFooter/index.d.ts b/src/components/GlobalFooter/index.d.ts deleted file mode 100644 index 3fa5c423eba263aa4c9d39eb49f395781c5e8f43..0000000000000000000000000000000000000000 --- a/src/components/GlobalFooter/index.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import * as React from 'react'; -export interface IGlobalFooterProps { - links?: Array<{ - key?: string; - title: React.ReactNode; - href: string; - blankTarget?: boolean; - }>; - copyright?: React.ReactNode; - style?: React.CSSProperties; -} - -export default class GlobalFooter extends React.Component {} diff --git a/src/components/GlobalFooter/index.js b/src/components/GlobalFooter/index.js deleted file mode 100644 index 1c2fb74efec05e82c1a19992cdbe09784d3bb7a8..0000000000000000000000000000000000000000 --- a/src/components/GlobalFooter/index.js +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react'; -import classNames from 'classnames'; -import styles from './index.less'; - -const GlobalFooter = ({ className, links, copyright }) => { - const clsString = classNames(styles.globalFooter, className); - return ( - - ); -}; - -export default GlobalFooter; diff --git a/src/components/GlobalFooter/index.less b/src/components/GlobalFooter/index.less deleted file mode 100644 index 101dcf04511b3bc17ce1da72de1ec8ad52cd865f..0000000000000000000000000000000000000000 --- a/src/components/GlobalFooter/index.less +++ /dev/null @@ -1,29 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.globalFooter { - padding: 0 16px; - margin: 48px 0 24px 0; - text-align: center; - - .links { - margin-bottom: 8px; - - a { - color: @text-color-secondary; - transition: all 0.3s; - - &:not(:last-child) { - margin-right: 40px; - } - - &:hover { - color: @text-color; - } - } - } - - .copyright { - color: @text-color-secondary; - font-size: @font-size-base; - } -} diff --git a/src/components/GlobalFooter/index.md b/src/components/GlobalFooter/index.md deleted file mode 100644 index 55b4be46c9187818887c020f72ec3465d29b1294..0000000000000000000000000000000000000000 --- a/src/components/GlobalFooter/index.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: - en-US: GlobalFooter - zh-CN: GlobalFooter -subtitle: 全局页脚 -cols: 1 -order: 7 ---- - -页脚属于全局导航的一部分,作为对顶部导航的补充,通过传递数据控制展示内容。 - -## API - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -links | 链接数据 | array<{ title: ReactNode, href: string, blankTarget?: boolean }> | - -copyright | 版权信息 | ReactNode | - diff --git a/src/components/GlobalHeader/RightContent.js b/src/components/GlobalHeader/RightContent.js deleted file mode 100644 index dad360ff08299518c7d3fdc7026c2b3b289b883f..0000000000000000000000000000000000000000 --- a/src/components/GlobalHeader/RightContent.js +++ /dev/null @@ -1,217 +0,0 @@ -import React, { PureComponent } from 'react'; -import { FormattedMessage, formatMessage } from 'umi/locale'; -import { Spin, Tag, Menu, Icon, Avatar, Tooltip } from 'antd'; -import moment from 'moment'; -import groupBy from 'lodash/groupBy'; -import NoticeIcon from '../NoticeIcon'; -import HeaderSearch from '../HeaderSearch'; -import HeaderDropdown from '../HeaderDropdown'; -import SelectLang from '../SelectLang'; -import styles from './index.less'; - -export default class GlobalHeaderRight extends PureComponent { - getNoticeData() { - 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(); - } - if (newNotice.id) { - newNotice.key = newNotice.id; - } - if (newNotice.extra && newNotice.status) { - const color = { - todo: '', - processing: 'blue', - urgent: 'red', - doing: 'gold', - }[newNotice.status]; - newNotice.extra = ( - - {newNotice.extra} - - ); - } - return newNotice; - }); - return groupBy(newNotices, 'type'); - } - - getUnreadData = noticeData => { - const unreadMsg = {}; - Object.entries(noticeData).forEach(([key, value]) => { - if (!unreadMsg[key]) { - unreadMsg[key] = 0; - } - if (Array.isArray(value)) { - unreadMsg[key] = value.filter(item => !item.read).length; - } - }); - return unreadMsg; - }; - - changeReadState = clickedItem => { - const { id } = clickedItem; - const { dispatch } = this.props; - dispatch({ - type: 'global/changeNoticeReadState', - payload: id, - }); - }; - - fetchMoreNotices = tabProps => { - const { list, name } = tabProps; - const { dispatch, notices = [] } = this.props; - const lastItemId = notices[notices.length - 1].id; - dispatch({ - type: 'global/fetchMoreNotices', - payload: { - lastItemId, - type: name, - offset: list.length, - }, - }); - }; - - render() { - const { - currentUser, - fetchingMoreNotices, - fetchingNotices, - loadedAllNotices, - onNoticeVisibleChange, - onMenuClick, - onNoticeClear, - skeletonCount, - theme, - } = this.props; - const menu = ( - - - - - - - - - - - - - - - - - - - - ); - const loadMoreProps = { - skeletonCount, - loadedAll: loadedAllNotices, - loading: fetchingMoreNotices, - }; - const noticeData = this.getNoticeData(); - const unreadMsg = this.getUnreadData(noticeData); - let className = styles.right; - if (theme === 'dark') { - className = `${styles.right} ${styles.dark}`; - } - return ( - - { - console.log('input', value); // eslint-disable-line - }} - onPressEnter={value => { - console.log('enter', value); // eslint-disable-line - }} - /> - - - - - - { - console.log(item, tabProps); // eslint-disable-line - this.changeReadState(item, tabProps); - }} - locale={{ - emptyText: formatMessage({ id: 'component.noticeIcon.empty' }), - clear: formatMessage({ id: 'component.noticeIcon.clear' }), - loadedAll: formatMessage({ id: 'component.noticeIcon.loaded' }), - loadMore: formatMessage({ id: 'component.noticeIcon.loading-more' }), - }} - onClear={onNoticeClear} - onLoadMore={this.fetchMoreNotices} - onPopupVisibleChange={onNoticeVisibleChange} - loading={fetchingNotices} - clearClose - > - - - - - {currentUser.name ? ( - - - - {currentUser.name} - - - ) : ( - - )} - - - ); - } -} diff --git a/src/components/GlobalHeader/index.js b/src/components/GlobalHeader/index.js deleted file mode 100644 index fe96cdea6d003485c78bd404cee957f7d0a345b1..0000000000000000000000000000000000000000 --- a/src/components/GlobalHeader/index.js +++ /dev/null @@ -1,41 +0,0 @@ -import React, { PureComponent } from 'react'; -import { Icon } from 'antd'; -import Link from 'umi/link'; -import Debounce from 'lodash-decorators/debounce'; -import styles from './index.less'; -import RightContent from './RightContent'; - -export default class GlobalHeader extends PureComponent { - componentWillUnmount() { - this.triggerResizeEvent.cancel(); - } - /* eslint-disable*/ - @Debounce(600) - triggerResizeEvent() { - // eslint-disable-line - const event = document.createEvent('HTMLEvents'); - event.initEvent('resize', true, false); - window.dispatchEvent(event); - } - toggle = () => { - const { collapsed, onCollapse } = this.props; - onCollapse(!collapsed); - this.triggerResizeEvent(); - }; - render() { - const { collapsed, isMobile, logo } = this.props; - return ( - - {isMobile && ( - - - - )} - - - - - - ); - } -} diff --git a/src/components/GlobalHeader/index.less b/src/components/GlobalHeader/index.less deleted file mode 100644 index 83a4151ed6164be0a1fb5f7ecdc741e6899c23ec..0000000000000000000000000000000000000000 --- a/src/components/GlobalHeader/index.less +++ /dev/null @@ -1,130 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -@pro-header-hover-bg: rgba(0, 0, 0, 0.025); - -.header { - height: @layout-header-height; - padding: 0; - background: #fff; - box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); - position: relative; -} - -.logo { - height: @layout-header-height; - line-height: @layout-header-height; - vertical-align: top; - display: inline-block; - padding: 0 0 0 24px; - cursor: pointer; - font-size: 20px; - img { - display: inline-block; - vertical-align: middle; - } -} - -.menu { - :global(.anticon) { - margin-right: 8px; - } - :global(.ant-dropdown-menu-item) { - min-width: 160px; - } -} - -.trigger { - font-size: 20px; - height: @layout-header-height; - cursor: pointer; - transition: all 0.3s, padding 0s; - padding: ~'calc((@{layout-header-height} - 20px) / 2)' 24px; - &:hover { - background: @pro-header-hover-bg; - } -} - -.right { - float: right; - height: 100%; - overflow: hidden; - .action { - cursor: pointer; - padding: 0 12px; - display: inline-block; - transition: all 0.3s; - height: 100%; - > i { - vertical-align: middle; - color: @text-color; - } - &:hover { - background: @pro-header-hover-bg; - } - &:global(.opened) { - background: @pro-header-hover-bg; - } - } - .search { - padding: 0 12px; - &:hover { - background: transparent; - } - } - .account { - .avatar { - margin: ~'calc((@{layout-header-height} - 24px) / 2)' 0; - margin-right: 8px; - color: @primary-color; - background: rgba(255, 255, 255, 0.85); - vertical-align: top; - } - } -} - -.dark { - height: @layout-header-height; - .action { - color: rgba(255, 255, 255, 0.85); - > i { - color: rgba(255, 255, 255, 0.85); - } - &:hover, - &:global(.opened) { - background: @primary-color; - } - :global(.ant-badge) { - color: rgba(255, 255, 255, 0.85); - } - } -} - -@media only screen and (max-width: @screen-md) { - .header { - :global(.ant-divider-vertical) { - vertical-align: unset; - } - .name { - display: none; - } - i.trigger { - padding: 22px 12px; - } - .logo { - padding-left: 12px; - padding-right: 12px; - position: relative; - } - .right { - position: absolute; - right: 12px; - top: 0; - background: #fff; - .account { - .avatar { - margin-right: 0; - } - } - } - } -} diff --git a/src/components/HeaderDropdown/index.js b/src/components/HeaderDropdown/index.js deleted file mode 100644 index a19c471ac19c61933d6c4c79e0ced4b8f8b43fba..0000000000000000000000000000000000000000 --- 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.less b/src/components/HeaderDropdown/index.less deleted file mode 100644 index 6494de0a6a23f993875c16439e73ef8d3f121922..0000000000000000000000000000000000000000 --- a/src/components/HeaderDropdown/index.less +++ /dev/null @@ -1,16 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.container > * { - background-color: #fff; - box-shadow: @shadow-1-down; - border-radius: 4px; -} - -@media screen and (max-width: @screen-xs) { - .container { - width: 100% !important; - } - .container > * { - border-radius: 0 !important; - } -} diff --git a/src/components/HeaderSearch/demo/basic.md b/src/components/HeaderSearch/demo/basic.md deleted file mode 100644 index 2139207c026ba26da47c5ef7191abf1dc4b81a98..0000000000000000000000000000000000000000 --- a/src/components/HeaderSearch/demo/basic.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -order: 0 -title: 全局搜索 ---- - -通常放置在导航工具条右侧。(点击搜索图标预览效果) - -````jsx -import HeaderSearch from 'ant-design-pro/lib/HeaderSearch'; - -ReactDOM.render( - - { - console.log('input', value); // eslint-disable-line - }} - onPressEnter={(value) => { - console.log('enter', value); // eslint-disable-line - }} - /> - -, mountNode); -```` diff --git a/src/components/HeaderSearch/index.d.ts b/src/components/HeaderSearch/index.d.ts deleted file mode 100644 index d78fde471ccd522d821f77b790647f5620efdb7e..0000000000000000000000000000000000000000 --- 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.en-US.md b/src/components/HeaderSearch/index.en-US.md deleted file mode 100644 index 6f4d06b4e10f43f16e2b997629a8ecd79ca50a3c..0000000000000000000000000000000000000000 --- a/src/components/HeaderSearch/index.en-US.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: - en-US: HeaderSearch - zh-CN: HeaderSearch -subtitle: Top search box -cols: 1 -order: 8 ---- - -Usually placed as an entry to the global search, placed on the right side of the navigation toolbar. - -## API - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -placeholder | placeholder text | string | - -dataSource | current list of prompts | string[] | - -onSearch | Called when searching items. | function(value) | - -onChange | Called when select an option or input value change, or value of input is changed | function(value) | - -onSelect | Called when a option is selected. param is option's value and option instance. | function(value) | - -onPressEnter | Callback when pressing Enter | function(value) | - -onVisibleChange | Show or hide the callback of the text box | function(value) |- -defaultOpen | The input box is displayed for the first time. | boolean | false -open | The input box is displayed | booelan |false \ No newline at end of file diff --git a/src/components/HeaderSearch/index.js b/src/components/HeaderSearch/index.js deleted file mode 100644 index 04f8b38ec8ff2e1c06455363a91d3e1e8f64aa9e..0000000000000000000000000000000000000000 --- a/src/components/HeaderSearch/index.js +++ /dev/null @@ -1,145 +0,0 @@ -import React, { PureComponent } from 'react'; -import PropTypes from 'prop-types'; -import { Input, Icon, AutoComplete } from 'antd'; -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, - }; - - static defaultProps = { - defaultActiveFirstOption: false, - onPressEnter: () => {}, - onSearch: () => {}, - onChange: () => {}, - className: '', - placeholder: '', - dataSource: [], - defaultOpen: false, - onVisibleChange: () => {}, - }; - - static getDerivedStateFromProps(props) { - if ('open' in props) { - return { - searchMode: props.open, - }; - } - return null; - } - - constructor(props) { - super(props); - this.state = { - searchMode: props.defaultOpen, - value: '', - }; - } - - componentWillUnmount() { - clearTimeout(this.timeout); - } - - onKeyDown = e => { - if (e.key === 'Enter') { - const { onPressEnter } = this.props; - const { value } = this.state; - this.timeout = setTimeout(() => { - onPressEnter(value); // Fix duplicate onPressEnter - }, 0); - } - }; - - onChange = value => { - const { onSearch, onChange } = this.props; - this.setState({ value }); - if (onSearch) { - onSearch(value); - } - if (onChange) { - onChange(value); - } - }; - - enterSearchMode = () => { - const { onVisibleChange } = this.props; - onVisibleChange(true); - this.setState({ searchMode: true }, () => { - const { searchMode } = this.state; - if (searchMode) { - this.input.focus(); - } - }); - }; - - leaveSearchMode = () => { - this.setState({ - searchMode: false, - value: '', - }); - }; - - // NOTE: 不能小于500,如果长按某键,第一次触发auto repeat的间隔是500ms,小于500会导致触发2次 - @Bind() - @Debounce(500, { - leading: true, - trailing: false, - }) - debouncePressEnter() { - const { onPressEnter } = this.props; - const { value } = this.state; - onPressEnter(value); - } - - render() { - const { className, placeholder, open, ...restProps } = this.props; - const { searchMode, value } = this.state; - delete restProps.defaultOpen; // for rc-select not affected - const inputClass = classNames(styles.input, { - [styles.show]: searchMode, - }); - return ( - { - if (propertyName === 'width' && !searchMode) { - const { onVisibleChange } = this.props; - onVisibleChange(searchMode); - } - }} - > - - - { - this.input = node; - }} - aria-label={placeholder} - placeholder={placeholder} - onKeyDown={this.onKeyDown} - onBlur={this.leaveSearchMode} - /> - - - ); - } -} diff --git a/src/components/HeaderSearch/index.less b/src/components/HeaderSearch/index.less deleted file mode 100644 index e97386d82d6dc3fe3bfee8d30d0dd38b6174b984..0000000000000000000000000000000000000000 --- a/src/components/HeaderSearch/index.less +++ /dev/null @@ -1,32 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.headerSearch { - :global(.anticon-search) { - cursor: pointer; - font-size: 16px; - } - .input { - transition: width 0.3s, margin-left 0.3s; - width: 0; - background: transparent; - border-radius: 0; - :global(.ant-select-selection) { - background: transparent; - } - input { - border: 0; - padding-left: 0; - padding-right: 0; - box-shadow: none !important; - } - &, - &:hover, - &:focus { - border-bottom: 1px solid @border-color-base; - } - &.show { - width: 210px; - margin-left: 8px; - } - } -} diff --git a/src/components/HeaderSearch/index.zh-CN.md b/src/components/HeaderSearch/index.zh-CN.md deleted file mode 100644 index 9c108c2bc14594ea082fe93af37836e610862f63..0000000000000000000000000000000000000000 --- a/src/components/HeaderSearch/index.zh-CN.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: - en-US: HeaderSearch - zh-CN: HeaderSearch -subtitle: 顶部搜索框 -cols: 1 -order: 8 ---- - -通常作为全局搜索的入口,放置在导航工具条右侧。 - -## API - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -placeholder | 占位文字 | string | - -dataSource | 当前提示内容列表 | string[] | - -onSearch | 搜索补全项的时候调用 | function(value) | - -onChange | 选中 option,或 input 的 value 变化时,调用此函数 | function(value) | - -onSelect | 被选中时调用,参数为选中项的 value 值 | function(value) | - -onPressEnter | 按下回车时的回调 | function(value) | - -onVisibleChange | 显示或隐藏文本框的回调 | function(value) |- -defaultOpen | 输入框首次显示是否显示 | boolean | false -open | 控制输入框是否显示 | booelan |false \ No newline at end of file diff --git a/src/components/Login/LoginItem.d.ts b/src/components/Login/LoginItem.d.ts deleted file mode 100644 index 30a7a2d6a483e2a8224fd315498f35ce72958f63..0000000000000000000000000000000000000000 --- a/src/components/Login/LoginItem.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as React from 'react'; -export interface ILoginItemProps { - name?: string; - rules?: any[]; - style?: React.CSSProperties; - onGetCaptcha?: () => void; - placeholder?: string; - buttonText?: React.ReactNode; -} - -export class LoginItem extends React.Component {} diff --git a/src/components/Login/LoginItem.js b/src/components/Login/LoginItem.js deleted file mode 100644 index b3cc4d48a978da65faa8d85fef62c7e00040f09a..0000000000000000000000000000000000000000 --- a/src/components/Login/LoginItem.js +++ /dev/null @@ -1,147 +0,0 @@ -import React, { Component } from 'react'; -import { Form, Input, Button, Row, Col } from 'antd'; -import omit from 'omit.js'; -import styles from './index.less'; -import ItemMap from './map'; -import LoginContext from './loginContext'; - -const FormItem = Form.Item; - -class WrapFormItem extends Component { - static defaultProps = { - getCaptchaButtonText: 'captcha', - getCaptchaSecondText: 'second', - }; - - constructor(props) { - super(props); - this.state = { - count: 0, - }; - } - - componentDidMount() { - const { updateActive, name } = this.props; - if (updateActive) { - updateActive(name); - } - } - - componentWillUnmount() { - clearInterval(this.interval); - } - - onGetCaptcha = () => { - const { onGetCaptcha } = this.props; - const result = onGetCaptcha ? onGetCaptcha() : null; - if (result === false) { - return; - } - if (result instanceof Promise) { - result.then(this.runGetCaptchaCountDown); - } else { - this.runGetCaptchaCountDown(); - } - }; - - getFormItemOptions = ({ onChange, defaultValue, customprops, rules }) => { - const options = { - rules: rules || customprops.rules, - }; - if (onChange) { - options.onChange = onChange; - } - if (defaultValue) { - options.initialValue = defaultValue; - } - return options; - }; - - runGetCaptchaCountDown = () => { - const { countDown } = this.props; - let count = countDown || 59; - this.setState({ count }); - this.interval = setInterval(() => { - count -= 1; - this.setState({ count }); - if (count === 0) { - clearInterval(this.interval); - } - }, 1000); - }; - - render() { - const { count } = this.state; - - const { - form: { getFieldDecorator }, - } = this.props; - - // 这么写是为了防止restProps中 带入 onChange, defaultValue, rules props - const { - onChange, - customprops, - defaultValue, - rules, - name, - getCaptchaButtonText, - getCaptchaSecondText, - updateActive, - type, - ...restProps - } = this.props; - - // get getFieldDecorator props - const options = this.getFormItemOptions(this.props); - - const otherProps = restProps || {}; - if (type === 'Captcha') { - const inputProps = omit(otherProps, ['onGetCaptcha', 'countDown']); - return ( - - - - {getFieldDecorator(name, options)()} - - - - {count ? `${count} ${getCaptchaSecondText}` : getCaptchaButtonText} - - - - - ); - } - return ( - - {getFieldDecorator(name, options)()} - - ); - } -} - -const LoginItem = {}; -Object.keys(ItemMap).forEach(key => { - const item = ItemMap[key]; - LoginItem[key] = props => ( - - {context => ( - - )} - - ); -}); - -export default LoginItem; diff --git a/src/components/Login/LoginSubmit.js b/src/components/Login/LoginSubmit.js deleted file mode 100644 index 4aebabf89a98a530292ba87534620e9ded8f88e7..0000000000000000000000000000000000000000 --- a/src/components/Login/LoginSubmit.js +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import classNames from 'classnames'; -import { Button, Form } from 'antd'; -import styles from './index.less'; - -const FormItem = Form.Item; - -const LoginSubmit = ({ className, ...rest }) => { - const clsString = classNames(styles.submit, className); - return ( - - - - ); -}; - -export default LoginSubmit; diff --git a/src/components/Login/LoginTab.d.ts b/src/components/Login/LoginTab.d.ts deleted file mode 100644 index db651f7b40c6194d1cd0cb8430736fc4d369e34d..0000000000000000000000000000000000000000 --- a/src/components/Login/LoginTab.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import * as React from 'react'; - -export interface ILoginTabProps { - key?: string; - tab?: React.ReactNode; -} -export default class LoginTab extends React.Component {} diff --git a/src/components/Login/LoginTab.js b/src/components/Login/LoginTab.js deleted file mode 100644 index 7c46db53292feb02b13ef3863f21ef25294b3a0e..0000000000000000000000000000000000000000 --- a/src/components/Login/LoginTab.js +++ /dev/null @@ -1,41 +0,0 @@ -import React, { Component } from 'react'; -import { Tabs } from 'antd'; -import LoginContext from './loginContext'; - -const { TabPane } = Tabs; - -const generateId = (() => { - let i = 0; - return (prefix = '') => { - i += 1; - return `${prefix}${i}`; - }; -})(); - -class LoginTab extends Component { - constructor(props) { - super(props); - this.uniqueId = generateId('login-tab-'); - } - - componentDidMount() { - const { tabUtil } = this.props; - tabUtil.addTab(this.uniqueId); - } - - render() { - const { children } = this.props; - return {children}; - } -} - -const wrapContext = props => ( - - {value => } - -); - -// 标志位 用来判断是不是自定义组件 -wrapContext.typeName = 'LoginTab'; - -export default wrapContext; diff --git a/src/components/Login/demo/basic.md b/src/components/Login/demo/basic.md deleted file mode 100644 index 5fbd0ca25448f92e964538c545edaf07d595ff27..0000000000000000000000000000000000000000 --- a/src/components/Login/demo/basic.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -order: 0 -title: - zh-CN: 标准登录 - en-US: Standard Login ---- - -Support login with account and mobile number. - -````jsx -import Login from 'ant-design-pro/lib/Login'; -import { Alert, Checkbox } from 'antd'; - -const { Tab, UserName, Password, Mobile, Captcha, Submit } = Login; - -class LoginDemo extends React.Component { - state = { - notice: '', - type: 'tab2', - autoLogin: true, - } - onSubmit = (err, values) => { - console.log('value collected ->', { ...values, autoLogin: this.state.autoLogin }); - if (this.state.type === 'tab1') { - this.setState({ - notice: '', - }, () => { - if (!err && (values.username !== 'admin' || values.password !== '888888')) { - setTimeout(() => { - this.setState({ - notice: 'The combination of username and password is incorrect!', - }); - }, 500); - } - }); - } - } - onTabChange = (key) => { - this.setState({ - type: key, - }); - } - changeAutoLogin = (e) => { - this.setState({ - autoLogin: e.target.checked, - }); - } - render() { - return ( - - - { - this.state.notice && - - } - - - - - - console.log('Get captcha!')} name="captcha" /> - - - Keep me logged in - Forgot password - - Login - - Other login methods - - - - Register - - - ); - } -} - -ReactDOM.render(, mountNode); -```` - - diff --git a/src/components/Login/index.d.ts b/src/components/Login/index.d.ts deleted file mode 100644 index 6a6f67fe6b1f250bd3708d0120bea1a22026b81b..0000000000000000000000000000000000000000 --- a/src/components/Login/index.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import Button from 'antd/lib/button'; -import * as React from 'react'; -import LoginItem from './LoginItem'; -import LoginTab from './LoginTab'; - -export interface ILoginProps { - defaultActiveKey?: string; - onTabChange?: (key: string) => void; - style?: React.CSSProperties; - onSubmit?: (error: any, values: any) => void; -} - -export default class Login extends React.Component { - public static Tab: typeof LoginTab; - public static UserName: typeof LoginItem; - public static Password: typeof LoginItem; - public static Mobile: typeof LoginItem; - public static Captcha: typeof LoginItem; - public static Submit: typeof Button; -} diff --git a/src/components/Login/index.en-US.md b/src/components/Login/index.en-US.md deleted file mode 100644 index 3b5992e28de312daba880f4ce9f834c61c626d40..0000000000000000000000000000000000000000 --- a/src/components/Login/index.en-US.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: Login -cols: 1 -order: 15 ---- - -Support multiple common ways of login with built-in controls. You can choose your own combinations and use with your custom controls. - -## API - -### Login - -Property | Description | Type | Default -----|------|-----|------ -defaultActiveKey | default key to activate the tab panel | String | - -onTabChange | callback on changing tabs | (key) => void | - -onSubmit | callback on submit | (err, values) => void | - - -### Login.Tab - -Property | Description | Type | Default -----|------|-----|------ -key | key of the tab | String | - -tab | displayed text of the tab | ReactNode | - - -### Login.UserName - -Property | Description | Type | Default -----|------|-----|------ -name | name of the control, also the key of the submitted data | String | - -rules | validation rules, same with [option.rules](getFieldDecorator(id, options)) in Form getFieldDecorator(id, options) | object[] | - - -Apart from the above properties, Login.Username also support all properties of antd.Input, together with the default values of basic settings, such as _placeholder_, _size_ and _prefix_. All of these default values can be over-written. - -### Login.Password, Login.Mobile are the same as Login.UserName - -### Login.Captcha - -Property | Description | Type | Default -----|------|-----|------ -onGetCaptcha | callback on getting a new Captcha | () => (void \| false \| Promise) | - -countDown | count down | number |- -buttonText | text on getting a new Captcha | ReactNode | '获取验证码' - -Apart from the above properties, _Login.Captcha_ support the same properties with _Login.UserName_. - -### Login.Submit - -Support all properties of _antd.Button_. \ No newline at end of file diff --git a/src/components/Login/index.js b/src/components/Login/index.js deleted file mode 100644 index 79cc56deb5e50f15d9e90915e96545794a7360dc..0000000000000000000000000000000000000000 --- a/src/components/Login/index.js +++ /dev/null @@ -1,132 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import { Form, Tabs } from 'antd'; -import classNames from 'classnames'; -import LoginItem from './LoginItem'; -import LoginTab from './LoginTab'; -import LoginSubmit from './LoginSubmit'; -import styles from './index.less'; -import LoginContext from './loginContext'; - -class Login extends Component { - static propTypes = { - className: PropTypes.string, - defaultActiveKey: PropTypes.string, - onTabChange: PropTypes.func, - onSubmit: PropTypes.func, - }; - - static defaultProps = { - className: '', - defaultActiveKey: '', - onTabChange: () => {}, - onSubmit: () => {}, - }; - - constructor(props) { - super(props); - this.state = { - type: props.defaultActiveKey, - tabs: [], - active: {}, - }; - } - - onSwitch = type => { - this.setState({ - type, - }); - const { onTabChange } = this.props; - onTabChange(type); - }; - - getContext = () => { - const { tabs } = this.state; - const { form } = this.props; - return { - tabUtil: { - addTab: id => { - this.setState({ - tabs: [...tabs, id], - }); - }, - removeTab: id => { - this.setState({ - tabs: tabs.filter(currentId => currentId !== id), - }); - }, - }, - form, - updateActive: activeItem => { - const { type, active } = this.state; - if (active[type]) { - active[type].push(activeItem); - } else { - active[type] = [activeItem]; - } - this.setState({ - active, - }); - }, - }; - }; - - handleSubmit = e => { - e.preventDefault(); - const { active, type } = this.state; - const { form, onSubmit } = this.props; - const activeFileds = active[type]; - form.validateFields(activeFileds, { force: true }, (err, values) => { - onSubmit(err, values); - }); - }; - - render() { - const { className, children } = this.props; - const { type, tabs } = this.state; - const TabChildren = []; - const otherChildren = []; - React.Children.forEach(children, item => { - if (!item) { - return; - } - // eslint-disable-next-line - if (item.type.typeName === 'LoginTab') { - TabChildren.push(item); - } else { - otherChildren.push(item); - } - }); - return ( - - - - {tabs.length ? ( - - - {TabChildren} - - {otherChildren} - - ) : ( - children - )} - - - - ); - } -} - -Login.Tab = LoginTab; -Login.Submit = LoginSubmit; -Object.keys(LoginItem).forEach(item => { - Login[item] = LoginItem[item]; -}); - -export default Form.create()(Login); diff --git a/src/components/Login/index.less b/src/components/Login/index.less deleted file mode 100644 index 646b6631d2b771e6f09332e62f310230715e462b..0000000000000000000000000000000000000000 --- a/src/components/Login/index.less +++ /dev/null @@ -1,53 +0,0 @@ -@import '~antd/lib/style/themes/default.less'; - -.login { - :global { - .ant-tabs .ant-tabs-bar { - border-bottom: 0; - margin-bottom: 24px; - text-align: center; - } - - .ant-form-item { - margin: 0 2px 24px; - } - } - - .getCaptcha { - display: block; - width: 100%; - } - - .icon { - font-size: 24px; - color: rgba(0, 0, 0, 0.2); - margin-left: 16px; - vertical-align: middle; - cursor: pointer; - transition: color 0.3s; - - &:hover { - color: @primary-color; - } - } - - .other { - text-align: left; - margin-top: 24px; - line-height: 22px; - - .register { - float: right; - } - } - - .prefixIcon { - font-size: @font-size-base; - color: @disabled-color; - } - - .submit { - width: 100%; - margin-top: 24px; - } -} diff --git a/src/components/Login/index.zh-CN.md b/src/components/Login/index.zh-CN.md deleted file mode 100644 index a869e96c323ab2cb9861121e4278f65d08b3e167..0000000000000000000000000000000000000000 --- a/src/components/Login/index.zh-CN.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: Login -subtitle: 登录 -cols: 1 -order: 15 ---- - -支持多种登录方式切换,内置了几种常见的登录控件,可以灵活组合,也支持和自定义控件配合使用。 - -## API - -### Login - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -defaultActiveKey | 默认激活 tab 面板的 key | String | - -onTabChange | 切换页签时的回调 | (key) => void | - -onSubmit | 点击提交时的回调 | (err, values) => void | - - -### Login.Tab - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -key | 对应选项卡的 key | String | - -tab | 选项卡头显示文字 | ReactNode | - - -### Login.UserName - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -name | 控件标记,提交数据中同样以此为 key | String | - -rules | 校验规则,同 Form getFieldDecorator(id, options) 中 [option.rules 的规则](getFieldDecorator(id, options)) | object[] | - - -除上述属性以外,Login.UserName 还支持 antd.Input 的所有属性,并且自带默认的基础配置,包括 `placeholder` `size` `prefix` 等,这些基础配置均可被覆盖。 -## Login.Password、Login.Mobile 同 Login.UserName - -### Login.Captcha - -参数 | 说明 | 类型 | 默认值 -----|------|-----|------ -onGetCaptcha | 点击获取校验码的回调 | () => (void \| false \| Promise) | - -countDown | 倒计时 | number |- -buttonText | 点击获取校验码的说明文字 | ReactNode | '获取验证码' - -除上述属性以外,Login.Captcha 支持的属性与 Login.UserName 相同。 - -### Login.Submit - -支持 antd.Button 的所有属性。 diff --git a/src/components/Login/loginContext.js b/src/components/Login/loginContext.js deleted file mode 100644 index a13e6599c4f4278d8bc5d4cf76e20e374e413fba..0000000000000000000000000000000000000000 --- a/src/components/Login/loginContext.js +++ /dev/null @@ -1,4 +0,0 @@ -import { createContext } from 'react'; - -const LoginContext = createContext(); -export default LoginContext; diff --git a/src/components/Login/map.js b/src/components/Login/map.js deleted file mode 100644 index dfa88199875ab0079636c8ccfc8f3037fc7eab99..0000000000000000000000000000000000000000 --- a/src/components/Login/map.js +++ /dev/null @@ -1,65 +0,0 @@ -import React from 'react'; -import { Icon } from 'antd'; -import styles from './index.less'; - -export default { - UserName: { - props: { - size: 'large', - id: 'userName', - prefix: , - placeholder: 'admin', - }, - rules: [ - { - required: true, - message: 'Please enter username!', - }, - ], - }, - Password: { - props: { - size: 'large', - prefix: , - type: 'password', - id: 'password', - placeholder: '888888', - }, - rules: [ - { - required: true, - message: 'Please enter password!', - }, - ], - }, - Mobile: { - props: { - size: 'large', - prefix: , - placeholder: 'mobile number', - }, - rules: [ - { - required: true, - message: 'Please enter mobile number!', - }, - { - pattern: /^1\d{10}$/, - message: 'Wrong mobile number format!', - }, - ], - }, - Captcha: { - props: { - size: 'large', - prefix: , - placeholder: 'captcha', - }, - rules: [ - { - required: true, - message: 'Please enter Captcha!', - }, - ], - }, -}; diff --git a/src/components/NoticeIcon/NoticeIconTab.d.ts b/src/components/NoticeIcon/NoticeIconTab.d.ts deleted file mode 100644 index 6ffaf032159f3cb909fde4bcda2ce57549bd9166..0000000000000000000000000000000000000000 --- a/src/components/NoticeIcon/NoticeIconTab.d.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { SkeletonProps } from 'antd/lib/skeleton'; -import * as React from 'react'; - -export interface INoticeIconData { - avatar?: string | React.ReactNode; - title?: React.ReactNode; - description?: React.ReactNode; - datetime?: React.ReactNode; - extra?: React.ReactNode; - style?: React.CSSProperties; -} - -export interface INoticeIconTabProps { - count?: number; - emptyText?: React.ReactNode; - emptyImage?: string; - list?: INoticeIconData[]; - loadedAll?: boolean; - loading?: boolean; - name?: string; - showClear?: boolean; - skeletonCount?: number; - skeletonProps?: SkeletonProps; - style?: React.CSSProperties; - title?: string; -} - -export default class NoticeIconTab extends React.Component {} diff --git a/src/components/NoticeIcon/NoticeList.js b/src/components/NoticeIcon/NoticeList.js deleted file mode 100644 index 6b73e6e0de9987fcc11a8df296b43e5cda5822bf..0000000000000000000000000000000000000000 --- a/src/components/NoticeIcon/NoticeList.js +++ /dev/null @@ -1,108 +0,0 @@ -import React from 'react'; -import { Avatar, List, Skeleton } from 'antd'; -import classNames from 'classnames'; -import styles from './NoticeList.less'; - -let ListElement = null; - -export default function NoticeList({ - data = [], - onClick, - onClear, - title, - locale, - emptyText, - emptyImage, - loading, - onLoadMore, - visible, - loadedAll = true, - scrollToLoad = true, - showClear = true, - skeletonCount = 5, - skeletonProps = {}, -}) { - if (data.length === 0) { - return ( - - {emptyImage ? : null} - {emptyText || locale.emptyText} - - ); - } - const loadingList = Array.from({ length: loading ? skeletonCount : 0 }).map(() => ({ loading })); - const LoadMore = loadedAll ? ( - - {locale.loadedAll} - - ) : ( - - {locale.loadMore} - - ); - const onScroll = event => { - if (!scrollToLoad || loading || loadedAll) return; - if (typeof onLoadMore !== 'function') return; - const { currentTarget: t } = event; - if (t.scrollHeight - t.scrollTop - t.clientHeight <= 40) { - onLoadMore(event); - ListElement = t; - } - }; - if (!visible && ListElement) { - try { - ListElement.scrollTo(null, 0); - } catch (err) { - ListElement = null; - } - } - return ( - - - {[...data, ...loadingList].map((item, i) => { - const itemCls = classNames(styles.item, { - [styles.read]: item.read, - }); - // eslint-disable-next-line no-nested-ternary - const leftIcon = item.avatar ? ( - typeof item.avatar === 'string' ? ( - - ) : ( - {item.avatar} - ) - ) : null; - - return ( - onClick(item)}> - - - {item.title} - {item.extra} - - } - description={ - - - {item.description} - - {item.datetime} - - } - /> - - - ); - })} - - {showClear ? ( - - {locale.clear} {title} - - ) : null} -
${title}
- ${data[0].value * 10}% -
- - {item.name} -
There were injuries alleged in three cases in 2015, and a fourth incident in September, according to the safety recall report. After meeting with US regulators in October, the firm decided to issue a voluntary recall.
Content Content Content Content
段落示意:蚂蚁金服务设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。
- - {currentUser.title} -
- - {currentUser.group} -
- - {currentUser.geographic.province.label} - {currentUser.geographic.city.label} -