WorkspaceContent.jsx 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. import React from 'react'
  2. import { connect } from 'react-redux'
  3. import appFactory from '../appFactory.js'
  4. import { PAGE } from '../helper.js'
  5. import Sidebar from './Sidebar.jsx'
  6. import Folder from '../component/Workspace/Folder.jsx'
  7. import ContentItem from '../component/Workspace/ContentItem.jsx'
  8. import ContentItemHeader from '../component/Workspace/ContentItemHeader.jsx'
  9. import PageWrapper from '../component/common/layout/PageWrapper.jsx'
  10. import PageTitle from '../component/common/layout/PageTitle.jsx'
  11. import PageContent from '../component/common/layout/PageContent.jsx'
  12. import DropdownCreateButton from '../component/common/Input/DropdownCreateButton.jsx'
  13. import {
  14. getAppList,
  15. getWorkspaceContent,
  16. getFolderContent,
  17. getWorkspaceList
  18. } from '../action-creator.async.js'
  19. import {
  20. newFlashMessage, setAppList,
  21. setWorkspaceData,
  22. setWorkspaceListIsOpenInSidebar,
  23. updateWorkspaceListData
  24. } from '../action-creator.sync.js'
  25. const qs = require('query-string')
  26. class WorkspaceContent extends React.Component {
  27. constructor (props) {
  28. super(props)
  29. this.state = {
  30. popupCreateContent: {
  31. display: false,
  32. type: undefined,
  33. folder: undefined
  34. },
  35. workspaceIdInUrl: props.match.params.idws ? parseInt(props.match.params.idws) : null
  36. }
  37. document.addEventListener('appCustomEvent', this.customEventReducer)
  38. }
  39. customEventReducer = ({ detail: { type, data } }) => {
  40. switch (type) {
  41. case 'openContentUrl':
  42. this.props.history.push(PAGE.WORKSPACE.CONTENT(data.idWorkspace, data.idContent))
  43. break
  44. case 'appClosed':
  45. this.props.history.push(PAGE.WORKSPACE.CONTENT(this.props.workspace.id, ''))
  46. break
  47. }
  48. }
  49. async componentDidMount () {
  50. const { workspaceIdInUrl } = this.state
  51. const { user, workspaceList, app, match, location, dispatch } = this.props
  52. if (Object.keys(app).length === 0) {
  53. const fetchGetAppList = await dispatch(getAppList())
  54. if (fetchGetAppList.status === 200) dispatch(setAppList(fetchGetAppList.json))
  55. }
  56. let wsToLoad = null
  57. if (match.params.idws !== undefined) wsToLoad = match.params.idws
  58. if (user.user_id !== -1 && workspaceList.length === 0) {
  59. const fetchGetWorkspaceList = await dispatch(getWorkspaceList(user.user_id))
  60. if (fetchGetWorkspaceList.status === 200) {
  61. dispatch(updateWorkspaceListData(fetchGetWorkspaceList.json))
  62. dispatch(setWorkspaceListIsOpenInSidebar(workspaceIdInUrl || fetchGetWorkspaceList.json[0].id, true))
  63. if (match.params.idws === undefined && fetchGetWorkspaceList.json.length > 0) {
  64. wsToLoad = fetchGetWorkspaceList.json[0].id // load first ws if none specified
  65. }
  66. }
  67. }
  68. if (wsToLoad === null) return // ws already loaded
  69. const wsContent = await dispatch(getWorkspaceContent(wsToLoad))
  70. if (wsContent.status === 200) dispatch(setWorkspaceData(wsContent.json, qs.parse(location.search).type))
  71. else dispatch(newFlashMessage('Error while loading workspace', 'danger'))
  72. }
  73. componentDidUpdate (prevProps, prevState) {
  74. const { app, workspace, user, renderApp, match, dispatch } = this.props
  75. if (this.state.workspaceIdInUrl === null) return
  76. const newWorkspaceId = parseInt(match.params.idws)
  77. if (prevState.workspaceIdInUrl !== newWorkspaceId) this.setState({workspaceIdInUrl: newWorkspaceId})
  78. if (user.id !== -1 && prevProps.user.id !== user.id) dispatch(getWorkspaceList(user.user_id, newWorkspaceId))
  79. if (match.params.idcts) { // if a content id is in url, open it
  80. const contentToOpen = workspace.content.find(wsc => wsc.id === parseInt(match.params.idcts))
  81. if (contentToOpen === undefined) return
  82. renderApp(
  83. app[contentToOpen.type],
  84. user,
  85. {...contentToOpen, workspace: workspace}
  86. )
  87. }
  88. }
  89. handleClickContentItem = content => this.props.history.push(`${PAGE.WORKSPACE.CONTENT(content.workspace_id, content.id)}${this.props.location.search}`)
  90. handleClickEditContentItem = (e, content) => {
  91. e.stopPropagation()
  92. console.log('edit nyi', content)
  93. }
  94. handleClickMoveContentItem = (e, content) => {
  95. e.stopPropagation()
  96. console.log('move nyi', content)
  97. }
  98. handleClickDownloadContentItem = (e, content) => {
  99. e.stopPropagation()
  100. console.log('download nyi', content)
  101. }
  102. handleClickArchiveContentItem = (e, content) => {
  103. e.stopPropagation()
  104. console.log('archive nyi', content)
  105. }
  106. handleClickDeleteContentItem = (e, content) => {
  107. e.stopPropagation()
  108. console.log('delete nyi', content)
  109. }
  110. handleClickFolder = folderId => {
  111. this.props.dispatch(getFolderContent(this.props.workspace.id, folderId))
  112. }
  113. handleClickCreateContent = (folder, contentType) => {
  114. this.props.renderCreateContentApp(this.props.app[contentType], this.props.user, folder)
  115. }
  116. render () {
  117. const { workspace, app } = this.props
  118. const filterWorkspaceContent = (contentList, filter) => filter.length === 0
  119. ? contentList
  120. : contentList.filter(c => c.type === 'folder' || filter.includes(c.type)) // keep unfiltered files and folders
  121. .map(c => c.type !== 'folder' ? c : {...c, content: filterWorkspaceContent(c.content, filter)}) // recursively filter folder content
  122. // .filter(c => c.type !== 'folder' || c.content.length > 0) // remove empty folder => 2018/05/21 - since we load only one lvl of content, don't remove empty folders
  123. const filteredWorkspaceContent = filterWorkspaceContent(workspace.content, workspace.filter)
  124. return (
  125. <div className='sidebarpagecontainer'>
  126. <Sidebar />
  127. <PageWrapper customeClass='workspace'>
  128. <PageTitle
  129. parentClass='workspace__header'
  130. customClass='justify-content-between'
  131. title={workspace.title}
  132. >
  133. <DropdownCreateButton parentClass='workspace__header__btnaddworkspace' />
  134. </PageTitle>
  135. <PageContent parentClass='workspace__content'>
  136. <div id='popupCreateContentContainer' />
  137. <div className='workspace__content__fileandfolder folder__content active'>
  138. <ContentItemHeader />
  139. { filteredWorkspaceContent.map((c, i) => c.type === 'folder'
  140. ? (
  141. <Folder
  142. app={app}
  143. folderData={c}
  144. onClickItem={this.handleClickContentItem}
  145. onClickExtendedAction={{
  146. edit: this.handleClickEditContentItem,
  147. move: this.handleClickMoveContentItem,
  148. download: this.handleClickDownloadContentItem,
  149. archive: this.handleClickArchiveContentItem,
  150. delete: this.handleClickDeleteContentItem
  151. }}
  152. onClickFolder={this.handleClickFolder}
  153. onClickCreateContent={this.handleClickCreateContent}
  154. isLast={i === filteredWorkspaceContent.length - 1}
  155. key={c.id}
  156. />
  157. )
  158. : (
  159. <ContentItem
  160. name={c.title}
  161. type={c.type}
  162. icon={(app[c.type] || {icon: ''}).icon}
  163. status={c.status}
  164. onClickItem={() => this.handleClickContentItem(c)}
  165. onClickExtendedAction={{
  166. edit: e => this.handleClickEditContentItem(e, c),
  167. move: e => this.handleClickMoveContentItem(e, c),
  168. download: e => this.handleClickDownloadContentItem(e, c),
  169. archive: e => this.handleClickArchiveContentItem(e, c),
  170. delete: e => this.handleClickDeleteContentItem(e, c)
  171. }}
  172. isLast={i === filteredWorkspaceContent.length - 1}
  173. key={c.id}
  174. />
  175. )
  176. )}
  177. </div>
  178. <DropdownCreateButton customClass='workspace__content__button mb-5' />
  179. <div id='appContainer' />
  180. </PageContent>
  181. </PageWrapper>
  182. </div>
  183. )
  184. }
  185. }
  186. const mapStateToProps = ({ user, workspace, workspaceList, app }) => ({ user, workspace, workspaceList, app })
  187. export default connect(mapStateToProps)(appFactory(WorkspaceContent))