Workplace.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. import React, { PureComponent } from 'react';
  2. import moment from 'moment';
  3. import { connect } from 'dva';
  4. import { Link } from 'dva/router';
  5. import { Row, Col, Card, List, Avatar, Spin } from 'antd';
  6. import { Radar } from 'components/Charts';
  7. import EditableLinkGroup from 'components/EditableLinkGroup';
  8. import PageHeaderLayout from '../../layouts/PageHeaderLayout';
  9. import styles from './Workplace.less';
  10. const links = [
  11. {
  12. title: '操作一',
  13. href: '',
  14. },
  15. {
  16. title: '操作二',
  17. href: '',
  18. },
  19. {
  20. title: '操作三',
  21. href: '',
  22. },
  23. {
  24. title: '操作四',
  25. href: '',
  26. },
  27. {
  28. title: '操作五',
  29. href: '',
  30. },
  31. {
  32. title: '操作六',
  33. href: '',
  34. },
  35. ];
  36. @connect(({ user, project, activities, chart, loading }) => ({
  37. currentUser: user.currentUser,
  38. project,
  39. activities,
  40. chart,
  41. currentUserLoading: loading.effects['user/fetchCurrent'],
  42. projectLoading: loading.effects['project/fetchNotice'],
  43. activitiesLoading: loading.effects['activities/fetchList'],
  44. }))
  45. export default class Workplace extends PureComponent {
  46. componentDidMount() {
  47. const { dispatch } = this.props;
  48. dispatch({
  49. type: 'user/fetchCurrent',
  50. });
  51. dispatch({
  52. type: 'project/fetchNotice',
  53. });
  54. dispatch({
  55. type: 'activities/fetchList',
  56. });
  57. dispatch({
  58. type: 'chart/fetch',
  59. });
  60. }
  61. componentWillUnmount() {
  62. const { dispatch } = this.props;
  63. dispatch({
  64. type: 'chart/clear',
  65. });
  66. }
  67. renderActivities() {
  68. const {
  69. activities: { list },
  70. } = this.props;
  71. return list.map(item => {
  72. const events = item.template.split(/@\{([^{}]*)\}/gi).map(key => {
  73. if (item[key]) {
  74. return (
  75. <a href={item[key].link} key={item[key].name}>
  76. {item[key].name}
  77. </a>
  78. );
  79. }
  80. return key;
  81. });
  82. return (
  83. <List.Item key={item.id}>
  84. <List.Item.Meta
  85. avatar={<Avatar src={item.user.avatar} />}
  86. title={
  87. <span>
  88. <a className={styles.username}>{item.user.name}</a>
  89. &nbsp;
  90. <span className={styles.event}>{events}</span>
  91. </span>
  92. }
  93. description={
  94. <span className={styles.datetime} title={item.updatedAt}>
  95. {moment(item.updatedAt).fromNow()}
  96. </span>
  97. }
  98. />
  99. </List.Item>
  100. );
  101. });
  102. }
  103. render() {
  104. const {
  105. currentUser,
  106. currentUserLoading,
  107. project: { notice },
  108. projectLoading,
  109. activitiesLoading,
  110. chart: { radarData },
  111. } = this.props;
  112. const pageHeaderContent = (
  113. <Spin spinning={currentUserLoading}>
  114. {currentUser && Object.keys(currentUser).length ? (
  115. <div className={styles.pageHeaderContent}>
  116. <div className={styles.avatar}>
  117. <Avatar size="large" src={currentUser.avatar} />
  118. </div>
  119. <div className={styles.content}>
  120. <div className={styles.contentTitle}>早安,{currentUser.name},祝你开心每一天!</div>
  121. <div>
  122. {currentUser.title} | {currentUser.group}
  123. </div>
  124. </div>
  125. </div>
  126. ) : null}
  127. </Spin>
  128. );
  129. const extraContent = (
  130. <div className={styles.extraContent}>
  131. <div className={styles.statItem}>
  132. <p>项目数</p>
  133. <p>56</p>
  134. </div>
  135. <div className={styles.statItem}>
  136. <p>团队内排名</p>
  137. <p>
  138. 8<span> / 24</span>
  139. </p>
  140. </div>
  141. <div className={styles.statItem}>
  142. <p>项目访问</p>
  143. <p>2,223</p>
  144. </div>
  145. </div>
  146. );
  147. return (
  148. <PageHeaderLayout content={pageHeaderContent} extraContent={extraContent}>
  149. <Row gutter={24}>
  150. <Col xl={16} lg={24} md={24} sm={24} xs={24}>
  151. <Card
  152. className={styles.projectList}
  153. style={{ marginBottom: 24 }}
  154. title="进行中的项目"
  155. bordered={false}
  156. extra={<Link to="/">全部项目</Link>}
  157. loading={projectLoading}
  158. bodyStyle={{ padding: 0 }}
  159. >
  160. {notice.map(item => (
  161. <Card.Grid className={styles.projectGrid} key={item.id}>
  162. <Card bodyStyle={{ padding: 0 }} bordered={false}>
  163. <Card.Meta
  164. title={
  165. <div className={styles.cardTitle}>
  166. <Avatar size="small" src={item.logo} />
  167. <Link to={item.href}>{item.title}</Link>
  168. </div>
  169. }
  170. description={item.description}
  171. />
  172. <div className={styles.projectItemContent}>
  173. <Link to={item.memberLink}>{item.member || ''}</Link>
  174. {item.updatedAt && (
  175. <span className={styles.datetime} title={item.updatedAt}>
  176. {moment(item.updatedAt).fromNow()}
  177. </span>
  178. )}
  179. </div>
  180. </Card>
  181. </Card.Grid>
  182. ))}
  183. </Card>
  184. <Card
  185. bodyStyle={{ padding: 0 }}
  186. bordered={false}
  187. className={styles.activeCard}
  188. title="动态"
  189. loading={activitiesLoading}
  190. >
  191. <List loading={activitiesLoading} size="large">
  192. <div className={styles.activitiesList}>{this.renderActivities()}</div>
  193. </List>
  194. </Card>
  195. </Col>
  196. <Col xl={8} lg={24} md={24} sm={24} xs={24}>
  197. <Card
  198. style={{ marginBottom: 24 }}
  199. title="快速开始 / 便捷导航"
  200. bordered={false}
  201. bodyStyle={{ padding: 0 }}
  202. >
  203. <EditableLinkGroup onAdd={() => {}} links={links} linkElement={Link} />
  204. </Card>
  205. <Card
  206. style={{ marginBottom: 24 }}
  207. bordered={false}
  208. title="XX 指数"
  209. loading={radarData.length === 0}
  210. >
  211. <div className={styles.chart}>
  212. <Radar hasLegend height={343} data={radarData} />
  213. </div>
  214. </Card>
  215. <Card
  216. bodyStyle={{ paddingTop: 12, paddingBottom: 12 }}
  217. bordered={false}
  218. title="团队"
  219. loading={projectLoading}
  220. >
  221. <div className={styles.members}>
  222. <Row gutter={48}>
  223. {notice.map(item => (
  224. <Col span={12} key={`members-item-${item.id}`}>
  225. <Link to={item.href}>
  226. <Avatar src={item.logo} size="small" />
  227. <span className={styles.member}>{item.member}</span>
  228. </Link>
  229. </Col>
  230. ))}
  231. </Row>
  232. </div>
  233. </Card>
  234. </Col>
  235. </Row>
  236. </PageHeaderLayout>
  237. );
  238. }
  239. }