DataManagerPortal.tsx 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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. // tslint:disable-next-line:no-empty-interface
  64. interface IVizPortalProps extends RouteComponentWithParams {}
  65. const DataManagerPortal: React.FC<IVizPortalProps> = (props) => {
  66. const dispatch = useDispatch()
  67. const {
  68. portals,
  69. currentPortal,
  70. currentDashboards,
  71. downloadList
  72. } = useSelector(mapStateToProps)
  73. const {
  74. history,
  75. match: { params }
  76. } = props
  77. const portalId = +params.portalId
  78. const projectId = +params.projectId
  79. useEffect(() => {
  80. dispatch(hideNavigator())
  81. if (!portals.length) {
  82. dispatch(VizActions.loadPortals(projectId))
  83. }
  84. }, [])
  85. useEffect(() => {
  86. dispatch(VizActions.loadPortalDashboards(portalId))
  87. }, [portalId])
  88. const goToViz = useCallback(() => {
  89. history.replace(`/project/${projectId}/dataManager/vizs`)
  90. }, [])
  91. const onLoadDownloadList = useCallback(() => dispatch(loadDownloadList()), [])
  92. const onDownloadFile = useCallback((id) => dispatch(downloadFile(id)), [])
  93. const [dashboardTreeNodes, firstDashboardKey] = useDashboardTreeNodes(currentDashboards)
  94. const [dashboardMenuVisible, setDashboardMenuVisible] = useState(false)
  95. const [dashboardMenuStyle, setDashboardMenuStyle] = useState({})
  96. const dashboardConfigMenu = useDashboardConfigMenu(dashboardMenuStyle)
  97. const closeDashboardMenu = useCallback(() => {
  98. setDashboardMenuVisible(false)
  99. }, [])
  100. useEffect(() => {
  101. document.addEventListener('click', closeDashboardMenu, false)
  102. return () => {
  103. document.removeEventListener('click', closeDashboardMenu, false)
  104. }
  105. }, [])
  106. const showDashboardContextMenu = useCallback((options: AntTreeNodeMouseEvent) => {
  107. const { node, event } = options
  108. const { pageX, pageY } = event
  109. const menuStyle: React.CSSProperties = {
  110. position: 'absolute',
  111. left: pageX,
  112. top: pageY
  113. }
  114. setDashboardMenuStyle(menuStyle)
  115. setDashboardMenuVisible(true)
  116. }, [])
  117. return (
  118. <Layout>
  119. <PageHeader
  120. ghost={false}
  121. title={currentPortal.name}
  122. subTitle={currentPortal.description}
  123. onBack={goToViz}
  124. extra={
  125. <DownloadList
  126. downloadList={downloadList}
  127. onLoadDownloadList={onLoadDownloadList}
  128. onDownloadFile={onDownloadFile}
  129. />
  130. }
  131. />
  132. {dashboardMenuVisible && dashboardConfigMenu}
  133. {Array.isArray(currentDashboards) &&
  134. (currentDashboards.length ? (
  135. <SplitPane
  136. spliter
  137. className="ant-layout-content"
  138. type="horizontal"
  139. initialSize={150}
  140. minSize={150}
  141. >
  142. <DirectoryTree
  143. defaultExpandAll
  144. blockNode
  145. defaultSelectedKeys={firstDashboardKey}
  146. onRightClick={showDashboardContextMenu}
  147. >
  148. {dashboardTreeNodes}
  149. </DirectoryTree>
  150. <Route
  151. path="/project/:projectId/dataManager/portal/:portalId/dashboard/:dashboardId"
  152. component={Grid}
  153. />
  154. </SplitPane>
  155. ) : (
  156. <Content
  157. style={{
  158. display: 'flex',
  159. flexDirection: 'column',
  160. alignItems: 'center',
  161. justifyContent: 'center'
  162. }}
  163. >
  164. <Result
  165. icon={<img src={require('assets/images/noDashboard.png')} />}
  166. extra={
  167. <p>
  168. <Button size="small" type="link">
  169. 创建文件夹
  170. </Button>
  171. <Button size="small" type="link">
  172. 创建 Dashboard
  173. </Button>
  174. </p>
  175. }
  176. />
  177. </Content>
  178. ))}
  179. </Layout>
  180. )
  181. }
  182. export default DataManagerPortal