WorkspaceContent.jsx 9.7KB

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