DataDisplayList.tsx 8.2 KB

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