ProjectRole.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. /*
  2. * <<
  3. * Davinci
  4. * ==
  5. * Copyright (C) 2016 - 2017 EDP
  6. * ==
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. * >>
  19. */
  20. import React from 'react'
  21. import { compose } from 'redux'
  22. import { connect } from 'react-redux'
  23. import {
  24. Button,
  25. Row,
  26. Col,
  27. Input,
  28. Tooltip,
  29. Popconfirm,
  30. Table,
  31. Modal,
  32. Form,
  33. Divider
  34. } from 'antd'
  35. import RoleForm from './Transfer'
  36. import Auth from './ProjectAuth'
  37. import AntdFormType from 'antd/lib/form/Form'
  38. import { OrganizationActions } from '../actions'
  39. const {
  40. loadOrganizationRole,
  41. loadProjectRoles,
  42. getVizVisbility,
  43. postVizVisbility
  44. } = OrganizationActions
  45. const styles = require('../Project.less')
  46. import { createStructuredSelector } from 'reselect'
  47. import { ProjectActions } from 'containers/Projects/actions'
  48. const {
  49. addProjectRole,
  50. loadRelRoleProject,
  51. updateRelRoleProject,
  52. deleteRelRoleProject
  53. } = ProjectActions
  54. import {
  55. makeSelectCurrentOrganizationProject,
  56. makeSelectCurrentOrganizationRole,
  57. makeSelectCurrentOrganizationProjectRoles,
  58. makeSelectCurrentOrganizations
  59. } from '../selectors'
  60. import { makeSelectCurrentProjectRole } from 'containers/Projects/selectors'
  61. import { makeSelectVizs } from 'containers/Schedule/selectors'
  62. interface IRoleStates {
  63. relationRoleVisible: boolean
  64. authSettingVisible: boolean
  65. roleTargetKeys: any[]
  66. projectRoles: any[]
  67. searchValue: string
  68. vizs: any[]
  69. }
  70. export interface IProjectRoles {
  71. id: number
  72. name: string
  73. description: string
  74. }
  75. interface IRoleProps {
  76. form?: any
  77. projectRoles: IProjectRoles[]
  78. projectDetail: any
  79. organizationRoles: any[]
  80. currentProjectRole: {
  81. id: number
  82. description: string
  83. name: string
  84. permission: object
  85. }
  86. vizs: any
  87. currentOrganization: any
  88. onLoadOrganizationRole: (id: number) => any
  89. onLoadProjectRoles: (id: number) => any
  90. onAddProjectRole: (id: number, roleIds: number[], resolve: () => any) => any
  91. onLoadRelRoleProject: (id: number, roleId: number) => any
  92. onUpdateRelRoleProject: (
  93. roleId: number,
  94. projectId: number,
  95. projectRole: object
  96. ) => any
  97. onDeleteRelRoleProject: (
  98. roleId: number,
  99. projectId: number,
  100. resolve?: () => any
  101. ) => () => any
  102. onLoadVizVisbility: (roleId: number, projectId: number, resolve: any) => any
  103. onPostVizVisbility: (id: number, permission: object, reslove: any) => any
  104. }
  105. export class ProjectRole extends React.Component<IRoleProps, IRoleStates> {
  106. private RoleForm: AntdFormType = null
  107. private refHandlers = {
  108. RoleForm: (ref) => (this.RoleForm = ref)
  109. }
  110. constructor(props) {
  111. super(props)
  112. this.state = {
  113. vizs: [],
  114. searchValue: '',
  115. projectRoles: [],
  116. roleTargetKeys: [],
  117. relationRoleVisible: false,
  118. authSettingVisible: false
  119. }
  120. }
  121. public componentWillMount() {
  122. const { vizs } = this.props
  123. this.loadOrganizationRole()
  124. this.loadProjectRoles(this.props.projectDetail['id'])
  125. if (vizs && vizs.length) {
  126. this.setState({ vizs })
  127. }
  128. }
  129. private loadOrganizationRole = () =>
  130. this.props.onLoadOrganizationRole(this.props.currentOrganization['id'])
  131. private loadProjectRoles = (id) => this.props.onLoadProjectRoles(id)
  132. private loopVizs = (key, value, tree) => {
  133. tree.forEach((viz) => {
  134. if (viz.children) {
  135. this.loopVizs(key, value, viz.children)
  136. }
  137. if (viz.vizType === key.slice(0, -1)) {
  138. viz.permission = value.some((val) => val === viz.id) ? 0 : 1
  139. } else {
  140. return
  141. }
  142. })
  143. }
  144. private toggleModal = (flag: string, id?: number) => () => {
  145. if (id) {
  146. const {
  147. onLoadRelRoleProject,
  148. projectDetail,
  149. onLoadVizVisbility
  150. } = this.props
  151. const vizs = this.state.vizs
  152. onLoadRelRoleProject(projectDetail.id, id)
  153. onLoadVizVisbility(id, projectDetail.id, (result) => {
  154. Object.entries(result).forEach(([key, value]) => {
  155. this.loopVizs(key, value, vizs)
  156. this.setState({
  157. vizs
  158. })
  159. })
  160. })
  161. }
  162. if (flag === 'relationRoleVisible') {
  163. this.setState({
  164. relationRoleVisible: !this.state[flag]
  165. })
  166. } else {
  167. this.setState({
  168. authSettingVisible: !this.state[flag]
  169. })
  170. }
  171. }
  172. public componentWillReceiveProps(nextProps) {
  173. const {
  174. projectRoles,
  175. projectDetail: { id }
  176. } = nextProps
  177. if (projectRoles !== this.props.projectRoles) {
  178. this.setState({
  179. projectRoles
  180. })
  181. const roled = projectRoles.map((role) => role.id)
  182. this.setState({ roleTargetKeys: roled })
  183. }
  184. if (id !== this.props.projectDetail['id']) {
  185. this.loadProjectRoles(id)
  186. }
  187. }
  188. private searchChange = (e) => {
  189. const searchValue = e.target.value
  190. const result = (this.props.projectRoles as any[]).filter((role) => {
  191. return role && role.name.trim().indexOf(searchValue.trim()) > -1
  192. })
  193. this.setState({
  194. searchValue,
  195. projectRoles:
  196. searchValue && searchValue.length ? result : this.props.projectRoles
  197. })
  198. }
  199. private onRelProjectrole = () => {
  200. const { roleTargetKeys } = this.state
  201. const {
  202. projectDetail: { id }
  203. } = this.props
  204. this.props.onAddProjectRole(id, roleTargetKeys, () => {
  205. this.loadProjectRoles(id)
  206. this.toggleModal('relationRoleVisible')()
  207. })
  208. }
  209. private setRowKeys = (item) => item.id
  210. private setTransferOptionTitle = (item) => item.name
  211. private setRoleTargetKeys = (newTargetKeys) => {
  212. if (newTargetKeys) {
  213. this.setState({ roleTargetKeys: newTargetKeys })
  214. }
  215. }
  216. private changeModulePermission = (record, event) => {
  217. const { user } = record
  218. const {
  219. onUpdateRelRoleProject,
  220. currentProjectRole,
  221. projectDetail
  222. } = this.props
  223. onUpdateRelRoleProject(currentProjectRole.id, projectDetail.id, {
  224. ...currentProjectRole.permission,
  225. [`${user}Permission`]: event.target.value
  226. })
  227. }
  228. private changeVizPermission = (record, event) => {
  229. const {
  230. onPostVizVisbility,
  231. currentProjectRole: { id }
  232. } = this.props
  233. const { vizs } = this.state
  234. onPostVizVisbility(
  235. id,
  236. {
  237. id: record.id,
  238. visible: event.target.value,
  239. viz: record.vizType
  240. },
  241. (result) => {
  242. loop(vizs, record)
  243. this.setState({ vizs })
  244. }
  245. )
  246. function loop(arr, record) {
  247. arr.forEach((a) => {
  248. if (a.children && a.children.length) {
  249. loop(a.children, record)
  250. }
  251. if (a.id && a.id === record.id && a.vizType === record.vizType) {
  252. a.permission = event.target.value
  253. } else {
  254. return
  255. }
  256. })
  257. }
  258. }
  259. public render() {
  260. const { organizationRoles, projectDetail } = this.props
  261. const { projectRoles } = this.state
  262. const roles = projectRoles && projectRoles.length ? projectRoles : []
  263. const addButton = (
  264. <Tooltip placement="bottom" title="关联">
  265. <Button
  266. type="primary"
  267. icon="plus"
  268. onClick={this.toggleModal('relationRoleVisible')}
  269. >
  270. 关联角色
  271. </Button>
  272. </Tooltip>
  273. )
  274. const relButton = (
  275. <Button
  276. key="submit"
  277. type="primary"
  278. // loading={adminModalLoading}
  279. // disabled={adminModalLoading}
  280. onClick={this.onRelProjectrole}
  281. >
  282. 保 存
  283. </Button>
  284. )
  285. const columns = [
  286. {
  287. title: '角色名称',
  288. dataIndex: 'name',
  289. key: 'rolename'
  290. // render: (text) => <span>{text.role === 1 ? '拥有者' : '成员'}</span>
  291. },
  292. {
  293. title: '设置',
  294. dataIndex: 'user',
  295. // className: isHidden ? utilStyles.hide : '',
  296. key: 'settings',
  297. render: (text, record) => {
  298. return (
  299. <span>
  300. <a
  301. href="javascript:;"
  302. onClick={this.toggleModal('authSettingVisible', record.id)}
  303. >
  304. 权限设置
  305. </a>
  306. <Divider type="vertical" />
  307. <Popconfirm
  308. title="确定删除?"
  309. placement="bottom"
  310. onConfirm={this.props.onDeleteRelRoleProject(
  311. record.id,
  312. projectDetail.id,
  313. () => this.loadProjectRoles(projectDetail.id)
  314. )}
  315. >
  316. <Tooltip title="删除">
  317. <a href="javascript:;">删除角色</a>
  318. </Tooltip>
  319. </Popconfirm>
  320. </span>
  321. )
  322. }
  323. }
  324. ]
  325. return (
  326. <div className={styles.role}>
  327. <Row>
  328. <Col span={14}>
  329. <Input.Search
  330. placeholder="搜索角色"
  331. value={this.state.searchValue}
  332. onChange={this.searchChange}
  333. />
  334. </Col>
  335. <Col span={2} offset={6}>
  336. {addButton}
  337. </Col>
  338. </Row>
  339. <Row>
  340. <div className={styles.tableWrap}>
  341. <Table
  342. bordered
  343. columns={columns}
  344. dataSource={roles}
  345. pagination={false}
  346. />
  347. </div>
  348. </Row>
  349. <Modal
  350. key="roleFormKey"
  351. title="关联角色"
  352. visible={this.state.relationRoleVisible}
  353. footer={relButton}
  354. onCancel={this.toggleModal('relationRoleVisible')}
  355. // afterClose={this.afterMemberFormClose}
  356. >
  357. <RoleForm
  358. wrappedComponentRef={this.refHandlers.RoleForm}
  359. dataSource={organizationRoles}
  360. optionTitle={this.setTransferOptionTitle}
  361. adminTargetKeys={this.state.roleTargetKeys}
  362. targetKeys={this.state.roleTargetKeys}
  363. setTargetKeys={this.setRoleTargetKeys}
  364. rowKeys={this.setRowKeys}
  365. />
  366. </Modal>
  367. <Modal
  368. footer={null}
  369. title="权限设置"
  370. visible={this.state.authSettingVisible}
  371. onCancel={this.toggleModal('authSettingVisible')}
  372. // afterClose={this.afterChangeRoleFormClose}
  373. wrapClassName="ant-modal-large ant-modal-center"
  374. >
  375. <Auth
  376. vizs={this.state.vizs}
  377. currentProjectRole={this.props.currentProjectRole}
  378. onChangeModulePermission={this.changeModulePermission}
  379. onChangeVizPermission={this.changeVizPermission}
  380. />
  381. </Modal>
  382. </div>
  383. )
  384. }
  385. }
  386. const mapStateToProps = createStructuredSelector({
  387. vizs: makeSelectVizs(),
  388. currentOrganization: makeSelectCurrentOrganizations(),
  389. projectDetail: makeSelectCurrentOrganizationProject(),
  390. organizationRoles: makeSelectCurrentOrganizationRole(),
  391. projectRoles: makeSelectCurrentOrganizationProjectRoles(),
  392. currentProjectRole: makeSelectCurrentProjectRole()
  393. })
  394. export function mapDispatchToProps(dispatch) {
  395. return {
  396. onLoadOrganizationRole: (id) => dispatch(loadOrganizationRole(id)),
  397. onLoadProjectRoles: (id) => dispatch(loadProjectRoles(id)),
  398. onAddProjectRole: (id, roleIds, resolve) =>
  399. dispatch(addProjectRole(id, roleIds, resolve)),
  400. onLoadRelRoleProject: (id, roleId) =>
  401. dispatch(loadRelRoleProject(id, roleId)),
  402. onUpdateRelRoleProject: (roleId, projectId, projectRole) =>
  403. dispatch(updateRelRoleProject(roleId, projectId, projectRole)),
  404. onDeleteRelRoleProject: (roleId, projectId, resolve) => () =>
  405. dispatch(deleteRelRoleProject(roleId, projectId, resolve)),
  406. onLoadVizVisbility: (roleId, projectId, resolve) =>
  407. dispatch(getVizVisbility(roleId, projectId, resolve)),
  408. onPostVizVisbility: (id, permission, reslove) =>
  409. dispatch(postVizVisbility(id, permission, reslove))
  410. }
  411. }
  412. const withConnect = connect(mapStateToProps, mapDispatchToProps)
  413. export default compose(withConnect)(ProjectRole)