WorkspaceContent.jsx 7.1KB

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