DisplayList.tsx 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. import React from 'react'
  2. import classnames from 'classnames'
  3. import { createStructuredSelector } from 'reselect'
  4. import { makeSelectProjectRoles } from 'containers/Projects/selectors'
  5. import { connect } from 'react-redux'
  6. import {compose} from 'redux'
  7. import { Col, Tooltip, Icon, Popconfirm, Row } from 'antd'
  8. import { IconProps } from 'antd/lib/icon'
  9. const styles = require('../Viz.less')
  10. import DisplayFormModal from './DisplayFormModal'
  11. import ModulePermission from 'containers/Account/components/checkModulePermission'
  12. import { IProject } from 'containers/Projects/types'
  13. import { IExludeRoles } from 'containers/Viz/components/PortalList'
  14. import { IProjectRoles } from 'containers/Organizations/component/ProjectRole'
  15. import { Display, DisplayFormType } from './types'
  16. export interface IDisplayEvent {
  17. onDisplayClick: (displayId: number) => () => void
  18. onAdd: (display: Display, resolve: () => void) => void
  19. onEdit: (display: Display, resolve: () => void) => void
  20. onCopy: (display: Display, resolve: () => void) => void
  21. onDelete: (displayId: number) => void
  22. }
  23. interface IDisplayListProps extends IDisplayEvent {
  24. projectId: number
  25. displays: Display[],
  26. currentProject?: IProject
  27. projectRoles: IProjectRoles[]
  28. onCheckName: (type, data, resolve, reject) => void
  29. onExcludeRoles: (type: string, id: number, resolve?: any) => any
  30. }
  31. interface IDisplayListStates {
  32. editingDisplay: Display
  33. modalLoading: boolean
  34. formType: DisplayFormType
  35. formVisible: boolean
  36. exludeRoles: IExludeRoles[]
  37. }
  38. export class DisplayList extends React.PureComponent<IDisplayListProps, IDisplayListStates> {
  39. constructor (props: IDisplayListProps) {
  40. super(props)
  41. this.state = {
  42. editingDisplay: null,
  43. modalLoading: false,
  44. formType: 'add',
  45. formVisible: false,
  46. exludeRoles: []
  47. }
  48. }
  49. private stopPPG = (e) => {
  50. e.stopPropagation()
  51. }
  52. public componentWillReceiveProps (nextProps) {
  53. if (nextProps && nextProps.projectRoles) {
  54. this.setState({
  55. exludeRoles: nextProps.projectRoles.map((role) => {
  56. return {
  57. ...role,
  58. permission: false
  59. }
  60. })
  61. })
  62. }
  63. }
  64. private saveDisplay = (display: Display, type: DisplayFormType) => {
  65. this.setState({ modalLoading: true })
  66. const { onAdd, onEdit, onCopy } = this.props
  67. const val = {
  68. ...display,
  69. roleIds: this.state.exludeRoles.filter((role) => !role.permission).map((p) => p.id)
  70. }
  71. if (typeof display.config === 'string' && display.config) {
  72. val.config = JSON.parse(display.config)
  73. }
  74. switch (type) {
  75. case 'add':
  76. onAdd({
  77. ...val
  78. }, () => { this.hideDisplayFormModal() })
  79. break
  80. case 'edit':
  81. onEdit({
  82. ...val
  83. }, () => { this.hideDisplayFormModal() })
  84. break
  85. case 'copy':
  86. onCopy({
  87. ...val
  88. }, () => { this.hideDisplayFormModal() })
  89. break
  90. }
  91. }
  92. private cancel = () => {
  93. this.setState({
  94. formVisible: false,
  95. modalLoading: false
  96. })
  97. }
  98. private showDisplayFormModal = (formType: DisplayFormType, display?: Display) => (e: React.MouseEvent<HTMLDivElement>) => {
  99. e.stopPropagation()
  100. this.setState({
  101. editingDisplay: formType === 'copy'
  102. ? {
  103. ...display,
  104. name: `${display.name}_copy`
  105. }
  106. : display,
  107. formType,
  108. formVisible: true
  109. })
  110. const { onExcludeRoles, projectRoles } = this.props
  111. if (onExcludeRoles && display) {
  112. onExcludeRoles('display', display.id, (result: number[]) => {
  113. this.setState({
  114. exludeRoles: projectRoles.map((role) => {
  115. return result.some((re) => re === role.id) ? role : {...role, permission: true}
  116. })
  117. })
  118. })
  119. } else {
  120. this.setState({
  121. exludeRoles: this.state.exludeRoles.map((role) => {
  122. return {
  123. ...role,
  124. permission: true
  125. }
  126. })
  127. })
  128. }
  129. }
  130. private hideDisplayFormModal = () => {
  131. this.setState({
  132. formVisible: false,
  133. modalLoading: false
  134. })
  135. }
  136. private delegate = (func: (...args) => void, ...args) => (e: React.MouseEvent<any>) => {
  137. func.apply(this, args)
  138. e.stopPropagation()
  139. }
  140. private changePermission = (scope: IExludeRoles, event) => {
  141. scope.permission = event.target.checked
  142. this.setState({
  143. exludeRoles: this.state.exludeRoles.map((role) => role && role.id === scope.id ? scope : role)
  144. })
  145. }
  146. private renderCreate () {
  147. return (
  148. <Col
  149. xxl={4}
  150. xl={6}
  151. lg={8}
  152. md={12}
  153. sm={24}
  154. key="createDisplay"
  155. >
  156. <div className={styles.display}>
  157. <div className={styles.container} onClick={this.showDisplayFormModal('add')}>
  158. <div className={styles.central}>
  159. <div className={`${styles.item} ${styles.icon}`}><Icon type="plus-circle-o" /></div>
  160. <div className={`${styles.item} ${styles.text}`}>创建新 大屏</div>
  161. </div>
  162. </div>
  163. </div>
  164. </Col>
  165. )
  166. }
  167. private renderDisplay (display: Display) {
  168. const coverStyle: React.CSSProperties = {
  169. backgroundImage: `url(${display.avatar})`
  170. }
  171. const { onDisplayClick, onDelete, currentProject } = this.props
  172. const editHint = !display.publish && '(编辑中…)'
  173. const displayClass = classnames({
  174. [styles.display]: true,
  175. [styles.editing]: !display.publish
  176. })
  177. const EditIcon = ModulePermission<IconProps>(currentProject, 'viz', false)(Icon)
  178. const AdminIcon = ModulePermission<IconProps>(currentProject, 'viz', true)(Icon)
  179. return (
  180. <Col
  181. xxl={4}
  182. xl={6}
  183. lg={8}
  184. md={12}
  185. sm={24}
  186. key={display.id}
  187. onClick={onDisplayClick(display.id)}
  188. >
  189. <div className={displayClass} style={coverStyle}>
  190. <div className={styles.container}>
  191. <header>
  192. <h3 className={styles.title}>{display.name} {editHint}</h3>
  193. <p className={styles.content}>{display.description}</p>
  194. </header>
  195. <div className={styles.displayActions}>
  196. <Tooltip title="编辑">
  197. <EditIcon className={styles.edit} type="setting" onClick={this.showDisplayFormModal('edit', display)} />
  198. </Tooltip>
  199. <Tooltip title="复制">
  200. <AdminIcon className={styles.copy} type="copy" onClick={this.showDisplayFormModal('copy', display)} />
  201. </Tooltip>
  202. <Popconfirm
  203. title="确定删除?"
  204. placement="bottom"
  205. onConfirm={this.delegate(onDelete, display.id)}
  206. >
  207. <Tooltip title="删除">
  208. <AdminIcon className={styles.delete} type="delete" onClick={this.stopPPG} />
  209. </Tooltip>
  210. </Popconfirm>
  211. </div>
  212. </div>
  213. </div>
  214. </Col>
  215. )
  216. }
  217. public render () {
  218. const { displays, projectId, currentProject, onCheckName } = this.props
  219. if (!Array.isArray(displays)) { return null }
  220. const { editingDisplay, formType, formVisible, modalLoading } = this.state
  221. let addAction
  222. if (currentProject && currentProject.permission) {
  223. const vizPermission = currentProject.permission.vizPermission
  224. addAction = vizPermission === 3
  225. ? [this.renderCreate(), ...displays.map((d) => this.renderDisplay(d))]
  226. : [...displays.map((d) => this.renderDisplay(d))]
  227. }
  228. return (
  229. <div>
  230. <Row
  231. gutter={20}
  232. >
  233. {addAction}
  234. </Row>
  235. <DisplayFormModal
  236. projectId={projectId}
  237. display={editingDisplay}
  238. visible={formVisible}
  239. loading={modalLoading}
  240. exludeRoles={this.state.exludeRoles}
  241. onChangePermission={this.changePermission}
  242. type={formType}
  243. onCheckName={onCheckName}
  244. onSave={this.saveDisplay}
  245. onCancel={this.cancel}
  246. />
  247. </div>
  248. )
  249. }
  250. }
  251. const mapStateToProps = createStructuredSelector({
  252. projectRoles: makeSelectProjectRoles()
  253. })
  254. const withConnect = connect(mapStateToProps, null)
  255. export default compose(
  256. withConnect
  257. )(DisplayList)