Tracim.jsx 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. import React from 'react'
  2. import { connect } from 'react-redux'
  3. import { translate } from 'react-i18next'
  4. import Sidebar from './Sidebar.jsx'
  5. import Header from './Header.jsx'
  6. import Login from './Login.jsx'
  7. import Account from './Account.jsx'
  8. import AppFullscreenRouter from './AppFullscreenRouter.jsx'
  9. import FlashMessage from '../component/FlashMessage.jsx'
  10. import WorkspaceContent from './WorkspaceContent.jsx'
  11. import WIPcomponent from './WIPcomponent.jsx'
  12. import {
  13. Route, withRouter, Redirect
  14. } from 'react-router-dom'
  15. import { COOKIE, PAGE } from '../helper.js'
  16. import {
  17. getAppList,
  18. getContentTypeList,
  19. getUserIsConnected, getWorkspaceList
  20. } from '../action-creator.async.js'
  21. import {
  22. newFlashMessage,
  23. removeFlashMessage,
  24. setAppList,
  25. setContentTypeList,
  26. setUserConnected,
  27. setWorkspaceListIsOpenInSidebar,
  28. setWorkspaceList
  29. } from '../action-creator.sync.js'
  30. import Cookies from 'js-cookie'
  31. import Dashboard from './Dashboard.jsx'
  32. class Tracim extends React.Component {
  33. constructor (props) {
  34. super(props)
  35. document.addEventListener('appCustomEvent', this.customEventReducer)
  36. }
  37. customEventReducer = async ({ detail: { type, data } }) => {
  38. switch (type) {
  39. case 'redirect':
  40. console.log('%c<Tracim> Custom event', 'color: #28a745', type, data)
  41. this.props.history.push(data.url)
  42. break
  43. case 'addFlashMsg':
  44. console.log('%c<Tracim> Custom event', 'color: #28a745', type, data)
  45. this.props.dispatch(newFlashMessage(data.msg, data.type, data.delay))
  46. break
  47. case 'refreshWorkspaceList':
  48. console.log('%c<Tracim> Custom event', 'color: #28a745', type, data)
  49. this.loadWorkspaceList()
  50. break
  51. }
  52. }
  53. async componentDidMount () {
  54. // console.log('<Tracim> did Mount')
  55. const { dispatch } = this.props
  56. const userFromCookies = {
  57. email: Cookies.get(COOKIE.USER_LOGIN),
  58. auth: Cookies.get(COOKIE.USER_AUTH)
  59. }
  60. const fetchGetUserIsConnected = await dispatch(getUserIsConnected(userFromCookies))
  61. switch (fetchGetUserIsConnected.status) {
  62. case 200:
  63. dispatch(setUserConnected({
  64. ...fetchGetUserIsConnected.json,
  65. auth: userFromCookies.auth,
  66. logged: true
  67. }))
  68. this.loadAppConfig()
  69. this.loadWorkspaceList()
  70. break
  71. case 401:
  72. Cookies.remove(COOKIE.USER_LOGIN)
  73. Cookies.remove(COOKIE.USER_AUTH)
  74. dispatch(setUserConnected({logged: false})); break
  75. default:
  76. dispatch(setUserConnected({logged: null})); break
  77. }
  78. }
  79. loadAppConfig = async () => {
  80. const { props } = this
  81. const fetchGetAppList = await props.dispatch(getAppList(props.user))
  82. if (fetchGetAppList.status === 200) props.dispatch(setAppList(fetchGetAppList.json))
  83. const fetchGetContentTypeList = await props.dispatch(getContentTypeList(props.user))
  84. if (fetchGetContentTypeList.status === 200) props.dispatch(setContentTypeList(fetchGetContentTypeList.json))
  85. }
  86. loadWorkspaceList = async () => {
  87. const { props } = this
  88. const fetchGetWorkspaceList = await props.dispatch(getWorkspaceList(props.user))
  89. if (fetchGetWorkspaceList.status === 200) {
  90. this.setState({workspaceListLoaded: true})
  91. props.dispatch(setWorkspaceList(fetchGetWorkspaceList.json))
  92. const idWorkspaceToOpen = (() =>
  93. props.match && props.match.params.idws !== undefined && !isNaN(props.match.params.idws)
  94. ? parseInt(props.match.params.idws)
  95. : fetchGetWorkspaceList.json[0].workspace_id
  96. )()
  97. props.dispatch(setWorkspaceListIsOpenInSidebar(idWorkspaceToOpen, true))
  98. }
  99. }
  100. handleRemoveFlashMessage = msg => this.props.dispatch(removeFlashMessage(msg))
  101. render () {
  102. const { props } = this
  103. if (props.user.logged === null) return null // @TODO show loader
  104. if (props.user.logged === false && props.location.pathname !== '/login') {
  105. return <Redirect to={{pathname: '/login', state: {from: props.location}}} />
  106. }
  107. if (props.location.pathname !== '/login' && (
  108. !props.system.workspaceListLoaded ||
  109. !props.system.appListLoaded ||
  110. !props.system.contentTypeListLoaded
  111. )) return null // @TODO Côme - 2018/08/22 - should show loader here
  112. return (
  113. <div className='tracim'>
  114. <Header />
  115. <FlashMessage flashMessage={props.flashMessage} removeFlashMessage={this.handleRemoveFlashMessage} t={props.t} />
  116. <div className='sidebarpagecontainer'>
  117. <Sidebar />
  118. <div className='tracim__content'>
  119. <Route path={PAGE.LOGIN} component={Login} />
  120. <Route exact path='/' component={() => {
  121. switch (props.user.logged) {
  122. case true:
  123. return <Redirect to={{pathname: PAGE.WORKSPACE.ROOT, state: {from: props.location}}} />
  124. case false:
  125. return <Redirect to={{pathname: '/login', state: {from: props.location}}} />
  126. case null:
  127. return null
  128. }
  129. }} />
  130. <Route path='/workspaces/:idws?' render={() => // Workspace Router
  131. <div>
  132. <Route exact path={PAGE.WORKSPACE.ROOT} render={() => props.workspaceList.length === 0 // handle '/' and redirect to first workspace
  133. ? null // @FIXME this needs to be handled in case of new user that has no workspace
  134. : <Redirect to={{pathname: PAGE.WORKSPACE.DASHBOARD(props.workspaceList[0].id), state: {from: props.location}}} />
  135. } />
  136. <Route exact path={`${PAGE.WORKSPACE.ROOT}/:idws`} render={props2 => // handle '/workspaces/:id' and add '/contents'
  137. <Redirect to={{pathname: PAGE.WORKSPACE.CONTENT_LIST(props2.match.params.idws), state: {from: props.location}}} />
  138. } />
  139. <Route path={PAGE.WORKSPACE.DASHBOARD(':idws')} component={Dashboard} />
  140. <Route path={PAGE.WORKSPACE.CALENDAR(':idws')} component={() => <div><br /><br /><br /><br />NYI</div>} />
  141. <Route path={PAGE.WORKSPACE.CONTENT(':idws', ':type', ':idcts')} component={WorkspaceContent} />
  142. <Route exact path={PAGE.WORKSPACE.CONTENT_LIST(':idws')} component={WorkspaceContent} />
  143. </div>
  144. } />
  145. <Route path={PAGE.ACCOUNT} render={() =>
  146. <Account />
  147. } />
  148. <Route path={PAGE.ADMIN.ROOT} render={() =>
  149. <AppFullscreenRouter />
  150. } />
  151. <Route path={'/wip/:cp'} component={WIPcomponent} /> {/* for testing purpose only */}
  152. <div id='appFeatureContainer' />
  153. <div id='popupCreateContentContainer' />
  154. </div>
  155. </div>
  156. </div>
  157. )
  158. }
  159. }
  160. const mapStateToProps = ({ user, appList, contentType, workspaceList, flashMessage, system }) => ({ user, appList, contentType, workspaceList, flashMessage, system })
  161. export default withRouter(connect(mapStateToProps)(translate()(Tracim)))