RoleList.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. import React from 'react'
  2. import FormType from 'antd/lib/form/Form'
  3. import { createStructuredSelector } from 'reselect'
  4. import RoleForm from './RoleForm'
  5. import CheckPanel from 'app/components/CheckPanel'
  6. // import RelRoleMember from './RelRoleMember'
  7. import { connect } from 'react-redux'
  8. import { Row, Col, Tooltip, Button, Input, Table, Modal, Popconfirm, Divider, message } from 'antd'
  9. import { ColumnProps } from 'antd/lib/table'
  10. const styles = require('../Organization.less')
  11. import { checkNameUniqueAction } from 'containers/App/actions'
  12. import { OrganizationActions } from '../actions'
  13. const { addRole, loadOrganizationRole, deleteRole, relRoleMember, editRole, getRelRoleMember } = OrganizationActions
  14. import ComponentPermission from 'containers/Account/components/checkMemberPermission'
  15. import { makeSelectRoleModalLoading, makeSelectCurrentOrganizationRole } from '../selectors'
  16. import { IOrganization, IOrganizationRole } from '../types'
  17. interface IRoleState {
  18. formType: string
  19. formVisible: boolean
  20. relFormVisible: boolean
  21. currentRoleId: number
  22. currentOrganizationRole: any[]
  23. groupTransfer: { id: string, targets: any[] }
  24. searchValue: string
  25. filteredTableSource: {
  26. type: 'origin' | 'filtered'
  27. dataSource: any[]
  28. }
  29. }
  30. interface IRoleProps {
  31. isLoginUserOwner?: boolean
  32. onAddRole?: (name: string, desc: string, id: number, resolve: () => any) => any
  33. onEditRole?: (name: string, desc: string, id: number, resolve: () => any) => any
  34. onDeleteRole?: (id, resolve) => any
  35. onRelRoleMember?: (id: number, memberIds: number[], resolve: () => any) => any
  36. onGetRelRoleMember?: (id: number, resolve: (result: any) => any) => any
  37. onLoadOrganizationRole?: (orgId: number) => any
  38. currentOrganization?: IOrganization
  39. currentOrganizationRole?: IOrganizationRole[]
  40. organizationMembers?: any[]
  41. organizations?: any
  42. roleModalLoading?: boolean
  43. onLoadOrganizationDetail?: (id: number) => any
  44. onCheckUniqueName?: (pathname: any, data: any, resolve: () => any, reject: (error: string) => any) => any
  45. }
  46. export interface ITeam {
  47. id?: number
  48. role?: number
  49. avatar?: string
  50. organization?: IOrganization
  51. name?: string
  52. visibility?: boolean
  53. description: string
  54. parentTeamId: number
  55. }
  56. export class RoleList extends React.PureComponent<IRoleProps, IRoleState> {
  57. constructor(props) {
  58. super(props)
  59. this.state = {
  60. formType: 'add',
  61. formVisible: false,
  62. relFormVisible: false,
  63. currentRoleId: 0,
  64. currentOrganizationRole: [],
  65. groupTransfer: {
  66. id: '',
  67. targets: []
  68. },
  69. searchValue: '',
  70. filteredTableSource: {
  71. type: 'origin',
  72. dataSource: []
  73. }
  74. }
  75. }
  76. private RoleForm: FormType
  77. private RelRoleMember: FormType
  78. private refHandles = {
  79. RoleForm: (ref) => this.RoleForm = ref,
  80. RelRoleMember: (ref) => this.RelRoleMember = ref
  81. }
  82. private showRelRoleForm = (flag, roleId?: number) => (e) => {
  83. const { onGetRelRoleMember } = this.props
  84. e.stopPropagation()
  85. onGetRelRoleMember(roleId, (result) => {
  86. const targets = result && result.length ? result.map((re) => re.user.id) : []
  87. // const targets = result && result.length ? result.map((re) => re.user) : []
  88. this.setState({
  89. relFormVisible: !this.state.relFormVisible,
  90. currentRoleId: roleId,
  91. groupTransfer: {
  92. id: `${roleId}`,
  93. targets
  94. }
  95. })
  96. })
  97. }
  98. public componentDidMount() {
  99. const { currentOrganizationRole } = this.props
  100. if (!currentOrganizationRole) {
  101. this.loadOrganizationRole()
  102. } else {
  103. this.setState({ currentOrganizationRole })
  104. }
  105. }
  106. public componentWillReceiveProps(nextProps) {
  107. const { currentOrganizationRole } = nextProps
  108. if (currentOrganizationRole !== this.props.currentOrganizationRole) {
  109. this.setState({
  110. currentOrganizationRole
  111. })
  112. }
  113. }
  114. private loadOrganizationRole = () => this.props.onLoadOrganizationRole(this.props.currentOrganization['id'])
  115. private showRoleForm = (flag, roleId?: number) => (e) => {
  116. e.stopPropagation()
  117. this.setState({
  118. formVisible: !this.state.formVisible,
  119. formType: flag
  120. }, () => {
  121. if (flag !== 'add') {
  122. setTimeout(() => {
  123. const { description, id, name } = this.props.currentOrganizationRole.find((role) => role.id === roleId)
  124. this.RoleForm.props.form.setFieldsValue({ description, id, name })
  125. }, 0)
  126. }
  127. })
  128. }
  129. private checkNameUnique = (rule, value = '', callback) => {
  130. const { onCheckUniqueName, currentOrganization: { id } } = this.props
  131. const data = {
  132. name: value,
  133. orgId: id,
  134. id: null
  135. }
  136. onCheckUniqueName('team', data,
  137. () => {
  138. callback()
  139. }, (err) => {
  140. callback(err)
  141. })
  142. }
  143. private onSaveRelRowMember = () => {
  144. const { onRelRoleMember } = this.props
  145. const { currentRoleId, groupTransfer } = this.state
  146. onRelRoleMember(currentRoleId, groupTransfer.targets, () => {
  147. this.hideRelForm()
  148. })
  149. }
  150. private hideTeamForm = () => {
  151. this.setState({
  152. formVisible: false
  153. })
  154. }
  155. private hideRelForm = () => {
  156. this.setState({
  157. relFormVisible: false
  158. })
  159. }
  160. private afterTeamFormClose = () => {
  161. this.RoleForm.props.form.resetFields()
  162. }
  163. // private afterRelFormClose = () => {
  164. // this.RelRoleMember.props.form.resetFields()
  165. // }
  166. private handleDelete = (roleId) => () => {
  167. const { onDeleteRole } = this.props
  168. this.loadOrganizationRole()
  169. if (roleId) {
  170. onDeleteRole(roleId, () => {
  171. message.success('删除成功')
  172. this.loadOrganizationRole()
  173. })
  174. }
  175. }
  176. private onGroupTransferChange = (targets) => {
  177. this.setState({
  178. groupTransfer: {
  179. id: this.state.groupTransfer.id,
  180. targets
  181. }
  182. })
  183. }
  184. private searchChange = (e) => {
  185. const searchValue = e.target.value
  186. const { currentOrganizationRole } = this.props
  187. const result = (currentOrganizationRole as any[]).filter((role) => {
  188. return role && role.name.indexOf(searchValue.trim()) > -1
  189. })
  190. this.setState({
  191. searchValue,
  192. currentOrganizationRole: searchValue && searchValue.length ? result : this.props.currentOrganizationRole
  193. })
  194. }
  195. private createOrRole = () => {
  196. const { formType } = this.state
  197. const { onAddRole, onEditRole } = this.props
  198. this.RoleForm.props.form.validateFieldsAndScroll((err, values) => {
  199. if (!err) {
  200. const { name, description, id } = values
  201. const orgId = this.props.currentOrganization.id
  202. if (formType === 'add') {
  203. onAddRole(name, description, orgId, () => {
  204. this.loadOrganizationRole()
  205. this.hideTeamForm()
  206. })
  207. } else {
  208. onEditRole(name, description, id, () => {
  209. this.loadOrganizationRole()
  210. this.hideTeamForm()
  211. })
  212. }
  213. }
  214. })
  215. }
  216. public render() {
  217. const { formVisible, relFormVisible, searchValue, filteredTableSource, formType, groupTransfer, currentOrganizationRole } = this.state
  218. const { isLoginUserOwner, currentOrganization, currentOrganization: { id }, roleModalLoading, organizationMembers } = this.props
  219. const roleModalTitle = formType === 'add' ? '新增角色' : '修改角色信息'
  220. const relRoleModalTitle = '关联成员'
  221. let CreateButton = void 0
  222. if (currentOrganization) {
  223. CreateButton = ComponentPermission(currentOrganization, '')(Button)
  224. }
  225. let columns: Array<ColumnProps<any>> = [
  226. {
  227. title: '角色名',
  228. dataIndex: 'name',
  229. key: 'name'
  230. },
  231. {
  232. title: '描述',
  233. dataIndex: 'description',
  234. key: 'description'
  235. }
  236. ]
  237. if (isLoginUserOwner) {
  238. columns = columns.concat({
  239. title: '操作',
  240. dataIndex: 'setting',
  241. key: 'setting',
  242. render: (text, record) => (
  243. <span>
  244. <a href="javascript:;" onClick={this.showRelRoleForm('add', record.id)}>关联成员</a>
  245. <Divider type="vertical" />
  246. <a href="javascript:;" onClick={this.showRoleForm('edit', record.id)}>编辑</a>
  247. <Divider type="vertical" />
  248. <Popconfirm title="确定删除?" onConfirm={this.handleDelete(record.id)}>
  249. <a href="javascript:;">删除</a>
  250. </Popconfirm>
  251. </span>
  252. )
  253. })
  254. }
  255. const addModalButtons =
  256. (
  257. <Button
  258. key="submit"
  259. type="primary"
  260. loading={roleModalLoading}
  261. disabled={roleModalLoading}
  262. onClick={this.createOrRole}
  263. >
  264. 保 存
  265. </Button>
  266. )
  267. const relRoleModalButtons =
  268. (
  269. <Button
  270. key="submit"
  271. type="primary"
  272. loading={roleModalLoading}
  273. disabled={roleModalLoading}
  274. onClick={this.onSaveRelRowMember}
  275. >
  276. 保 存
  277. </Button>
  278. )
  279. const roleMembers = organizationMembers.map(v => v.user)
  280. return (
  281. <div className={styles.listWrapper}>
  282. <Row>
  283. <Col span={16}>
  284. <Input.Search
  285. value={searchValue}
  286. placeholder="搜索角色"
  287. onChange={this.searchChange}
  288. />
  289. </Col>
  290. <Col span={1} offset={7}>
  291. <Tooltip placement="bottom" title="创建角色">
  292. <CreateButton
  293. type="primary"
  294. icon="plus"
  295. onClick={this.showRoleForm('add')}
  296. />
  297. </Tooltip>
  298. </Col>
  299. </Row>
  300. <Row>
  301. <div className={styles.tableWrap}>
  302. <Table
  303. bordered
  304. columns={columns}
  305. dataSource={currentOrganizationRole}
  306. />
  307. </div>
  308. </Row>
  309. <Modal
  310. title={roleModalTitle}
  311. visible={formVisible}
  312. footer={addModalButtons}
  313. onCancel={this.hideTeamForm}
  314. afterClose={this.afterTeamFormClose}
  315. >
  316. <RoleForm
  317. type={formType}
  318. groupSource={[]}
  319. organizationMembers={organizationMembers}
  320. groupTarget={groupTransfer.targets}
  321. onGroupChange={this.onGroupTransferChange}
  322. wrappedComponentRef={this.refHandles.RoleForm}
  323. />
  324. </Modal>
  325. <Modal
  326. width={1040}
  327. title={relRoleModalTitle}
  328. visible={relFormVisible}
  329. footer={relRoleModalButtons}
  330. onCancel={this.hideRelForm}
  331. destroyOnClose={true}
  332. // afterClose={this.afterRelFormClose}
  333. >
  334. {/* <RelRoleMember
  335. organizationMembers={organizationMembers}
  336. groupTarget={groupTransfer.targets}
  337. onGroupChange={this.onGroupTransferChange}
  338. wrappedComponentRef={this.refHandles.RelRoleMember}
  339. /> */}
  340. <CheckPanel
  341. dataSource={roleMembers}
  342. defaultKeys={groupTransfer.targets}
  343. closableByTag={true}
  344. labelKey={'username'}
  345. valueKey={'id'}
  346. placeholder={'请输入用户名'}
  347. tokenSeparators={[';']}
  348. onChange={this.onGroupTransferChange}
  349. />
  350. </Modal>
  351. </div>
  352. )
  353. }
  354. }
  355. type MappedStates = ReturnType<typeof mapStateToProps>
  356. type MappedDispatches = ReturnType<typeof mapDispatchToProps>
  357. const mapStateToProps = createStructuredSelector({
  358. roleModalLoading: makeSelectRoleModalLoading(),
  359. currentOrganizationRole: makeSelectCurrentOrganizationRole(),
  360. })
  361. export function mapDispatchToProps(dispatch) {
  362. return {
  363. onLoadOrganizationRole: (orgId) => dispatch(loadOrganizationRole(orgId)),
  364. onAddRole: (name, desc, id, resolve) => dispatch(addRole(name, desc, id, resolve)),
  365. onEditRole: (name, desc, id, resolve) => dispatch(editRole(name, desc, id, resolve)),
  366. onDeleteRole: (id, resolve) => dispatch(deleteRole(id, resolve)),
  367. onRelRoleMember: (id, memberIds, resolve) => dispatch(relRoleMember(id, memberIds, resolve)),
  368. onGetRelRoleMember: (id, resolve) => dispatch(getRelRoleMember(id, resolve)),
  369. onCheckUniqueName: (pathname, data, resolve, reject) => dispatch(checkNameUniqueAction(pathname, data, resolve, reject))
  370. }
  371. }
  372. export default connect<MappedStates, MappedDispatches, IRoleProps>(mapStateToProps, mapDispatchToProps)(RoleList)