BasicLayout.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import { Layout, Icon } from 'antd';
  4. import DocumentTitle from 'react-document-title';
  5. import { connect } from 'dva';
  6. import { Route, Redirect, Switch } from 'dva/router';
  7. import { ContainerQuery } from 'react-container-query';
  8. import classNames from 'classnames';
  9. import GlobalHeader from '../components/GlobalHeader';
  10. import GlobalFooter from '../components/GlobalFooter';
  11. import SiderMenu from '../components/SiderMenu';
  12. import NotFound from '../routes/Exception/404';
  13. const { Content } = Layout;
  14. const query = {
  15. 'screen-xs': {
  16. maxWidth: 575,
  17. },
  18. 'screen-sm': {
  19. minWidth: 576,
  20. maxWidth: 767,
  21. },
  22. 'screen-md': {
  23. minWidth: 768,
  24. maxWidth: 991,
  25. },
  26. 'screen-lg': {
  27. minWidth: 992,
  28. maxWidth: 1199,
  29. },
  30. 'screen-xl': {
  31. minWidth: 1200,
  32. },
  33. };
  34. class BasicLayout extends React.PureComponent {
  35. static childContextTypes = {
  36. location: PropTypes.object,
  37. breadcrumbNameMap: PropTypes.object,
  38. routeData: PropTypes.array,
  39. }
  40. getChildContext() {
  41. const { location, navData, getRouteData } = this.props;
  42. const routeData = getRouteData('BasicLayout');
  43. const firstMenuData = navData.reduce((arr, current) => arr.concat(current.children), []);
  44. const menuData = this.getMenuData(firstMenuData, '');
  45. const breadcrumbNameMap = {};
  46. routeData.concat(menuData).forEach((item) => {
  47. breadcrumbNameMap[item.path] = {
  48. name: item.name,
  49. component: item.component,
  50. };
  51. });
  52. return { location, breadcrumbNameMap, routeData };
  53. }
  54. getPageTitle() {
  55. const { location, getRouteData } = this.props;
  56. const { pathname } = location;
  57. let title = 'Ant Design Pro';
  58. getRouteData('BasicLayout').forEach((item) => {
  59. if (item.path === pathname) {
  60. title = `${item.name} - Ant Design Pro`;
  61. }
  62. });
  63. return title;
  64. }
  65. getMenuData = (data, parentPath) => {
  66. let arr = [];
  67. data.forEach((item) => {
  68. if (item.name) {
  69. arr.push({ path: `${parentPath}/${item.path}`, name: item.name });
  70. }
  71. if (item.children) {
  72. arr = arr.concat(this.getMenuData(item.children, `${parentPath}/${item.path}`));
  73. }
  74. });
  75. return arr;
  76. }
  77. render() {
  78. const {
  79. currentUser, collapsed, fetchingNotices, notices, getRouteData, navData, location, dispatch,
  80. } = this.props;
  81. const layout = (
  82. <Layout>
  83. <SiderMenu
  84. collapsed={collapsed}
  85. navData={navData}
  86. location={location}
  87. dispatch={dispatch}
  88. />
  89. <Layout>
  90. <GlobalHeader
  91. currentUser={currentUser}
  92. fetchingNotices={fetchingNotices}
  93. notices={notices}
  94. collapsed={collapsed}
  95. dispatch={dispatch}
  96. />
  97. <Content style={{ margin: '24px 24px 0', height: '100%' }}>
  98. <div style={{ minHeight: 'calc(100vh - 260px)' }}>
  99. <Switch>
  100. {
  101. getRouteData('BasicLayout').map(item =>
  102. (
  103. <Route
  104. exact={item.exact}
  105. key={item.path}
  106. path={item.path}
  107. component={item.component}
  108. />
  109. )
  110. )
  111. }
  112. <Redirect exact from="/" to="/dashboard/analysis" />
  113. <Route component={NotFound} />
  114. </Switch>
  115. </div>
  116. <GlobalFooter
  117. links={[{
  118. title: 'Pro 首页',
  119. href: 'http://pro.ant.design',
  120. blankTarget: true,
  121. }, {
  122. title: 'GitHub',
  123. href: 'https://github.com/ant-design/ant-design-pro',
  124. blankTarget: true,
  125. }, {
  126. title: 'Ant Design',
  127. href: 'http://ant.design',
  128. blankTarget: true,
  129. }]}
  130. copyright={
  131. <div>
  132. Copyright <Icon type="copyright" /> 2017 蚂蚁金服体验技术部出品
  133. </div>
  134. }
  135. />
  136. </Content>
  137. </Layout>
  138. </Layout>
  139. );
  140. return (
  141. <DocumentTitle title={this.getPageTitle()}>
  142. <ContainerQuery query={query}>
  143. {params => <div className={classNames(params)}>{layout}</div>}
  144. </ContainerQuery>
  145. </DocumentTitle>
  146. );
  147. }
  148. }
  149. export default connect(state => ({
  150. currentUser: state.user.currentUser,
  151. collapsed: state.global.collapsed,
  152. fetchingNotices: state.global.fetchingNotices,
  153. notices: state.global.notices,
  154. }))(BasicLayout);