mock平台

GroupList.js 9.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. import React, { PureComponent as Component } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { connect } from 'react-redux';
  4. import { Icon, Modal, Input, message,Spin, Row, Menu, Col, Popover, Tooltip } from 'antd';
  5. import { autobind } from 'core-decorators';
  6. import axios from 'axios';
  7. import { withRouter } from 'react-router-dom';
  8. const { TextArea } = Input;
  9. const Search = Input.Search;
  10. import UsernameAutoComplete from '../../../components/UsernameAutoComplete/UsernameAutoComplete.js';
  11. import GuideBtns from '../../../components/GuideBtns/GuideBtns.js';
  12. import { fetchNewsData } from '../../../reducer/modules/news.js';
  13. import {
  14. fetchGroupList,
  15. setCurrGroup,
  16. setGroupList,
  17. fetchGroupMsg
  18. } from '../../../reducer/modules/group.js';
  19. import _ from 'underscore';
  20. import './GroupList.scss';
  21. const tip = (
  22. <div className="title-container">
  23. <h3 className="title">欢迎使用 YApi ~</h3>
  24. <p>
  25. 这里的 <b>“个人空间”</b>{' '}
  26. 是你自己才能看到的分组,你拥有这个分组的全部权限,可以在这个分组里探索 YApi 的功能。
  27. </p>
  28. </div>
  29. );
  30. @connect(
  31. state => ({
  32. groupList: state.group.groupList,
  33. currGroup: state.group.currGroup,
  34. curUserRole: state.user.role,
  35. curUserRoleInGroup: state.group.currGroup.role || state.group.role,
  36. studyTip: state.user.studyTip,
  37. study: state.user.study
  38. }),
  39. {
  40. fetchGroupList,
  41. setCurrGroup,
  42. setGroupList,
  43. fetchNewsData,
  44. fetchGroupMsg
  45. }
  46. )
  47. @withRouter
  48. export default class GroupList extends Component {
  49. static propTypes = {
  50. groupList: PropTypes.array,
  51. currGroup: PropTypes.object,
  52. fetchGroupList: PropTypes.func,
  53. setCurrGroup: PropTypes.func,
  54. setGroupList: PropTypes.func,
  55. match: PropTypes.object,
  56. history: PropTypes.object,
  57. curUserRole: PropTypes.string,
  58. curUserRoleInGroup: PropTypes.string,
  59. studyTip: PropTypes.number,
  60. study: PropTypes.bool,
  61. fetchNewsData: PropTypes.func,
  62. fetchGroupMsg: PropTypes.func
  63. };
  64. state = {
  65. addGroupModalVisible: false,
  66. newGroupName: '',
  67. newGroupDesc: '',
  68. currGroupName: '',
  69. currGroupDesc: '',
  70. groupList: [],
  71. owner_uids: []
  72. };
  73. constructor(props) {
  74. super(props);
  75. }
  76. async componentWillMount() {
  77. const groupId = !isNaN(this.props.match.params.groupId)
  78. ? parseInt(this.props.match.params.groupId)
  79. : 0;
  80. await this.props.fetchGroupList();
  81. let currGroup = false;
  82. if (this.props.groupList.length && groupId) {
  83. for (let i = 0; i < this.props.groupList.length; i++) {
  84. if (this.props.groupList[i]._id === groupId) {
  85. currGroup = this.props.groupList[i];
  86. }
  87. }
  88. } else if (!groupId && this.props.groupList.length) {
  89. this.props.history.push(`/group/${this.props.groupList[0]._id}`);
  90. }
  91. if (!currGroup) {
  92. currGroup = this.props.groupList[0] || { group_name: '', group_desc: '' };
  93. this.props.history.replace(`${currGroup._id}`);
  94. }
  95. this.setState({ groupList: this.props.groupList });
  96. this.props.setCurrGroup(currGroup);
  97. }
  98. @autobind
  99. showModal() {
  100. this.setState({
  101. addGroupModalVisible: true
  102. });
  103. }
  104. @autobind
  105. hideModal() {
  106. this.setState({
  107. newGroupName: '',
  108. group_name: '',
  109. owner_uids: [],
  110. addGroupModalVisible: false
  111. });
  112. }
  113. @autobind
  114. async addGroup() {
  115. const { newGroupName: group_name, newGroupDesc: group_desc, owner_uids } = this.state;
  116. const res = await axios.post('/api/group/add', { group_name, group_desc, owner_uids });
  117. if (!res.data.errcode) {
  118. this.setState({
  119. newGroupName: '',
  120. group_name: '',
  121. owner_uids: [],
  122. addGroupModalVisible: false
  123. });
  124. await this.props.fetchGroupList();
  125. this.setState({ groupList: this.props.groupList });
  126. this.props.fetchGroupMsg(this.props.currGroup._id);
  127. this.props.fetchNewsData(this.props.currGroup._id, 'group', 1, 10);
  128. } else {
  129. message.error(res.data.errmsg);
  130. }
  131. }
  132. @autobind
  133. async editGroup() {
  134. const { currGroupName: group_name, currGroupDesc: group_desc } = this.state;
  135. const id = this.props.currGroup._id;
  136. const res = await axios.post('/api/group/up', { group_name, group_desc, id });
  137. if (res.data.errcode) {
  138. message.error(res.data.errmsg);
  139. } else {
  140. await this.props.fetchGroupList();
  141. this.setState({ groupList: this.props.groupList });
  142. const currGroup = _.find(this.props.groupList, group => {
  143. return +group._id === +id;
  144. });
  145. this.props.setCurrGroup(currGroup);
  146. // this.props.setCurrGroup({ group_name, group_desc, _id: id });
  147. this.props.fetchGroupMsg(this.props.currGroup._id);
  148. this.props.fetchNewsData(this.props.currGroup._id, 'group', 1, 10);
  149. }
  150. }
  151. @autobind
  152. inputNewGroupName(e) {
  153. this.setState({ newGroupName: e.target.value });
  154. }
  155. @autobind
  156. inputNewGroupDesc(e) {
  157. this.setState({ newGroupDesc: e.target.value });
  158. }
  159. @autobind
  160. selectGroup(e) {
  161. const groupId = e.key;
  162. //const currGroup = this.props.groupList.find((group) => { return +group._id === +groupId });
  163. const currGroup = _.find(this.props.groupList, group => {
  164. return +group._id === +groupId;
  165. });
  166. this.props.setCurrGroup(currGroup);
  167. this.props.history.replace(`${currGroup._id}`);
  168. this.props.fetchNewsData(groupId, 'group', 1, 10);
  169. }
  170. @autobind
  171. onUserSelect(uids) {
  172. this.setState({
  173. owner_uids: uids
  174. });
  175. }
  176. @autobind
  177. searchGroup(e, value) {
  178. const v = value || e.target.value;
  179. const { groupList } = this.props;
  180. if (v === '') {
  181. this.setState({ groupList });
  182. } else {
  183. this.setState({
  184. groupList: groupList.filter(group => new RegExp(v, 'i').test(group.group_name))
  185. });
  186. }
  187. }
  188. componentWillReceiveProps(nextProps) {
  189. // GroupSetting 组件设置的分组信息,通过redux同步到左侧分组菜单中
  190. if (this.props.groupList !== nextProps.groupList) {
  191. this.setState({
  192. groupList: nextProps.groupList
  193. });
  194. }
  195. }
  196. render() {
  197. const { currGroup } = this.props;
  198. return (
  199. <div className="m-group">
  200. {!this.props.study ? <div className="study-mask" /> : null}
  201. <div className="group-bar">
  202. <div className="curr-group">
  203. <div className="curr-group-name">
  204. <span className="name">{currGroup.group_name}</span>
  205. <Tooltip title="添加分组">
  206. <a className="editSet">
  207. <Icon className="btn" type="folder-add" onClick={this.showModal} />
  208. </a>
  209. </Tooltip>
  210. </div>
  211. <div className="curr-group-desc">简介: {currGroup.group_desc}</div>
  212. </div>
  213. <div className="group-operate">
  214. <div className="search">
  215. <Search
  216. placeholder="搜索分类"
  217. onChange={this.searchGroup}
  218. onSearch={v => this.searchGroup(null, v)}
  219. />
  220. </div>
  221. </div>
  222. {this.state.groupList.length === 0 && <Spin style={{
  223. marginTop: 20,
  224. display: 'flex',
  225. justifyContent: 'center'
  226. }} />}
  227. <Menu
  228. className="group-list"
  229. mode="inline"
  230. onClick={this.selectGroup}
  231. selectedKeys={[`${currGroup._id}`]}
  232. >
  233. {this.state.groupList.map(group => {
  234. if (group.type === 'private') {
  235. return (
  236. <Menu.Item
  237. key={`${group._id}`}
  238. className="group-item"
  239. style={{ zIndex: this.props.studyTip === 0 ? 3 : 1 }}
  240. >
  241. <Icon type="user" />
  242. <Popover
  243. overlayClassName="popover-index"
  244. content={<GuideBtns />}
  245. title={tip}
  246. placement="right"
  247. visible={this.props.studyTip === 0 && !this.props.study}
  248. >
  249. {group.group_name}
  250. </Popover>
  251. </Menu.Item>
  252. );
  253. } else {
  254. return (
  255. <Menu.Item key={`${group._id}`} className="group-item">
  256. <Icon type="folder-open" />
  257. {group.group_name}
  258. </Menu.Item>
  259. );
  260. }
  261. })}
  262. </Menu>
  263. </div>
  264. {this.state.addGroupModalVisible ? (
  265. <Modal
  266. title="添加分组"
  267. visible={this.state.addGroupModalVisible}
  268. onOk={this.addGroup}
  269. onCancel={this.hideModal}
  270. className="add-group-modal"
  271. >
  272. <Row gutter={6} className="modal-input">
  273. <Col span="5">
  274. <div className="label">分组名:</div>
  275. </Col>
  276. <Col span="15">
  277. <Input placeholder="请输入分组名称" onChange={this.inputNewGroupName} />
  278. </Col>
  279. </Row>
  280. <Row gutter={6} className="modal-input">
  281. <Col span="5">
  282. <div className="label">简介:</div>
  283. </Col>
  284. <Col span="15">
  285. <TextArea rows={3} placeholder="请输入分组描述" onChange={this.inputNewGroupDesc} />
  286. </Col>
  287. </Row>
  288. <Row gutter={6} className="modal-input">
  289. <Col span="5">
  290. <div className="label">组长:</div>
  291. </Col>
  292. <Col span="15">
  293. <UsernameAutoComplete callbackState={this.onUserSelect} />
  294. </Col>
  295. </Row>
  296. </Modal>
  297. ) : (
  298. ''
  299. )}
  300. </div>
  301. );
  302. }
  303. }