DataVizList.tsx 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. import React from 'react'
  2. import classnames from 'classnames'
  3. import Helmet from 'react-helmet'
  4. import { Link } from 'react-router-dom'
  5. import { compose } from 'redux'
  6. import { connect } from 'react-redux'
  7. import { createStructuredSelector } from 'reselect'
  8. import { checkNameUniqueAction } from '../App/actions'
  9. import { ProjectActions } from '../Projects/actions'
  10. import { VizActions } from '../Viz/actions'
  11. import { makeSelectCurrentProject } from '../Projects/selectors'
  12. import { makeSelectPortals, makeSelectDisplays } from '../Viz/selectors'
  13. import { Icon, Row, Col, Breadcrumb } from 'antd'
  14. import Box from 'components/Box'
  15. import Container, { ContainerTitle, ContainerBody } from 'components/Container'
  16. import PortalList from './components/DataPortalList'
  17. import DisplayList from './components/DataDisplayList'
  18. import { IProject } from '../Projects/types'
  19. import { IPortal, Display, IDisplayFormed } from './types'
  20. import styles from './Viz.less'
  21. import utilStyles from 'assets/less/util.less'
  22. import { RouteComponentWithParams } from 'utils/types'
  23. import OrganizationActions from '../Organizations/actions'
  24. interface IVizProps {
  25. currentProject: IProject
  26. displays: Display[]
  27. portals: IPortal[]
  28. onLoadDisplays: (projectId: number) => void
  29. onAddDisplay: (display: IDisplayFormed, resolve: () => void) => void
  30. onEditDisplay: (display: IDisplayFormed, resolve: () => void) => void
  31. onDeleteDisplay: (displayId: number) => void
  32. onCopyDisplay: (display: IDisplayFormed, resolve: () => void) => void
  33. onLoadPortals: (projectId: number) => void
  34. onAddPortal: (portal: IPortal, resolve) => void
  35. onEditPortal: (portal: IPortal, resolve) => void
  36. onDeletePortal: (portalId: number) => void
  37. onCheckUniqueName: (
  38. pathname: string,
  39. data: any,
  40. resolve: () => any,
  41. reject: (error: string) => any
  42. ) => any
  43. onLoadProjectRoles: (projectId: number) => void
  44. onExcludeRoles: (type: string, id: number, resolve?: any) => any
  45. }
  46. interface IVizStates {
  47. collapse: { dashboard: boolean; display: boolean }
  48. }
  49. export class VizList extends React.Component<IVizProps & RouteComponentWithParams,
  50. IVizStates> {
  51. public state: Readonly<IVizStates> = {
  52. collapse: {
  53. dashboard: true,
  54. display: true
  55. }
  56. }
  57. public componentWillMount() {
  58. const { match, onLoadDisplays, onLoadPortals, onLoadProjectRoles } = this.props
  59. const projectId = +match.params.projectId
  60. onLoadDisplays(projectId)
  61. onLoadPortals(projectId)
  62. onLoadProjectRoles(projectId)
  63. }
  64. private goToPortal = (portalId: number) => () => {
  65. const { history, match } = this.props
  66. // const next = this.props.location.pathname.replace('/vizs', '')
  67. history.push(`/project/${match.params.projectId}/portal/${portalId}`)
  68. // history.push(`${next}/portal/${portalId}`)
  69. }
  70. private goToDisplay = (displayId: number) => () => {
  71. const {
  72. match,
  73. currentProject: {
  74. permission: { vizPermission }
  75. }
  76. } = this.props
  77. const projectId = match.params.projectId
  78. const isToPreview = vizPermission === 1
  79. const path = `/project/${projectId}/display/${displayId}${isToPreview ? '/preview' : ''}`
  80. // const next = this.props.location.pathname.replace('/vizs', '')
  81. // const path = `${next}/display/${displayId}${isToPreview ? '/preview' : ''}`
  82. this.props.history.push(path)
  83. }
  84. private onCollapseChange = (key: string) => () => {
  85. const { collapse } = this.state
  86. this.setState({
  87. collapse: {
  88. ...collapse,
  89. [key]: !collapse[key]
  90. }
  91. })
  92. }
  93. public render() {
  94. const {
  95. displays,
  96. match,
  97. onAddDisplay,
  98. onEditDisplay,
  99. onDeleteDisplay,
  100. onCopyDisplay,
  101. portals,
  102. onAddPortal,
  103. onEditPortal,
  104. onDeletePortal,
  105. currentProject,
  106. onCheckUniqueName
  107. } = this.props
  108. const projectId = +match.params.projectId
  109. const isHideDashboardStyle = classnames({
  110. [styles.listPadding]: true,
  111. [utilStyles.hide]: !this.state.collapse.dashboard
  112. })
  113. const isHideDisplayStyle = classnames({
  114. [styles.listPadding]: true,
  115. [utilStyles.hide]: !this.state.collapse.display
  116. })
  117. return (
  118. <Container>
  119. <Helmet title='数据看板' />
  120. <ContainerBody>
  121. <Box>
  122. <Box.Header>
  123. <Box.Title>
  124. <Row onClick={this.onCollapseChange('dashboard')}>
  125. <Col span={20}>
  126. <Icon
  127. type={`${this.state.collapse.dashboard ? 'down' : 'right'
  128. }`}
  129. />
  130. 仪表板
  131. </Col>
  132. </Row>
  133. </Box.Title>
  134. </Box.Header>
  135. <div className={isHideDashboardStyle}>
  136. <PortalList
  137. currentProject={currentProject}
  138. projectId={projectId}
  139. portals={portals}
  140. onPortalClick={this.goToPortal}
  141. onAdd={onAddPortal}
  142. onEdit={onEditPortal}
  143. onDelete={onDeletePortal}
  144. onCheckUniqueName={onCheckUniqueName}
  145. onExcludeRoles={this.props.onExcludeRoles}
  146. />
  147. </div>
  148. </Box>
  149. <div className={styles.spliter16} />
  150. <Box>
  151. <Box.Header>
  152. <Box.Title>
  153. <Row onClick={this.onCollapseChange('display')}>
  154. <Col span={20}>
  155. <Icon
  156. type={`${this.state.collapse.display ? 'down' : 'right'}`}
  157. />
  158. 大屏
  159. </Col>
  160. </Row>
  161. </Box.Title>
  162. </Box.Header>
  163. <div className={isHideDisplayStyle}>
  164. <DisplayList
  165. currentProject={currentProject}
  166. projectId={projectId}
  167. displays={displays}
  168. onDisplayClick={this.goToDisplay}
  169. onAdd={onAddDisplay}
  170. onEdit={onEditDisplay}
  171. onCopy={onCopyDisplay}
  172. onDelete={onDeleteDisplay}
  173. onCheckName={onCheckUniqueName}
  174. onExcludeRoles={this.props.onExcludeRoles}
  175. />
  176. </div>
  177. </Box>
  178. </ContainerBody>
  179. </Container>
  180. )
  181. }
  182. }
  183. const mapStateToProps = createStructuredSelector({
  184. displays: makeSelectDisplays(),
  185. portals: makeSelectPortals(),
  186. currentProject: makeSelectCurrentProject()
  187. })
  188. export function mapDispatchToProps(dispatch) {
  189. return {
  190. onLoadDisplays: (projectId) => dispatch(VizActions.loadDisplays(projectId)),
  191. onAddDisplay: (display: IDisplayFormed, resolve) =>
  192. dispatch(VizActions.addDisplay(display, resolve)),
  193. onEditDisplay: (display: IDisplayFormed, resolve) =>
  194. dispatch(VizActions.editDisplay(display, resolve)),
  195. onDeleteDisplay: (id) => dispatch(VizActions.deleteDisplay(id)),
  196. onCopyDisplay: (display: IDisplayFormed, resolve) =>
  197. dispatch(VizActions.copyDisplay(display, resolve)),
  198. onLoadPortals: (projectId) => dispatch(VizActions.loadPortals(projectId)),
  199. onAddPortal: (portal, resolve) =>
  200. dispatch(VizActions.addPortal(portal, resolve)),
  201. onEditPortal: (portal, resolve) =>
  202. dispatch(VizActions.editPortal(portal, resolve)),
  203. onDeletePortal: (id) => dispatch(VizActions.deletePortal(id)),
  204. onCheckUniqueName: (pathname, data, resolve, reject) =>
  205. dispatch(checkNameUniqueAction(pathname, data, resolve, reject)),
  206. onLoadProjectRoles: (projectId) =>
  207. dispatch(OrganizationActions.loadProjectRoles(projectId)),
  208. onExcludeRoles: (type, id, resolve) =>
  209. dispatch(ProjectActions.excludeRoles(type, id, resolve))
  210. }
  211. }
  212. const withConnect = connect(
  213. mapStateToProps,
  214. mapDispatchToProps
  215. )
  216. export default compose(withConnect)(VizList)