WorkspaceContent.jsx 8.2KB

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