Portal.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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, { useEffect, useCallback, useState } from 'react'
  21. import { createStructuredSelector } from 'reselect'
  22. import { useDispatch, useSelector } from 'react-redux'
  23. import {
  24. makeSelectDownloadList
  25. } from 'containers/App/selectors'
  26. import {
  27. makeSelectPortals,
  28. makeSelectCurrentPortal,
  29. makeSelectCurrentDashboards
  30. } from './selectors'
  31. import {
  32. hideNavigator,
  33. loadDownloadList,
  34. downloadFile
  35. } from 'containers/App/actions'
  36. import { VizActions } from './actions'
  37. import { Route } from 'react-router-dom'
  38. import { RouteComponentWithParams } from 'utils/types'
  39. import {
  40. Layout,
  41. Result,
  42. PageHeader,
  43. Tree,
  44. Icon,
  45. Button,
  46. Menu,
  47. Dropdown
  48. } from 'antd'
  49. const { Header, Sider, Content } = Layout
  50. const { DirectoryTree } = Tree
  51. import SplitPane from 'components/SplitPane'
  52. import DownloadList from 'components/DownloadList'
  53. import useDashboardConfigMenu from './hooks/dashboardConfigMenu'
  54. import { Grid } from 'containers/Dashboard/Loadable'
  55. import useDashboardTreeNodes from './hooks/dashboardTreeNodes'
  56. import { AntTreeNodeMouseEvent } from 'antd/lib/tree'
  57. const mapStateToProps = createStructuredSelector({
  58. downloadList: makeSelectDownloadList(),
  59. portals: makeSelectPortals(),
  60. currentPortal: makeSelectCurrentPortal(),
  61. currentDashboards: makeSelectCurrentDashboards()
  62. })
  63. interface IVizPortalProps extends RouteComponentWithParams {}
  64. const VizPortal: React.FC<IVizPortalProps> = (props) => {
  65. const dispatch = useDispatch()
  66. const {
  67. portals,
  68. currentPortal,
  69. currentDashboards,
  70. downloadList
  71. } = useSelector(mapStateToProps)
  72. const {
  73. history,
  74. match: { params }
  75. } = props
  76. const portalId = +params.portalId
  77. const projectId = +params.projectId
  78. useEffect(() => {
  79. dispatch(hideNavigator())
  80. if (!portals.length) {
  81. dispatch(VizActions.loadPortals(projectId))
  82. }
  83. }, [])
  84. useEffect(() => {
  85. dispatch(VizActions.loadPortalDashboards(portalId))
  86. }, [portalId])
  87. const goToViz = useCallback(() => {
  88. history.replace(`/project/${projectId}/vizs`)
  89. }, [])
  90. const onLoadDownloadList = useCallback(() => dispatch(loadDownloadList()), [])
  91. const onDownloadFile = useCallback((id) => dispatch(downloadFile(id)), [])
  92. const [dashboardTreeNodes, firstDashboardKey] = useDashboardTreeNodes(currentDashboards)
  93. const [dashboardMenuVisible, setDashboardMenuVisible] = useState(false)
  94. const [dashboardMenuStyle, setDashboardMenuStyle] = useState({})
  95. const dashboardConfigMenu = useDashboardConfigMenu(dashboardMenuStyle)
  96. const closeDashboardMenu = useCallback(() => {
  97. setDashboardMenuVisible(false)
  98. }, [])
  99. useEffect(() => {
  100. document.addEventListener('click', closeDashboardMenu, false)
  101. return () => {
  102. document.removeEventListener('click', closeDashboardMenu, false)
  103. }
  104. }, [])
  105. const showDashboardContextMenu = useCallback((options: AntTreeNodeMouseEvent) => {
  106. const { node, event } = options
  107. const { pageX, pageY } = event
  108. const menuStyle: React.CSSProperties = {
  109. position: 'absolute',
  110. left: pageX,
  111. top: pageY
  112. }
  113. setDashboardMenuStyle(menuStyle)
  114. setDashboardMenuVisible(true)
  115. }, [])
  116. return (
  117. <Layout>
  118. <PageHeader
  119. ghost={false}
  120. title={currentPortal.name}
  121. subTitle={currentPortal.description}
  122. onBack={goToViz}
  123. extra={
  124. <DownloadList
  125. downloadList={downloadList}
  126. onLoadDownloadList={onLoadDownloadList}
  127. onDownloadFile={onDownloadFile}
  128. />
  129. }
  130. />
  131. {dashboardMenuVisible && dashboardConfigMenu}
  132. {Array.isArray(currentDashboards) &&
  133. (currentDashboards.length ? (
  134. <SplitPane
  135. spliter
  136. className="ant-layout-content"
  137. type="horizontal"
  138. initialSize={150}
  139. minSize={150}
  140. >
  141. <DirectoryTree
  142. defaultExpandAll
  143. blockNode
  144. defaultSelectedKeys={firstDashboardKey}
  145. onRightClick={showDashboardContextMenu}
  146. >
  147. {dashboardTreeNodes}
  148. </DirectoryTree>
  149. <Route
  150. path="/project/:projectId/portal/:portalId/dashboard/:dashboardId"
  151. component={Grid}
  152. />
  153. </SplitPane>
  154. ) : (
  155. <Content
  156. style={{
  157. display: 'flex',
  158. flexDirection: 'column',
  159. alignItems: 'center',
  160. justifyContent: 'center'
  161. }}
  162. >
  163. <Result
  164. icon={<img src={require('assets/images/noDashboard.png')} />}
  165. extra={
  166. <p>
  167. <Button size="small" type="link">
  168. 创建文件夹
  169. </Button>
  170. <Button size="small" type="link">
  171. 创建 Dashboard
  172. </Button>
  173. </p>
  174. }
  175. />
  176. </Content>
  177. ))}
  178. </Layout>
  179. )
  180. }
  181. export default VizPortal