Organization.tsx 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import React from 'react'
  2. import { Link } from 'react-router-dom'
  3. import { Icon, Tabs, Breadcrumb } from 'antd'
  4. import Box from 'components/Box'
  5. const styles = require('./Organization.less')
  6. import MemberList from './component/MemberList'
  7. import ProjectList from './component/ProjectList'
  8. import Setting from './component/Setting'
  9. import RoleList from './component/RoleList'
  10. const utilStyles = require('assets/less/util.less')
  11. const TabPane = Tabs.TabPane
  12. import Avatar from 'components/Avatar'
  13. import { connect } from 'react-redux'
  14. import injectReducer from 'utils/injectReducer'
  15. import injectSaga from 'utils/injectSaga'
  16. import reducerProject from '../Projects/reducer'
  17. import sagaProject from '../Projects/sagas'
  18. import { compose } from 'redux'
  19. import { OrganizationActions } from './actions'
  20. import { makeSelectLoginUser } from 'containers/App/selectors'
  21. import {
  22. makeSelectOrganizations,
  23. makeSelectCurrentOrganizations,
  24. makeSelectCurrentOrganizationProjects,
  25. makeSelectCurrentOrganizationProjectsDetail,
  26. makeSelectCurrentOrganizationRole,
  27. makeSelectCurrentOrganizationMembers,
  28. makeSelectInviteMemberList
  29. } from './selectors'
  30. import { createStructuredSelector } from 'reselect'
  31. import { ProjectActions } from 'containers/Projects/actions'
  32. import { makeSelectStarUserList, makeSelectCollectProjects } from '../Projects/selectors'
  33. import { RouteComponentWithParams } from 'utils/types'
  34. import { IOrganization, IOrganizationProps } from './types'
  35. export class Organization extends React.PureComponent <IOrganizationProps & RouteComponentWithParams, {}> {
  36. constructor (props) {
  37. super(props)
  38. }
  39. private toProject = (id: number) => () => {
  40. this.props.history.push(`/project/${id}`)
  41. }
  42. public componentWillMount () {
  43. const {
  44. onLoadOrganizationMembers,
  45. onLoadOrganizationDetail,
  46. onLoadOrganizationRole,
  47. match
  48. } = this.props
  49. const organizationId = +match.params.organizationId
  50. onLoadOrganizationMembers(organizationId)
  51. onLoadOrganizationDetail(organizationId)
  52. onLoadOrganizationRole(organizationId)
  53. }
  54. private deleteOrganization = (id) => {
  55. this.props.onDeleteOrganization(id, () => {
  56. this.props.history.push(`/account/organizations`)
  57. })
  58. }
  59. private editOrganization = (organization) => () => {
  60. this.props.onEditOrganization(organization)
  61. }
  62. private getRolesTotal (): number {
  63. const { currentOrganizationRole } = this.props
  64. return Array.isArray(currentOrganizationRole) ? currentOrganizationRole.length : 0
  65. }
  66. private getProjectsTotal () {
  67. const { currentOrganizationProjects } = this.props
  68. return Array.isArray(currentOrganizationProjects) ? currentOrganizationProjects.length : 0
  69. }
  70. private getMembersTotal () {
  71. const { currentOrganizationMembers } = this.props
  72. return Array.isArray(currentOrganizationMembers) ? currentOrganizationMembers.length : 0
  73. }
  74. public render () {
  75. const {
  76. loginUser,
  77. organizations,
  78. currentOrganization,
  79. currentOrganizationMembers,
  80. inviteMemberList,
  81. match: { params: { organizationId } },
  82. currentOrganizationProjectsDetail
  83. } = this.props
  84. if (!currentOrganization) { return null }
  85. const { avatar, name} = currentOrganization as IOrganization
  86. const memeberOfLoginUser = currentOrganizationMembers && currentOrganizationMembers.find((m) => m.user.id === loginUser.id)
  87. const isLoginUserOwner = !!memeberOfLoginUser && memeberOfLoginUser.user.role === 1
  88. return (
  89. <Box>
  90. <Box.Header>
  91. <Box.Title>
  92. <Breadcrumb className={utilStyles.breadcrumb}>
  93. <Breadcrumb.Item>
  94. <Link to="/account/organizations">
  95. <Icon type="left-circle-o" />返回组织列表
  96. </Link>
  97. </Breadcrumb.Item>
  98. </Breadcrumb>
  99. </Box.Title>
  100. </Box.Header>
  101. <Box.Body>
  102. <div className={styles.organizationLogo}>
  103. <Avatar path={avatar} enlarge={false} size="small"/>
  104. <div className={styles.title}>{name}</div>
  105. </div>
  106. <Tabs>
  107. <TabPane tab={<span><Icon type="api" />项目<span className={styles.badge}>{this.getProjectsTotal()}</span></span>} key="projects">
  108. <ProjectList
  109. toProject={this.toProject}
  110. organizationId={+organizationId}
  111. currentOrganization={currentOrganization}
  112. organizationMembers={currentOrganizationMembers}
  113. organizationProjectsDetail={currentOrganizationProjectsDetail}
  114. />
  115. </TabPane>
  116. <TabPane tab={<span><Icon type="user" />成员<span className={styles.badge}>{this.getMembersTotal()}</span></span>} key="members">
  117. <MemberList
  118. loginUser={loginUser}
  119. organizationId={+organizationId}
  120. loadOrganizationsMembers={this.props.onLoadOrganizationMembers}
  121. organizationMembers={currentOrganizationMembers}
  122. currentOrganization={currentOrganization}
  123. inviteMemberList={inviteMemberList}
  124. onInviteMember={this.props.onInviteMember}
  125. handleSearchMember={this.props.onSearchMember}
  126. deleteOrganizationMember={this.props.onDeleteOrganizationMember}
  127. changeOrganizationMemberRole={this.props.onChangeOrganizationMemberRole}
  128. onGetRoleListByMemberId={this.props.onGetRoleListByMemberId}
  129. />
  130. </TabPane>
  131. <TabPane tab={<span><Icon type="usergroup-add" />角色<span className={styles.badge}>{this.getRolesTotal()}</span></span>} key="roles">
  132. <RoleList
  133. isLoginUserOwner={isLoginUserOwner}
  134. onLoadOrganizationDetail={this.props.onLoadOrganizationDetail}
  135. organizations={organizations}
  136. organizationMembers={currentOrganizationMembers}
  137. currentOrganization={this.props.currentOrganization}
  138. />
  139. </TabPane>
  140. {
  141. currentOrganization && currentOrganization.role === 1 ? <TabPane tab={<span><Icon type="setting" />设置</span>} key="settings">
  142. <Setting
  143. currentOrganization={this.props.currentOrganization}
  144. editOrganization={this.editOrganization}
  145. deleteOrganization={this.deleteOrganization}
  146. />
  147. </TabPane> : ''}
  148. </Tabs>
  149. </Box.Body>
  150. </Box>
  151. )
  152. }
  153. }
  154. const mapStateToProps = createStructuredSelector({
  155. loginUser: makeSelectLoginUser(),
  156. starUserList: makeSelectStarUserList(),
  157. organizations: makeSelectOrganizations(),
  158. inviteMemberList: makeSelectInviteMemberList(),
  159. currentOrganization: makeSelectCurrentOrganizations(),
  160. currentOrganizationRole: makeSelectCurrentOrganizationRole(),
  161. currentOrganizationMembers: makeSelectCurrentOrganizationMembers(),
  162. currentOrganizationProjects: makeSelectCurrentOrganizationProjects(),
  163. currentOrganizationProjectsDetail: makeSelectCurrentOrganizationProjectsDetail()
  164. })
  165. export function mapDispatchToProps (dispatch) {
  166. return {
  167. onGetProjectStarUser: (id) => dispatch(ProjectActions.getProjectStarUser(id)),
  168. onLoadOrganizationProjects: (param) => dispatch(OrganizationActions.loadOrganizationProjects(param)),
  169. onLoadOrganizationRole: (orgId) => dispatch(OrganizationActions.loadOrganizationRole(orgId)),
  170. onLoadOrganizationMembers: (id) => dispatch(OrganizationActions.loadOrganizationMembers(id)),
  171. onLoadOrganizationDetail: (id) => dispatch(OrganizationActions.loadOrganizationDetail(id)),
  172. onEditOrganization: (organization) => dispatch(OrganizationActions.editOrganization(organization)),
  173. onDeleteOrganization: (id, resolve) => dispatch(OrganizationActions.deleteOrganization(id, resolve)),
  174. onSearchMember: (keyword) => dispatch(OrganizationActions.searchMember(keyword)),
  175. onInviteMember: (orgId, members, needEmail, resolve) => dispatch(OrganizationActions.inviteMember(orgId, members, needEmail, resolve)),
  176. onDeleteOrganizationMember: (id, resolve) => dispatch(OrganizationActions.deleteOrganizationMember(id, resolve)),
  177. onChangeOrganizationMemberRole: (id, role, resolve) => dispatch(OrganizationActions.changeOrganizationMemberRole(id, role, resolve)),
  178. onGetRoleListByMemberId: (orgId, memberId, resolve) => dispatch(OrganizationActions.getRoleListByMemberId(orgId, memberId, resolve))
  179. }
  180. }
  181. const withConnect = connect(mapStateToProps, mapDispatchToProps)
  182. const withProjectReducer = injectReducer({ key: 'project', reducer: reducerProject })
  183. const withProjectSaga = injectSaga({ key: 'project', saga: sagaProject })
  184. export default compose(
  185. withProjectReducer,
  186. withProjectSaga,
  187. withConnect
  188. )(Organization)