diff --git a/src/components/GlobalHeader/RightContent.js b/src/components/GlobalHeader/RightContent.js
new file mode 100644
index 0000000000000000000000000000000000000000..0b94093cae107696bf0a4a616fda6340d1f2851d
--- /dev/null
+++ b/src/components/GlobalHeader/RightContent.js
@@ -0,0 +1,141 @@
+import React, { PureComponent } from 'react';
+import { Spin, Tag, Menu, Icon, Dropdown, Avatar, Tooltip } from 'antd';
+import moment from 'moment';
+import groupBy from 'lodash/groupBy';
+import NoticeIcon from '../NoticeIcon';
+import HeaderSearch from '../HeaderSearch';
+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();
+ }
+ // 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');
+ }
+ render() {
+ const {
+ currentUser,
+ fetchingNotices,
+ onNoticeVisibleChange,
+ onMenuClick,
+ onNoticeClear,
+ } = this.props;
+ const menu = (
+
+ );
+ const noticeData = this.getNoticeData();
+ let className = styles.right;
+ if (this.props.theme === 'white') {
+ className = `${styles.right} ${styles.white}`;
+ }
+ return (
+
+
{
+ console.log('input', value); // eslint-disable-line
+ }}
+ onPressEnter={(value) => {
+ console.log('enter', value); // eslint-disable-line
+ }}
+ />
+
+
+
+
+
+ {
+ console.log(item, tabProps); // eslint-disable-line
+ }}
+ onClear={onNoticeClear}
+ onPopupVisibleChange={onNoticeVisibleChange}
+ loading={fetchingNotices}
+ popupAlign={{ offset: [20, -16] }}
+ >
+
+
+
+
+ {currentUser.name ? (
+
+
+
+ {currentUser.name}
+
+
+ ) : (
+
+ )}
+
+ );
+ }
+}
diff --git a/src/components/GlobalHeader/index.js b/src/components/GlobalHeader/index.js
index a1a5614b325aa39f75c0f4e9d56bd7808491fce5..f6b7db5373534e5ab798bde4dc781a34e2f09bd5 100644
--- a/src/components/GlobalHeader/index.js
+++ b/src/components/GlobalHeader/index.js
@@ -1,148 +1,42 @@
import React, { PureComponent } from 'react';
-import { Menu, Icon, Spin, Tag, Dropdown, Avatar, Divider, Tooltip } from 'antd';
-import moment from 'moment';
-import groupBy from 'lodash/groupBy';
import Debounce from 'lodash-decorators/debounce';
+import { Icon, Divider } from 'antd';
import { Link } from 'dva/router';
-import NoticeIcon from '../NoticeIcon';
-import HeaderSearch from '../HeaderSearch';
import styles from './index.less';
+import RightContent from './RightContent';
export default class GlobalHeader extends PureComponent {
componentWillUnmount() {
this.triggerResizeEvent.cancel();
}
- 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();
- }
- // 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');
- }
- toggle = () => {
- const { collapsed, onCollapse } = this.props;
- onCollapse(!collapsed);
- this.triggerResizeEvent();
- }
@Debounce(600)
- triggerResizeEvent() { // eslint-disable-line
+ 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 {
- currentUser, collapsed, fetchingNotices, isMobile, logo,
- onNoticeVisibleChange, onMenuClick, onNoticeClear,
- } = this.props;
- const menu = (
-
- );
- const noticeData = this.getNoticeData();
+ const { collapsed, isMobile, logo } = this.props;
return (
- {isMobile && (
- [
- (
-
-
-
- ),
-
,
- ]
- )}
+ {isMobile && [
+
+
+ ,
+
,
+ ]}
-
-
{
- console.log('input', value); // eslint-disable-line
- }}
- onPressEnter={(value) => {
- console.log('enter', value); // eslint-disable-line
- }}
- />
-
-
-
-
-
- {
- console.log(item, tabProps); // eslint-disable-line
- }}
- onClear={onNoticeClear}
- onPopupVisibleChange={onNoticeVisibleChange}
- loading={fetchingNotices}
- popupAlign={{ offset: [20, -16] }}
- >
-
-
-
-
- {currentUser.name ? (
-
-
-
- {currentUser.name}
-
-
- ) : }
-
+
+
);
}
diff --git a/src/components/GlobalHeader/index.less b/src/components/GlobalHeader/index.less
index a9e9d92f74e3e08fe35b06bc821f0094298f86cf..dfe717f9043ea914ef8605a743f25e549222540c 100644
--- a/src/components/GlobalHeader/index.less
+++ b/src/components/GlobalHeader/index.less
@@ -1,10 +1,10 @@
-@import "~antd/lib/style/themes/default.less";
+@import '~antd/lib/style/themes/default.less';
.header {
height: 64px;
padding: 0 12px 0 0;
background: #fff;
- box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
+ box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
position: relative;
}
@@ -42,7 +42,7 @@ i.trigger {
font-size: 20px;
line-height: 64px;
cursor: pointer;
- transition: all .3s, padding 0s;
+ transition: all 0.3s, padding 0s;
padding: 0 24px;
&:hover {
background: @primary-1;
@@ -56,7 +56,7 @@ i.trigger {
cursor: pointer;
padding: 0 12px;
display: inline-block;
- transition: all .3s;
+ transition: all 0.3s;
height: 100%;
> i {
font-size: 16px;
@@ -69,8 +69,7 @@ i.trigger {
}
}
.search {
- padding: 0;
- margin: 0 12px;
+ padding: 0 12px;
&:hover {
background: transparent;
}
@@ -79,12 +78,29 @@ i.trigger {
.avatar {
margin: 20px 8px 20px 0;
color: @primary-color;
- background: rgba(255, 255, 255, .85);
+ background: rgba(255, 255, 255, 0.85);
vertical-align: middle;
}
}
}
+.white {
+ height: 64px;
+ .action {
+ color: rgba(255, 255, 255, 0.85);
+ > i {
+ color: rgba(255, 255, 255, 0.85);
+ }
+ &:hover,
+ &:global(.ant-popover-open) {
+ 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) {
diff --git a/src/components/SiderMenu/BaseMeun.js b/src/components/SiderMenu/BaseMeun.js
new file mode 100644
index 0000000000000000000000000000000000000000..00c90e011e78491eadd93b6c5989b28331e02971
--- /dev/null
+++ b/src/components/SiderMenu/BaseMeun.js
@@ -0,0 +1,175 @@
+import React, { PureComponent } from 'react';
+import { Menu, Icon } from 'antd';
+import { Link } from 'dva/router';
+import pathToRegexp from 'path-to-regexp';
+import { urlToList } from '../utils/pathTools';
+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' && icon.indexOf('http') === 0) {
+ return ;
+ }
+ if (typeof icon === 'string') {
+ return ;
+ }
+ return icon;
+};
+
+export const getMeunMatcheys = (flatMenuKeys, path) => {
+ return flatMenuKeys.filter((item) => {
+ return pathToRegexp(item).test(path);
+ });
+};
+
+export default class BaseMeun extends PureComponent {
+ constructor(props) {
+ super(props);
+ this.menus = props.menuData;
+ this.flatMenuKeys = this.getFlatMenuKeys(props.menuData);
+ }
+ /**
+ * Recursively flatten the data
+ * [{path:string},{path:string}] => {path,path2}
+ * @param menus
+ */
+ getFlatMenuKeys(menus) {
+ let keys = [];
+ menus.forEach((item) => {
+ if (item.children) {
+ keys = keys.concat(this.getFlatMenuKeys(item.children));
+ }
+ keys.push(item.path);
+ });
+ return keys;
+ }
+ /**
+ * 获得菜单子节点
+ * @memberof SiderMenu
+ */
+ getNavMenuItems = (menusData) => {
+ if (!menusData) {
+ return [];
+ }
+ return menusData
+ .filter(item => item.name && !item.hideInMenu)
+ .map((item) => {
+ // make dom
+ const ItemDom = this.getSubMenuOrItem(item);
+ return this.checkPermissionItem(item.authority, ItemDom);
+ })
+ .filter(item => item);
+ };
+ // Get the currently selected menu
+ getSelectedMenuKeys = () => {
+ const { location: { pathname } } = this.props;
+ return urlToList(pathname).map(itemPath =>
+ getMeunMatcheys(this.flatMenuKeys, itemPath).pop(),
+ );
+ };
+ /**
+ * get SubMenu or Item
+ */
+ getSubMenuOrItem = (item) => {
+ if (item.children && item.children.some(child => child.name)) {
+ return (
+
+ {getIcon(item.icon)}
+ {item.name}
+
+ ) : (
+ item.name
+ )
+ }
+ key={item.path}
+ >
+ {this.getNavMenuItems(item.children)}
+
+ );
+ } else {
+ return (
+ {this.getMenuItemPath(item)}
+ );
+ }
+ };
+ /**
+ * 判断是否是http链接.返回 Link 或 a
+ * Judge whether it is http link.return a or Link
+ * @memberof SiderMenu
+ */
+ getMenuItemPath = (item) => {
+ const itemPath = this.conversionPath(item.path);
+ const icon = getIcon(item.icon);
+ const { target, name } = item;
+ // Is it a http link
+ if (/^https?:\/\//.test(itemPath)) {
+ return (
+
+ {icon}
+ {name}
+
+ );
+ }
+ return (
+ {
+ this.props.onCollapse(true);
+ }
+ : undefined
+ }
+ >
+ {icon}
+ {name}
+
+ );
+ };
+ // permission to check
+ checkPermissionItem = (authority, ItemDom) => {
+ if (this.props.Authorized && this.props.Authorized.check) {
+ const { check } = this.props.Authorized;
+ return check(authority, ItemDom);
+ }
+ return ItemDom;
+ };
+ conversionPath = (path) => {
+ if (path && path.indexOf('http') === 0) {
+ return path;
+ } else {
+ return `/${path || ''}`.replace(/\/+/g, '/');
+ }
+ };
+ render() {
+ const { openKeys } = this.props;
+ // if pathname can't match, use the nearest parent's key
+ let selectedKeys = this.getSelectedMenuKeys();
+ if (!selectedKeys.length && openKeys) {
+ selectedKeys = [openKeys[openKeys.length - 1]];
+ }
+ return (
+
+ );
+ }
+}
diff --git a/src/components/SiderMenu/SiderMenu.js b/src/components/SiderMenu/SiderMenu.js
index 072f5cea9eb4326ea3e0dafd0abde9c18a3311b2..5f5e17c150672fe5e6fc341b42f19b8dcd4d142d 100644
--- a/src/components/SiderMenu/SiderMenu.js
+++ b/src/components/SiderMenu/SiderMenu.js
@@ -1,32 +1,12 @@
import React, { PureComponent } from 'react';
-import { Layout, Menu, Icon } from 'antd';
-import pathToRegexp from 'path-to-regexp';
+import { Layout } from 'antd';
import { Link } from 'dva/router';
import styles from './index.less';
+import BaseMeun, { getMeunMatcheys } from './BaseMeun';
import { urlToList } from '../utils/pathTools';
-const { Sider } = Layout;
-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' && icon.indexOf('http') === 0) {
- return ;
- }
- if (typeof icon === 'string') {
- return ;
- }
- return icon;
-};
-export const getMeunMatcheys = (flatMenuKeys, path) => {
- return flatMenuKeys.filter((item) => {
- return pathToRegexp(item).test(path);
- });
-};
+const { Sider } = Layout;
export default class SiderMenu extends PureComponent {
constructor(props) {
@@ -44,19 +24,6 @@ export default class SiderMenu extends PureComponent {
});
}
}
- /**
- * Convert pathname to openKeys
- * /list/search/articles = > ['list','/list/search']
- * @param props
- */
- getDefaultCollapsedSubMenus(props) {
- const { location: { pathname } } = props || this.props;
- return urlToList(pathname)
- .map((item) => {
- return getMeunMatcheys(this.flatMenuKeys, item)[0];
- })
- .filter(item => item);
- }
/**
* Recursively flatten the data
* [{path:string},{path:string}] => {path,path2}
@@ -73,115 +40,17 @@ export default class SiderMenu extends PureComponent {
return keys;
}
/**
- * 判断是否是http链接.返回 Link 或 a
- * Judge whether it is http link.return a or Link
- * @memberof SiderMenu
- */
- getMenuItemPath = (item) => {
- const itemPath = this.conversionPath(item.path);
- const icon = getIcon(item.icon);
- const { target, name } = item;
- // Is it a http link
- if (/^https?:\/\//.test(itemPath)) {
- return (
-
- {icon}
- {name}
-
- );
- }
- return (
- {
- this.props.onCollapse(true);
- }
- : undefined
- }
- >
- {icon}
- {name}
-
- );
- };
- /**
- * get SubMenu or Item
- */
- getSubMenuOrItem = (item) => {
- if (item.children && item.children.some(child => child.name)) {
- return (
-
- {getIcon(item.icon)}
- {item.name}
-
- ) : (
- item.name
- )
- }
- key={item.path}
- >
- {this.getNavMenuItems(item.children)}
-
- );
- } else {
- return (
- {this.getMenuItemPath(item)}
- );
- }
- };
- /**
- * 获得菜单子节点
- * @memberof SiderMenu
+ * Convert pathname to openKeys
+ * /list/search/articles = > ['list','/list/search']
+ * @param props
*/
- getNavMenuItems = (menusData) => {
- if (!menusData) {
- return [];
- }
- return menusData
- .filter(item => item.name && !item.hideInMenu)
+ getDefaultCollapsedSubMenus(props) {
+ const { location: { pathname } } = props || this.props;
+ return urlToList(pathname)
.map((item) => {
- // make dom
- const ItemDom = this.getSubMenuOrItem(item);
- return this.checkPermissionItem(item.authority, ItemDom);
+ return getMeunMatcheys(this.flatMenuKeys, item)[0];
})
.filter(item => item);
- };
- // Get the currently selected menu
- getSelectedMenuKeys = () => {
- const { location: { pathname } } = this.props;
- return urlToList(pathname).map(itemPath =>
- getMeunMatcheys(this.flatMenuKeys, itemPath).pop(),
- );
- };
- // conversion Path
- // 转化路径
- conversionPath = (path) => {
- if (path && path.indexOf('http') === 0) {
- return path;
- } else {
- return `/${path || ''}`.replace(/\/+/g, '/');
- }
- };
- // permission to check
- checkPermissionItem = (authority, ItemDom) => {
- if (this.props.Authorized && this.props.Authorized.check) {
- const { check } = this.props.Authorized;
- return check(authority, ItemDom);
- }
- return ItemDom;
- };
- isMainMenu = (key) => {
- return this.menus.some(
- item =>
- key && (item.key === key || item.path === key),
- );
}
handleOpenChange = (openKeys) => {
const lastOpenKey = openKeys[openKeys.length - 1];
@@ -193,17 +62,6 @@ export default class SiderMenu extends PureComponent {
render() {
const { logo, collapsed, onCollapse } = this.props;
const { openKeys } = this.state;
- // Don't show popup menu when it is been collapsed
- const menuProps = collapsed
- ? {}
- : {
- openKeys,
- };
- // if pathname can't match, use the nearest parent's key
- let selectedKeys = this.getSelectedMenuKeys();
- if (!selectedKeys.length) {
- selectedKeys = [openKeys[openKeys.length - 1]];
- }
return (
Ant Design Pro
-
+ />
);
}
diff --git a/src/components/SiderMenu/SilderMenu.test.js b/src/components/SiderMenu/SilderMenu.test.js
index e6f1f55a8dc578a8ad156171e6b4be423b730abd..361f99378eee6f462d43cf398ec001054ed4aeed 100644
--- a/src/components/SiderMenu/SilderMenu.test.js
+++ b/src/components/SiderMenu/SilderMenu.test.js
@@ -1,4 +1,4 @@
-import { getMeunMatcheys } from './SiderMenu';
+import { getMeunMatcheys } from './BaseMeun';
const meun = [
'/dashboard',
diff --git a/src/components/TopNavHeader/index.js b/src/components/TopNavHeader/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..83778649bfc2483c90bfe10c3478f73f1538afe0
--- /dev/null
+++ b/src/components/TopNavHeader/index.js
@@ -0,0 +1,26 @@
+import React, { PureComponent } from 'react';
+import { Link } from 'dva/router';
+import RightContent from '../GlobalHeader/RightContent';
+import BaseMeun from '../SiderMenu/BaseMeun';
+import styles from './index.less';
+
+export default class TopNavHeader extends PureComponent {
+ render() {
+ return (
+
+
+
+
+
+
Ant Design Pro
+
+
+
+
+
+
+
+
+ );
+ }
+}
diff --git a/src/components/TopNavHeader/index.less b/src/components/TopNavHeader/index.less
new file mode 100644
index 0000000000000000000000000000000000000000..037b12b0f7bb04a030166de0dcb9791e14dd1db7
--- /dev/null
+++ b/src/components/TopNavHeader/index.less
@@ -0,0 +1,31 @@
+.main {
+ display: flex;
+ height: 64px;
+ margin: auto;
+ max-width: 1200px;
+ .left {
+ flex: 1;
+ display: flex;
+ .logo {
+ width: 160px;
+ height: 64px;
+ position: relative;
+ line-height: 64px;
+ transition: all 0.3s;
+ overflow: hidden;
+ img {
+ display: inline-block;
+ vertical-align: middle;
+ height: 32px;
+ }
+ h1 {
+ color: #fff;
+ display: inline-block;
+ vertical-align: middle;
+ font-size: 16px;
+ margin: 0 0 0 12px;
+ font-weight: 400;
+ }
+ }
+ }
+}
diff --git a/src/layouts/BasicLayout.js b/src/layouts/BasicLayout.js
index ab85895758ae98ab284eb2084a1765d4c19a8005..f6237e8e854674c07817be711034258999a396aa 100644
--- a/src/layouts/BasicLayout.js
+++ b/src/layouts/BasicLayout.js
@@ -9,6 +9,7 @@ import classNames from 'classnames';
import { enquireScreen } from 'enquire-js';
import GlobalHeader from '../components/GlobalHeader';
import GlobalFooter from '../components/GlobalFooter';
+import TopNavHeader from '../components/TopNavHeader';
import SiderMenu from '../components/SiderMenu';
import NotFound from '../routes/Exception/404';
import { getRoutes } from '../utils/utils';
@@ -153,26 +154,45 @@ class BasicLayout extends React.PureComponent {
}
}
render() {
+ const isFluid = this.props.layout === 'fluid';
const {
currentUser, collapsed, fetchingNotices, notices, routerData, match, location,
} = this.props;
const bashRedirect = this.getBashRedirect();
const layout = (
-
+ Authorized={Authorized}
+ menuData={getMenuData()}
+ collapsed={collapsed}
+ location={location}
+ isMobile={this.state.isMobile}
+ onCollapse={this.handleMenuCollapse}
+ />
+ )}
+ {isFluid && !isMobile ? (
+
+ ) : (
+ )}
@@ -253,6 +274,7 @@ class BasicLayout extends React.PureComponent {
export default connect(({ user, global, loading }) => ({
currentUser: user.currentUser,
collapsed: global.collapsed,
+ layout: global.layout,
fetchingNotices: loading.effects['global/fetchNotices'],
notices: global.notices,
}))(BasicLayout);
diff --git a/src/layouts/GridContent.js b/src/layouts/GridContent.js
new file mode 100644
index 0000000000000000000000000000000000000000..60c22d5d24fc43917ebb3824f345a1642fa71a58
--- /dev/null
+++ b/src/layouts/GridContent.js
@@ -0,0 +1,17 @@
+import React, { PureComponent } from 'react';
+import { connect } from 'dva';
+import styles from './GridContent.less';
+
+class GridContent extends PureComponent {
+ render() {
+ let className = `${styles.main}`;
+ if (this.props.layout === 'fluid') {
+ className = `${styles.main} ${styles.fluid}`;
+ }
+ return {this.props.children}
;
+ }
+}
+
+export default connect(({ global }) => ({
+ layout: global.layout,
+}))(GridContent);
diff --git a/src/layouts/GridContent.less b/src/layouts/GridContent.less
new file mode 100644
index 0000000000000000000000000000000000000000..b06ad0c6e28ba8819d35f0c326f2aad15427189b
--- /dev/null
+++ b/src/layouts/GridContent.less
@@ -0,0 +1,9 @@
+.main {
+ width: 100%;
+ height: 100%;
+ min-height: 100%;
+ &.fluid {
+ max-width: 1200px;
+ margin: 0 auto;
+ }
+}
diff --git a/src/layouts/PageHeaderLayout.js b/src/layouts/PageHeaderLayout.js
index 2c615e897db6549d9af9f13a1a4ad0994a7ab70d..7416127958c8a0a02fa9d6429d7c17f6a333b589 100644
--- a/src/layouts/PageHeaderLayout.js
+++ b/src/layouts/PageHeaderLayout.js
@@ -1,12 +1,17 @@
import React from 'react';
import { Link } from 'dva/router';
import PageHeader from '../components/PageHeader';
+import GridContent from './GridContent';
import styles from './PageHeaderLayout.less';
export default ({ children, wrapperClassName, top, ...restProps }) => (
{top}
- {children ?
{children}
: null}
+ {children ? (
+
+ {children}
+
+ ) : null}
);
diff --git a/src/layouts/PageHeaderLayout.less b/src/layouts/PageHeaderLayout.less
index a0c0a6efe6c5c8cbd606cadc143959bab71a275b..39a449657a98b039c29e6654fd117267cbb5283a 100644
--- a/src/layouts/PageHeaderLayout.less
+++ b/src/layouts/PageHeaderLayout.less
@@ -1,4 +1,4 @@
-@import "~antd/lib/style/themes/default.less";
+@import '~antd/lib/style/themes/default.less';
.content {
margin: 24px 24px 0;
diff --git a/src/models/global.js b/src/models/global.js
index 55841e16d053db3bf4c92b94ce877cd6601d4965..64221aaad55adbb09f0ea73ec6ede75efe4b6c06 100644
--- a/src/models/global.js
+++ b/src/models/global.js
@@ -5,6 +5,7 @@ export default {
state: {
collapsed: false,
+ layout: 'fluid',
notices: [],
},
@@ -40,6 +41,12 @@ export default {
collapsed: payload,
};
},
+ changeLayout(state, { payload }) {
+ return {
+ ...state,
+ layout: payload,
+ };
+ },
saveNotices(state, { payload }) {
return {
...state,
diff --git a/src/routes/Dashboard/Analysis.js b/src/routes/Dashboard/Analysis.js
index f6df44063c86b9cad082764c9a9b3a37438b8600..b1f3a435c43fd1ee003963e7b1f5260a15eb0699 100644
--- a/src/routes/Dashboard/Analysis.js
+++ b/src/routes/Dashboard/Analysis.js
@@ -1,4 +1,4 @@
-import React, { Component, Fragment } from 'react';
+import React, { Component } from 'react';
import { connect } from 'dva';
import {
Row,
@@ -14,6 +14,7 @@ import {
Dropdown,
} from 'antd';
import numeral from 'numeral';
+import GridContent from '../../layouts/GridContent';
import {
ChartCard,
yuan,
@@ -241,7 +242,7 @@ export default class Analysis extends Component {
};
return (
-
+
-
+
);
}
}
diff --git a/src/routes/Dashboard/Monitor.js b/src/routes/Dashboard/Monitor.js
index 897dc9ce116573c4fd9a76f9c2309b141ff0bc2a..8332cc98b351a51009d4ad51ab9f508e7689f31b 100644
--- a/src/routes/Dashboard/Monitor.js
+++ b/src/routes/Dashboard/Monitor.js
@@ -1,7 +1,8 @@
-import React, { PureComponent, Fragment } from 'react';
+import React, { PureComponent } from 'react';
import { connect } from 'dva';
import { Row, Col, Card, Tooltip } from 'antd';
import numeral from 'numeral';
+import GridContent from '../../layouts/GridContent';
import Authorized from '../../utils/Authorized';
import { Pie, WaterWave, Gauge, TagCloud } from '../../components/Charts';
import NumberInfo from '../../components/NumberInfo';
@@ -35,7 +36,7 @@ export default class Monitor extends PureComponent {
const { tags } = monitor;
return (
-
+
@@ -164,7 +165,7 @@ export default class Monitor extends PureComponent {
-
+
);
}
}
diff --git a/src/routes/UserProfile/UserCenter.js b/src/routes/UserProfile/UserCenter.js
index b09d49270649dbdc3cc65cc0e381b8657bc03c9d..a1a603d3391e21e09cc209e0c110f7aa83f02516 100644
--- a/src/routes/UserProfile/UserCenter.js
+++ b/src/routes/UserProfile/UserCenter.js
@@ -3,14 +3,28 @@ import { connect } from 'dva';
import { Link } from 'dva/router';
import moment from 'moment';
import numeral from 'numeral';
-import { List, Card, Row, Col, Icon, Dropdown,
- Menu, Avatar, Tag, Divider, Tooltip, Spin, Input } from 'antd';
+import {
+ List,
+ Card,
+ Row,
+ Col,
+ Icon,
+ Dropdown,
+ Menu,
+ Avatar,
+ Tag,
+ Divider,
+ Tooltip,
+ Spin,
+ Input,
+} from 'antd';
import AvatarList from '../../components/AvatarList';
import { formatWan } from '../../utils/utils';
import styles from './UserCenter.less';
-import stylesArticles from '../List/Articles.less';
-import stylesApplications from '../List/Applications.less';
import stylesProjects from '../List/Projects.less';
+import stylesArticles from './List/Articles.less';
+import stylesApplications from './List/Applications.less';
+import GridContent from '../layouts/GridContent';
@connect(({ list, loading, user, project }) => ({
list,
@@ -26,7 +40,7 @@ export default class UserCenter extends PureComponent {
newTags: [],
inputVisible: false,
inputValue: '',
- }
+ };
componentDidMount() {
const { dispatch } = this.props;
@@ -46,33 +60,39 @@ export default class UserCenter extends PureComponent {
onTabChange = (key) => {
this.setState({ 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 }];
+ if (
+ inputValue &&
+ newTags.filter(tag => tag.label === inputValue).length === 0
+ ) {
+ newTags = [
+ ...newTags,
+ { key: `new-${newTags.length}`, label: inputValue },
+ ];
}
this.setState({
newTags,
inputVisible: false,
inputValue: '',
});
- }
+ };
renderArticles = (list, loading) => {
const IconText = ({ type, text }) => (
@@ -81,11 +101,14 @@ export default class UserCenter extends PureComponent {
{text}
);
- const ListContent = ({ data: { content, updatedAt, avatar, owner, href } }) => (
+ const ListContent = ({
+ data: { content, updatedAt, avatar, owner, href },
+ }) => (
@@ -108,9 +131,14 @@ export default class UserCenter extends PureComponent {
]}
>
{item.title}
- )}
+ title={
+
+ {item.title}
+
+ }
description={
Ant Design
@@ -124,19 +152,37 @@ export default class UserCenter extends PureComponent {
)}
/>
);
- }
+ };
renderApplications = (list, loading) => {
const itemMenu = (
);
@@ -165,10 +211,18 @@ export default class UserCenter extends PureComponent {
hoverable
bodyStyle={{ paddingBottom: 20 }}
actions={[
- ,
- ,
- ,
- ,
+
+
+ ,
+
+
+ ,
+
+
+ ,
+
+
+ ,
]}
>
);
- }
+ };
renderProjects = (list, loading) => {
return (
@@ -211,15 +265,13 @@ export default class UserCenter extends PureComponent {
{moment(item.updatedAt).fromNow()}
- {
- item.members.map(member => (
-
- ))
- }
+ {item.members.map(member => (
+
+ ))}
@@ -228,22 +280,137 @@ export default class UserCenter extends PureComponent {
)}
/>
);
+ };
+ renderContent() {
+ const { newTags, inputVisible, inputValue } = this.state;
+ const {
+ currentUser,
+ project: { notice },
+ projectLoading,
+ } = this.props;
+ return (
+
+
+
+
{currentUser.name}
+
{currentUser.signature}
+
+
+
+
+ {currentUser.title}
+
+
+
+ {currentUser.group}
+
+
+
+ {currentUser.geographic.province.label}
+ {currentUser.geographic.city.label}
+
+
+
+
+
标签
+ {currentUser.tags.map(item =>
{item.label})}
+
+
+
+
+
+
+
团队
+
+
+ {notice.map(item => (
+
+
+ {item.member}
+
+ ))}
+
+
+
+
+
+
标签
+ {currentUser.tags
+ .concat(newTags)
+ .map(item =>
{item.label})}
+ {inputVisible && (
+
+ )}
+ {!inputVisible && (
+
+
+
+ )}
+
+
+
+
团队
+
+
+ {notice.map(item => (
+
+
+
+ {item.member}
+
+
+ ))}
+
+
+
+
+ );
}
-
render() {
- const { key, newTags, inputVisible, inputValue } = this.state;
- const { list: { list }, listLoading, currentUser, currentUserLoading,
- project: { notice }, projectLoading } = this.props;
- const operationTabList = [{
- key: 'article',
- tab: 文章 (8),
- }, {
- key: 'application',
- tab: 应用 (8),
- }, {
- key: 'project',
- tab: 项目 (8),
- }];
+ const {
+ list: { list },
+ listLoading,
+ currentUser,
+ currentUserLoading,
+ } = this.props;
+ const operationTabList = [
+ {
+ key: 'article',
+ tab: (
+
+ 文章 (8)
+
+ ),
+ },
+ {
+ key: 'application',
+ tab: (
+
+ 应用 (8)
+
+ ),
+ },
+ {
+ key: 'project',
+ tab: (
+
+ 项目 (8)
+
+ ),
+ },
+ ];
const contentMap = {
article: this.renderArticles(list, listLoading),
application: this.renderApplications(list, listLoading),
@@ -251,94 +418,33 @@ export default class UserCenter extends PureComponent {
};
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...'
- }
-
-
-
-
- {contentMap[key]}
-
-
-
-
+
+
+
+
+
+ {currentUser && Object.keys(currentUser).length
+ ? this.renderContent()
+ : 'loading...'}
+
+
+
+
+ {contentMap[this.state.key]}
+
+
+
+
+
);
}
}
diff --git a/src/routes/UserProfile/Userinfo/Info.js b/src/routes/UserProfile/Userinfo/Info.js
index ad6cdca52351503d0d385a27a7e1a91aef1a8463..4281fcb213dc2ecea0ea1d23f89126b7ef97ec7e 100644
--- a/src/routes/UserProfile/Userinfo/Info.js
+++ b/src/routes/UserProfile/Userinfo/Info.js
@@ -3,7 +3,8 @@ import { connect } from 'dva';
import { Route, routerRedux, Switch, Redirect } from 'dva/router';
import { Menu } from 'antd';
import styles from './Info.less';
-import { getRoutes } from '../../../utils/utils';
+import { getRoutes } from '../../utils/utils';
+import GridContent from '../../layouts/GridContent';
const { Item } = Menu;
@@ -71,43 +72,36 @@ export default class Info extends Component {
return '';
}
return (
- {
- this.main = ref;
- }}
- >
-
-
+
+
+
+
+
+
+
{this.getRightTitle()}
+
+ {getRoutes(match.path, routerData).map(item => (
+ (
+
+ )}
+ exact={item.exact}
+ />
+ ))}
+
+
+
+
-
-
{this.getRightTitle()}
-
- {getRoutes(match.path, routerData).map(item => (
- (
-
- )}
- exact={item.exact}
- />
- ))}
-
-
-
-
-
+
);
}
}