Browse Source

[https://github.com/tracim/tracim/issues/759] added 'contents' to routes + refactor <Route> for React Router

Skylsmoi 5 years ago
parent
commit
024da22495

+ 2 - 5
frontend/src/component/Workspace/OpenContentApp.jsx View File

@@ -22,13 +22,10 @@ export class OpenContentApp extends React.Component {
22 22
       console.log('%c<OpenContentApp> contentToOpen', 'color: #dcae84', contentToOpen)
23 23
 
24 24
       if (appOpenedType === contentToOpen.type) { // app already open
25
-        dispatchCustomEvent({
26
-          type: `${contentToOpen.type}_reloadContent`, // handled by html-document:src/container/AdminWorkspaceUser.jsx
27
-          data: contentToOpen
28
-        })
25
+        dispatchCustomEvent(`${contentToOpen.type}_reloadContent`, contentToOpen)
29 26
       } else { // open another app
30 27
         // if another app is already visible, hide it
31
-        if (appOpenedType !== false) dispatchCustomEvent({type: `${appOpenedType}_hideApp`})
28
+        if (appOpenedType !== false) dispatchCustomEvent(`${appOpenedType}_hideApp`, {})
32 29
         // open app
33 30
         renderAppFeature(
34 31
           contentType.find(ct => ct.slug === contentToOpen.type),

+ 1 - 4
frontend/src/container/Account.jsx View File

@@ -1,6 +1,5 @@
1 1
 import React from 'react'
2 2
 import { connect } from 'react-redux'
3
-import Sidebar from './Sidebar.jsx'
4 3
 import UserInfo from '../component/Account/UserInfo.jsx'
5 4
 import MenuSubComponent from '../component/Account/MenuSubComponent.jsx'
6 5
 import PersonalData from '../component/Account/PersonalData.jsx'
@@ -102,9 +101,7 @@ class Account extends React.Component {
102 101
     })()
103 102
 
104 103
     return (
105
-      <div className='sidebarpagecontainer'>
106
-        <Sidebar />
107
-
104
+      <div className='Account'>
108 105
         <PageWrapper customClass='account'>
109 106
           <PageTitle
110 107
             parentClass={'account'}

+ 1 - 4
frontend/src/container/AppFullscreenManager.jsx View File

@@ -4,7 +4,6 @@ import { withRouter } from 'react-router'
4 4
 import { Route } from 'react-router-dom'
5 5
 import { PAGE } from '../helper.js'
6 6
 import appFactory from '../appFactory.js'
7
-import Sidebar from './Sidebar.jsx'
8 7
 
9 8
 class AppFullscreenManager extends React.Component {
10 9
   constructor (props) {
@@ -20,9 +19,7 @@ class AppFullscreenManager extends React.Component {
20 19
     const { props } = this
21 20
 
22 21
     return (
23
-      <div className='sidebarpagecontainer'>
24
-        <Sidebar />
25
-
22
+      <div className='AppFullScreenManager'>
26 23
         <div id='appFullscreenContainer' />
27 24
 
28 25
         {this.state.AmIMounted && (// we must wait for the component to be fully mounted to be sure the div#appFullscreenContainer exists in DOM

+ 1 - 4
frontend/src/container/Dashboard.jsx View File

@@ -1,6 +1,5 @@
1 1
 import React from 'react'
2 2
 import { connect } from 'react-redux'
3
-import Sidebar from './Sidebar.jsx'
4 3
 import { translate } from 'react-i18next'
5 4
 import {
6 5
   PageWrapper,
@@ -93,9 +92,7 @@ class Dashboard extends React.Component {
93 92
     const { props, state } = this
94 93
 
95 94
     return (
96
-      <div className='sidebarpagecontainer'>
97
-        <Sidebar />
98
-
95
+      <div className='Dashboard' style={{width: '100%'}}>
99 96
         <PageWrapper customeClass='dashboard'>
100 97
           <PageTitle
101 98
             parentClass='dashboard__header'

+ 2 - 2
frontend/src/container/Login.jsx View File

@@ -55,8 +55,8 @@ class Login extends React.Component {
55 55
       Cookies.set(COOKIE.USER_LOGIN, inputLogin.value)
56 56
       Cookies.set(COOKIE.USER_AUTH, userAuth)
57 57
 
58
-      history.push(PAGE.HOME)
59
-    } else if (fetchPostUserLogin.status === 400) {
58
+      history.push(PAGE.WORKSPACE.ROOT)
59
+    } else if (fetchPostUserLogin.status === 403) {
60 60
       dispatch(newFlashMessage(t('Email or password invalid'), 'danger'))
61 61
     }
62 62
   }

+ 6 - 3
frontend/src/container/Sidebar.jsx View File

@@ -25,7 +25,7 @@ class Sidebar extends React.Component {
25 25
     super(props)
26 26
     this.state = {
27 27
       sidebarClose: false,
28
-      workspaceIdInUrl: props.match.params.idws ? parseInt(props.match.params.idws) : null
28
+      workspaceIdInUrl: props.match && props.match.params.idws ? parseInt(props.match.params.idws) : null
29 29
     }
30 30
 
31 31
     document.addEventListener('appCustomEvent', this.customEventReducer)
@@ -41,14 +41,17 @@ class Sidebar extends React.Component {
41 41
   }
42 42
 
43 43
   componentDidMount () {
44
+    // console.log('Sidebar Did Mount', this.props)
44 45
     this.loadAppConfigAndWorkspaceList()
45 46
   }
46 47
 
47 48
   componentDidUpdate (prevProps, prevState) {
49
+    const { props } = this
50
+
48 51
     // console.log('%c<Sidebar> Did Update', 'color: #c17838')
49
-    if (this.props.match.params.idws === undefined || isNaN(this.props.match.params.idws)) return
52
+    if (!props.match || props.match.params.idws === undefined || isNaN(props.match.params.idws)) return
50 53
 
51
-    const newWorkspaceId = parseInt(this.props.match.params.idws)
54
+    const newWorkspaceId = parseInt(props.match.params.idws)
52 55
     if (prevState.workspaceIdInUrl !== newWorkspaceId) this.setState({workspaceIdInUrl: newWorkspaceId})
53 56
   }
54 57
 

+ 48 - 17
frontend/src/container/Tracim.jsx View File

@@ -1,18 +1,17 @@
1 1
 import React from 'react'
2 2
 import { connect } from 'react-redux'
3 3
 import { translate } from 'react-i18next'
4
+import Sidebar from './Sidebar.jsx'
4 5
 import Header from './Header.jsx'
5 6
 import Login from './Login.jsx'
6
-import Dashboard from './Dashboard.jsx'
7 7
 import Account from './Account.jsx'
8 8
 import AppFullscreenManager from './AppFullscreenManager.jsx'
9 9
 import FlashMessage from '../component/FlashMessage.jsx'
10 10
 import WorkspaceContent from './WorkspaceContent.jsx'
11 11
 import WIPcomponent from './WIPcomponent.jsx'
12 12
 import {
13
-  Route, withRouter, Switch
13
+  Route, withRouter, Redirect
14 14
 } from 'react-router-dom'
15
-import PrivateRoute from './PrivateRoute.jsx'
16 15
 import { COOKIE, PAGE } from '../helper.js'
17 16
 import {
18 17
   getUserIsConnected
@@ -22,6 +21,7 @@ import {
22 21
   setUserConnected
23 22
 } from '../action-creator.sync.js'
24 23
 import Cookies from 'js-cookie'
24
+import Dashboard from './Dashboard.jsx'
25 25
 
26 26
 class Tracim extends React.Component {
27 27
   constructor (props) {
@@ -40,6 +40,7 @@ class Tracim extends React.Component {
40 40
   }
41 41
 
42 42
   async componentDidMount () {
43
+    // console.log('<Tracim> did Mount')
43 44
     const { dispatch } = this.props
44 45
 
45 46
     const userFromCookies = {
@@ -66,27 +67,57 @@ class Tracim extends React.Component {
66 67
   handleRemoveFlashMessage = msg => this.props.dispatch(removeFlashMessage(msg))
67 68
 
68 69
   render () {
69
-    const { flashMessage, t } = this.props
70
+    const { props } = this
70 71
 
71 72
     return (
72 73
       <div className='tracim'>
73 74
         <Header />
74
-        <FlashMessage flashMessage={flashMessage} removeFlashMessage={this.handleRemoveFlashMessage} t={t} />
75
+        <FlashMessage flashMessage={props.flashMessage} removeFlashMessage={this.handleRemoveFlashMessage} t={props.t} />
75 76
 
76 77
         <div className='tracim__content'>
77 78
           <Route path={PAGE.LOGIN} component={Login} />
78 79
 
79
-          <PrivateRoute exact path='/' component={WorkspaceContent} />
80
-
81
-          <Switch>
82
-            <PrivateRoute path={PAGE.WORKSPACE.DASHBOARD(':idws')} component={Dashboard} />
83
-            <PrivateRoute path={PAGE.WORKSPACE.CALENDAR(':idws')} component={() => <div><br /><br /><br /><br />NYI</div>} />
84
-            <PrivateRoute path={PAGE.WORKSPACE.CONTENT(':idws', ':type?', ':idcts?')} component={WorkspaceContent} />
85
-          </Switch>
86
-
87
-          <PrivateRoute path={PAGE.ACCOUNT} component={Account} />
88
-          <PrivateRoute path={PAGE.ADMIN.ROOT} component={AppFullscreenManager} />
89
-          <PrivateRoute path={'/wip/:cp'} component={WIPcomponent} /> {/* for testing purpose only */}
80
+          <Route exact path='/' component={() => {
81
+            switch (props.user.logged) {
82
+              case true:
83
+                return <Redirect to={{pathname: PAGE.WORKSPACE.ROOT, state: {from: props.location}}} />
84
+              case false:
85
+                return <Redirect to={{pathname: '/login', state: {from: props.location}}} />
86
+              case null:
87
+                return null
88
+            }
89
+          }} />
90
+
91
+          { props.user.logged
92
+            ? (
93
+              <Route path='/workspaces/:idws?' render={() => // Workspace Router
94
+                <div className='sidebarpagecontainer'>
95
+                  <Sidebar />
96
+
97
+                  <Route exact path={PAGE.WORKSPACE.ROOT} render={() => props.workspaceList.length === 0 // handle '/' and redirect to first workspace
98
+                    ? null
99
+                    : <Redirect to={{pathname: `/workspaces/${props.workspaceList[0].id}/contents`, state: {from: props.location}}} />
100
+                  } />
101
+
102
+                  <Route exact path={`${PAGE.WORKSPACE.ROOT}/:idws`} render={props2 => // handle '/workspaces/:id' and add '/contents'
103
+                    <Redirect to={{pathname: `/workspaces/${props2.match.params.idws}/contents`, state: {from: props.location}}} />
104
+                  } />
105
+
106
+                  <Route path={PAGE.WORKSPACE.DASHBOARD(':idws')} component={Dashboard} />
107
+                  <Route path={PAGE.WORKSPACE.CALENDAR(':idws')} component={() => <div><br /><br /><br /><br />NYI</div>} />
108
+                  <Route path={PAGE.WORKSPACE.CONTENT(':idws', ':type', ':idcts')} component={WorkspaceContent} />
109
+                  <Route exact path={PAGE.WORKSPACE.CONTENT_LIST(':idws')} component={WorkspaceContent} />
110
+
111
+                  <Route path={PAGE.ACCOUNT} component={Account} />
112
+                  <Route path={PAGE.ADMIN.ROOT} component={AppFullscreenManager} />
113
+                </div>
114
+              } />
115
+            )
116
+            : props.user.logged === false && props.location.pathname !== '/login' &&
117
+              <Redirect to={{pathname: '/login', state: {from: props.location}}} />
118
+          }
119
+
120
+          <Route path={'/wip/:cp'} component={WIPcomponent} /> {/* for testing purpose only */}
90 121
 
91 122
           <div id='appFeatureContainer' />
92 123
         </div>
@@ -96,5 +127,5 @@ class Tracim extends React.Component {
96 127
   }
97 128
 }
98 129
 
99
-const mapStateToProps = ({ user, appList, contentType, flashMessage }) => ({ user, appList, contentType, flashMessage })
130
+const mapStateToProps = ({ user, appList, contentType, workspaceList, flashMessage }) => ({ user, appList, contentType, workspaceList, flashMessage })
100 131
 export default withRouter(connect(mapStateToProps)(translate()(Tracim)))

+ 3 - 5
frontend/src/container/WorkspaceContent.jsx View File

@@ -3,7 +3,6 @@ import { connect } from 'react-redux'
3 3
 import { withRouter, Route } from 'react-router-dom'
4 4
 import appFactory from '../appFactory.js'
5 5
 import { PAGE } from '../helper.js'
6
-import Sidebar from './Sidebar.jsx'
7 6
 import Folder from '../component/Workspace/Folder.jsx'
8 7
 import ContentItem from '../component/Workspace/ContentItem.jsx'
9 8
 import ContentItemHeader from '../component/Workspace/ContentItemHeader.jsx'
@@ -108,7 +107,8 @@ class WorkspaceContent extends React.Component {
108 107
 
109 108
   handleClickContentItem = content => {
110 109
     console.log('%c<WorkspaceContent> content clicked', 'color: #c17838', content)
111
-    this.props.history.push(`/workspaces/${content.idWorkspace}/${content.type}/${content.id}`)
110
+    // this.props.history.push(`/workspaces/${content.idWorkspace}/${content.type}/${content.id}`)
111
+    this.props.history.push(PAGE.WORKSPACE.CONTENT(content.idWorkspace, content.type, content.id))
112 112
   }
113 113
 
114 114
   handleClickEditContentItem = (e, content) => {
@@ -166,9 +166,7 @@ class WorkspaceContent extends React.Component {
166 166
       : []
167 167
 
168 168
     return (
169
-      <div className='sidebarpagecontainer'>
170
-        <Sidebar />
171
-
169
+      <div className='WorkspaceContent' style={{width: '100%'}}>
172 170
         <OpenContentApp
173 171
           // automatically open the app for the idContent in url
174 172
           idWorkspace={this.state.workspaceIdInUrl}

+ 0 - 1
frontend/src/css/Dashboard.styl View File

@@ -31,7 +31,6 @@ coloricon()
31 31
     color lecteur
32 32
 
33 33
 .dashboard
34
-  margin-left 20px
35 34
   width 100%
36 35
   &__header
37 36
     flexwrap()

+ 1 - 1
frontend/src/css/Generic.styl View File

@@ -111,7 +111,7 @@ a
111 111
 
112 112
 
113 113
 .pageContentGeneric
114
-  margin 10px 0 0 0
114
+  margin 10px 15px 0 15px
115 115
   width 100%
116 116
   height 100%
117 117
 

+ 0 - 1
frontend/src/css/Workspace.styl View File

@@ -4,7 +4,6 @@
4 4
     flex-wrap wrap
5 5
     margin-right 15px
6 6
   &__content
7
-    margin 0 15px
8 7
     &__button
9 8
       display flex
10 9
       justify-content flex-end

+ 3 - 5
frontend/src/helper.js View File

@@ -24,14 +24,12 @@ export const workspaceConfig = {
24 24
 export const PAGE = {
25 25
   HOME: '/',
26 26
   WORKSPACE: {
27
+    ROOT: '/workspaces',
27 28
     DASHBOARD: (idws = ':idws') => `/workspaces/${idws}/dashboard`,
28
-    NEW: (idws, type) => `/workspaces/${idws}/${type}/new`,
29
+    NEW: (idws, type) => `/workspaces/${idws}/contents/${type}/new`,
29 30
     CALENDAR: (idws = ':idws') => `/workspaces/${idws}/calendar`,
30 31
     CONTENT_LIST: (idws = ':idws') => `/workspaces/${idws}/contents`,
31
-    CONTENT: (idws = ':idws', type = ':type?', idcts = ':idcts?') => `/workspaces/${idws}/${type}/${idcts}`, // @TODO add /contents/ in url and remove <Switch> in <Tracim>
32
-    // CONTENT_NEW: (idws = ':idws', ctstype = ':ctstype') => `/workspaces/${idws}/contents/${ctstype}/new`,
33
-    // CONTENT_EDIT: (idws = ':idws', idcts = ':idcts') => `/workspaces/${idws}/contents/${idcts}/edit`,
34
-    // CONTENT_TITLE_EDIT: (idws = ':idws', idcts = ':idcts') => `/workspaces/${idws}/contents/${idcts}/title/edit`,
32
+    CONTENT: (idws = ':idws', type = ':type', idcts = ':idcts') => `/workspaces/${idws}/contents/${type}/${idcts}`,
35 33
     ADMIN: (idws = ':idws') => `/workspaces/${idws}/admin`
36 34
   },
37 35
   LOGIN: '/login',