Browse Source

Merge branch 'develop' of github.com:tracim/tracim_front into develop

AlexiCauvin 6 years ago
parent
commit
1621e4c134

+ 21 - 21
jsonserver/static_db.json View File

@@ -114,7 +114,7 @@
114 114
         "id": 2,
115 115
         "parent_id": null,
116 116
         "workspace_id": 1,
117
-        "title": "Doit-on intégrer la nouvelle fonctionnalité de tracim maintenant ?",
117
+        "title": "Doit-on intégrer la nouvelle fonctionnalité maintenant ?",
118 118
         "type": "Thread",
119 119
         "status": "current"
120 120
       },
@@ -122,7 +122,7 @@
122 122
         "id": 6,
123 123
         "parent_id": null,
124 124
         "workspace_id": 1,
125
-        "title": "Maquette.png Tracim v3",
125
+        "title": "Maquette.png",
126 126
         "type": "File",
127 127
         "status": "outdated"
128 128
       },
@@ -130,7 +130,7 @@
130 130
         "id": 10,
131 131
         "parent_id": null,
132 132
         "workspace_id": 1,
133
-        "title": "README.md de tracim_lib",
133
+        "title": "README.md",
134 134
         "type": "PageMarkdown",
135 135
         "status": "validated"
136 136
       },
@@ -138,7 +138,7 @@
138 138
         "id": 7,
139 139
         "parent_id": null,
140 140
         "workspace_id": 1,
141
-        "title": "Etape d'installation de Tracim",
141
+        "title": "Les etapes pour installer le logiciel",
142 142
         "type": "Task",
143 143
         "status": "canceled"
144 144
       },
@@ -146,7 +146,7 @@
146 146
         "id": 8,
147 147
         "parent_id": null,
148 148
         "workspace_id": 1,
149
-        "title": "Correction du fichier css",
149
+        "title": "Correction du fichier CSS",
150 150
         "type": "Issue",
151 151
         "status": "current"
152 152
       },
@@ -154,7 +154,7 @@
154 154
         "id": 3,
155 155
         "parent_id": null,
156 156
         "workspace_id": 1,
157
-        "title": "Correction bug tracim",
157
+        "title": "Correction bug",
158 158
         "type": "folder",
159 159
         "allowed_app": ["PageHtml", "Thread", "File", "PageMarkdown", "Task", "Issue"],
160 160
         "content": []
@@ -166,7 +166,7 @@
166 166
       "id": 4,
167 167
       "parent_id": 3,
168 168
       "workspace_id": 1,
169
-      "title": "Schema Backend tracim v2",
169
+      "title": "Schema Backend",
170 170
       "type": "File",
171 171
       "status": "outdated"
172 172
     },
@@ -182,7 +182,7 @@
182 182
       "id": 11,
183 183
       "parent_id": 3,
184 184
       "workspace_id": 1,
185
-      "title": "Correction à effectuer sur le frontend de Tracim v2",
185
+      "title": "Correction à effectuer",
186 186
       "type": "folder",
187 187
       "allowed_app": ["PageHtml", "Thread", "File", "PageMarkdown", "Task", "Issue"],
188 188
       "content": []
@@ -193,7 +193,7 @@
193 193
       "id": 12,
194 194
       "parent_id": 11,
195 195
       "workspace_id": 1,
196
-      "title": "Liste des correction à effectuer",
196
+      "title": "Liste des corrections à effectuer",
197 197
       "type": "PageHtml",
198 198
       "status": "current"
199 199
     },
@@ -218,7 +218,7 @@
218 218
       "day": "27/11/17",
219 219
       "hour": "11h45"
220 220
     },
221
-    "text": "Proident esse laboris in sed officia exercitation ut anim ea."
221
+    "text": "Voici le début de ce qui nous servira de cachier des charges pour la partie design du logiciel, chacun peut completer le documents, nésité pas à faire des retours ! "
222 222
   }, {
223 223
     "id": 1,
224 224
     "type": "message",
@@ -229,9 +229,9 @@
229 229
     },
230 230
     "createdAt": {
231 231
       "day": "27/11/16",
232
-      "hour": "10h30"
232
+      "hour": "10h35"
233 233
     },
234
-    "text": "Proident esse laboris in sed officia exercitation ut anim ea. in sed officia exercitation ut"
234
+    "text": "Bonjour, je viens de modifier le cahier des charges sur la partie design v2."
235 235
   }, {
236 236
     "id": 2,
237 237
     "type": "message",
@@ -244,7 +244,7 @@
244 244
       "day": "27/11/15",
245 245
       "hour": "10h30"
246 246
     },
247
-    "text": "Proident esse laboris in sed officia exercitation ut anim ea. Proident esse laboris in sed officia exercitation ut anim ea. Proident esse laboris in sed officia exercitation ut anim ea."
247
+    "text": "Je viens de tout relire, je pense que c'est bon, on peut commencer les choses sérieuses."
248 248
   }, {
249 249
     "id": 3,
250 250
     "type": "version",
@@ -254,7 +254,7 @@
254 254
       "avatar": "https://www.algoo.fr/static/images/algoo_images/algoo-logo.jpg"
255 255
     },
256 256
     "createdAt": {
257
-      "day": "27/11/11"
257
+      "day": "24/11/11"
258 258
     },
259 259
     "number": "5"
260 260
   }],
@@ -265,7 +265,7 @@
265 265
     "status": "validated",
266 266
     "icon": "fa fa-fw fa-code-fork",
267 267
     "version": "version n°5",
268
-    "text": "Je suis le contenu de cette fameuse <b>page HTML</b><br /> sur la programmation fonctionnelle",
268
+    "text": " <center><b>Design V2</b></center><br/><br/><br/> Suite à la réunion tenue ce vendredi, je mets à jour ce document concernant le futur design de notre interface. Comme convenue nous aurons un dashboard qui va résumer toute l'activité présente sur le site ainsi que toutes les personnes qui auront participer au projet. De plus il y aura la présence d'un historique pour permettre à tout le monde de voir, qui a modifié, créé ou contribué aux documents. Mais aussi savoir qui a déposé ou envoyé un message dans le canal de discussion. <br/><br/><br/><br/><br/> Deuxième point évoqué: Le fait de pouvoir modifier l'interface et la couleur pour les futurs utilisateurs. On devra donc avoir accés à différents thémes d'interface et de couleurs prédéfinis mais aussi le possibilité de pouvoir créer ces propres thémes. Des maquettes devront bientôt être disponible pour nous donner un aperçu de ce que pourra être l'outil final. <br/><br/><br/><br/> Nécesité pas à rajouter,modifier ce que j'ai écrit, il doit surêment y avoir des manques. ",
269 269
     "workspace": {
270 270
       "id": 1,
271 271
       "title": "Liste des contenus",
@@ -287,7 +287,7 @@
287 287
       "text": "Bonjour, Dans le cadre d'une procédure de renouvellement de DSP, où deux sociétés se sont portées candidats et ont remis une offre, la société qui n'a pas retenue souhaite que le rapport d'analyse des offres lui soit communiqué. Ce document peut il être communiqué, en tout ou partie, dans le respect des préconisations de la CADA (loi 07-07-1978) ?Merci pour votre retour d'expérience.",
288 288
       "createdAt": {
289 289
         "day": "05/03/18",
290
-        "hour": "10h00"
290
+        "hour": "9h33"
291 291
       }
292 292
     }, {
293 293
       "id": 1,
@@ -298,7 +298,7 @@
298 298
       },
299 299
       "createdAt": {
300 300
         "day": "05/03/18",
301
-        "hour": "09h59"
301
+        "hour": "09h40"
302 302
       },
303 303
       "text": "Le doc est communicable mais doit être en partie occulté. Je te met en pièce jointe un doc la dessus. Tu peux aussi voir le Conseil n° 20003802 et Avis n° 20011051 de la CADA"
304 304
     }, {
@@ -311,7 +311,7 @@
311 311
       "text": "Oups, je ne trouve plus comment faire. :-O  tant pis je te colle le texte ci après  Une fois la délégation de service public  ou le marché signé, les documents composant la procédure de passation perdent leur caractère préparatoire  au sens des dispositions de l’article 2 de la loi du 17 juillet 1978, et deviennent, en principe, communicables à toute personne qui en fait la demande, y compris à un candidat évincé [Voir FAQ n° 2 et 7].  Toutefois, en vertu du II de l’article 6 de la même loi, ce droit d’accès doit s’exercer dans le respect du secret en matière industrielle et commerciale lequel recouvre le secret des procédés, le secret des informations économiques et financières, et le secret des stratégies commerciales  [Voir FAQ n° 4]. À ce titre, sont notamment exclus de la communication les éléments suivants, qui devront être occultés :  - les mentions relatives aux moyens techniques et humains ;  - les mentions concernant le chiffre d’affaires, les coordonnées bancaires ;  - les références autres que celles qui correspondent à des marchés publics.  La communication de certaines informations comporte un risque d’atteinte à la libre concurrence (dans le rapport d’analyse des offres ou le détail des prix par exemple). Les autorités administratives doivent donc, pour apprécier les informations qui sont protégées par le secret en matière industrielle et commerciale, tenir compte du mode de passation, de la durée, ou de l’objet du marché [Voir FAQ n° 5].  Le tableau ci-après fait apparaître les pièces qui ne posent aucune difficulté de communication, et celles qui nécessitent une analyse du risque d’atteinte à la concurrence. La CADA a dégagé, au fur à mesure des affaires qui lui étaient soumises, trois catégories de marchés : ponctuel, répétitif et fréquent [pour leur définition voir FAQ n° 6].  Le détail de l’offre de prix de l’entreprise attributaire est communicable dans le cas d'un marché ponctuel , car il reflète le coût du service public, et ne l’est pas pour un marché répétitif, car il serait susceptible de porter atteinte à la concurrence lors du renouvellement du marché  .",
312 312
       "createdAt": {
313 313
         "day": "05/03/18",
314
-        "hour": "09h59"
314
+        "hour": "09h46"
315 315
       }
316 316
     }, {
317 317
       "id": 3,
@@ -323,7 +323,7 @@
323 323
       "text": "il y a aussi des informations générales et un tableau récapitulatif intéressant au lien suivant :  http://www.cada.fr/marches-publics%2c6085.html  bon WE.",
324 324
       "createdAt": {
325 325
         "day": "05/03/18",
326
-        "hour": "09h59"
326
+        "hour": "09h50"
327 327
       }
328 328
     }, {
329 329
       "id": 4,
@@ -335,13 +335,13 @@
335 335
       "text": "Je croyais que le rapport d'analyse des offres n'étant pas une pièce officielle de la procédure de DSP, n'avait pas à être communiqué. En revanche, l'avis de la COP qui est une pièce officielle de la procédure doit être communiqué à la demande d'un candidat en occultant certains éléments énoncés ci-dessous. J'ai tout faux ?!",
336 336
       "createdAt": {
337 337
         "day": "05/03/18",
338
-        "hour": "09h59"
338
+        "hour": "10h00"
339 339
       }
340 340
     }]
341 341
   },
342 342
   "workspace_list": [{
343 343
     "id": 0,
344
-    "title": "Dev Tracim"
344
+    "title": "Developpement Tracim"
345 345
   }, {
346 346
     "id": 1,
347 347
     "title": "Marketing"

+ 1 - 0
package.json View File

@@ -29,6 +29,7 @@
29 29
     "file-loader": "^1.1.5",
30 30
     "i18next": "^10.5.0",
31 31
     "prop-types": "^15.6.0",
32
+    "query-string": "^6.1.0",
32 33
     "react": "^16.0.0",
33 34
     "react-animate-height": "^0.10.10",
34 35
     "react-dom": "^16.0.0",

+ 2 - 4
src/action-creator.async.js View File

@@ -12,7 +12,6 @@ import {
12 12
   updateUserData,
13 13
   setUserRole,
14 14
   WORKSPACE,
15
-  setWorkspaceData,
16 15
   WORKSPACE_LIST,
17 16
   updateWorkspaceListData,
18 17
   FOLDER,
@@ -169,14 +168,13 @@ export const getWorkspaceList = (userId, workspaceIdToOpen) => async dispatch =>
169 168
   }
170 169
 }
171 170
 
172
-export const getWorkspaceContent = (workspaceId, filterStr) => async dispatch => {
173
-  const fetchGetWorkspaceContent = await fetchWrapper({
171
+export const getWorkspaceContent = workspaceId => dispatch => {
172
+  return fetchWrapper({
174 173
     url: `${FETCH_CONFIG.mockApiUrl}/workspace/${workspaceId}`,
175 174
     param: {...FETCH_CONFIG.header, method: 'GET'},
176 175
     actionName: WORKSPACE,
177 176
     dispatch
178 177
   })
179
-  if (fetchGetWorkspaceContent.status === 200) dispatch(setWorkspaceData(fetchGetWorkspaceContent.json, filterStr))
180 178
 }
181 179
 
182 180
 export const getFolderContent = (workspaceId, folderId) => async dispatch => {

+ 0 - 4
src/action-creator.sync.js View File

@@ -33,10 +33,6 @@ export const WORKSPACE_LIST = 'WorkspaceList'
33 33
 export const updateWorkspaceListData = workspaceList => ({ type: `Update/${WORKSPACE_LIST}`, workspaceList })
34 34
 export const setWorkspaceListIsOpenInSidebar = (workspaceId, isOpenInSidebar) => ({ type: `Set/${WORKSPACE_LIST}/isOpenInSidebar`, workspaceId, isOpenInSidebar })
35 35
 
36
-export const FILE_CONTENT = 'FileContent'
37
-export const setActiveFileContentActive = file => ({ type: `Set/${FILE_CONTENT}/Active`, file })
38
-export const setActiveFileContentHide = () => ({ type: `Set/${FILE_CONTENT}/Hide` })
39
-
40 36
 export const APP_LIST = 'App/List'
41 37
 export const setAppList = appList => ({ type: `Set/${APP_LIST}`, appList })
42 38
 

+ 2 - 2
src/component/Header/MenuActionListItem/MenuProfil.jsx View File

@@ -1,7 +1,7 @@
1 1
 import React from 'react'
2 2
 import { Link } from 'react-router-dom'
3 3
 import PropTypes from 'prop-types'
4
-import { PAGE_NAME } from '../../../helper.js'
4
+import { PAGE } from '../../../helper.js'
5 5
 
6 6
 const MenuProfil = props => {
7 7
   return props.user.logged
@@ -15,7 +15,7 @@ const MenuProfil = props => {
15 15
             </div>
16 16
           </button>
17 17
           <div className='profilgroup__setting dropdown-menu' aria-labelledby='dropdownMenuButton'>
18
-            <Link className='setting__link dropdown-item' to={PAGE_NAME.ACCOUNT}>Mon compte</Link>
18
+            <Link className='setting__link dropdown-item' to={PAGE.ACCOUNT}>Mon compte</Link>
19 19
             {/* <div className='setting__link dropdown-item'>Mot de passe</div> */}
20 20
             <div className='setting__link dropdown-item' onClick={props.onClickLogout}>Se déconnecter</div>
21 21
           </div>

+ 2 - 2
src/component/Sidebar/WorkspaceListItem.jsx View File

@@ -33,7 +33,7 @@ const WorkspaceListItem = props => {
33 33
         >
34 34
           <li
35 35
             className='sidebar__navigation__workspace__item__submenu__dropdown'
36
-            onClick={() => props.onClickAllContent(props.wsId)}
36
+            onClick={() => props.onClickAllContent(props.idWs)}
37 37
           >
38 38
             <div className='dropdown__icon'>
39 39
               <i className='fa fa-th' />
@@ -89,7 +89,7 @@ const WorkspaceListItem = props => {
89 89
           { Object.keys(props.app).map(a =>
90 90
             <li
91 91
               className={classnames('sidebar__navigation__workspace__item__submenu__dropdown', {'activeFilter': props.activeFilterList.includes(a)})}
92
-              onClick={() => props.onClickContentFilter(props.wsId, a)}
92
+              onClick={() => props.onClickContentFilter(props.idWs, a)}
93 93
               key={a}
94 94
             >
95 95
               <div className='dropdown__icon'>

+ 34 - 20
src/container/Dashboard.jsx View File

@@ -41,9 +41,7 @@ class Dashboard extends Component {
41 41
                 <div className='pageTitleGeneric__title dashboard__header__title__text mr-3'>
42 42
                   Dashboard
43 43
                 </div>
44
-                <div className='dashboard__header__acces'>
45
-                  (privé)
46
-                </div>
44
+                <div className='dashboard__header__acces' />
47 45
               </div>
48 46
               <div className='dashboard__header__advancedmode mr-3'>
49 47
                 <button type='button' className='btn btn-primary'>Activer édition avancé</button>
@@ -53,12 +51,11 @@ class Dashboard extends Component {
53 51
             <div className='dashboard__wkswrapper'>
54 52
               <div className='dashboard__workspace'>
55 53
                 <div className='dashboard__workspace__title'>
56
-                  Nouvelle ligne directive sur le nouveau design de Tracim
54
+                  Développement tracim
57 55
                 </div>
58 56
 
59 57
                 <div className='dashboard__workspace__detail'>
60
-                  Ut in et sit adipisicing mollit amet ut exercitation proident laborum duis occaecat eu aute qui ut.
61
-                  Dolore veniam eu consectetur occaecat est elit dolor nulla est ut amet do reprehenderit eiusmod tempor.
58
+                  Ligne directive pour le prochain design de Tracim et des futurs fonctionnalités.
62 59
                 </div>
63 60
               </div>
64 61
               <div className='dashboard__userstatut'>
@@ -147,7 +144,7 @@ class Dashboard extends Component {
147 144
                     <i className='fa fa-video-camera' />
148 145
                   </div>
149 146
                   <div className='dashboard__calltoaction__button__text__title'>
150
-                    débuter une visioconférence
147
+                    Débuter une visioconférence
151 148
                   </div>
152 149
                 </div>
153 150
               </div>
@@ -192,7 +189,7 @@ class Dashboard extends Component {
192 189
                       <i className='fa fa-comments-o' />
193 190
                     </div>
194 191
                     <div className='dashboard__activity__workspace__name'>
195
-                      <span>Workspace 1</span>
192
+                      <span>Développement Tracim</span>
196 193
                     </div>
197 194
                   </div>
198 195
 
@@ -201,7 +198,7 @@ class Dashboard extends Component {
201 198
                       <i className='fa fa-list-ul' />
202 199
                     </div>
203 200
                     <div className='dashboard__activity__workspace__name'>
204
-                      Workspace 2
201
+                      Mission externe
205 202
                     </div>
206 203
                   </div>
207 204
 
@@ -210,7 +207,7 @@ class Dashboard extends Component {
210 207
                       <i className='fa fa-list-ul' />
211 208
                     </div>
212 209
                     <div className='dashboard__activity__workspace__name'>
213
-                      Workspace 3
210
+                      Recherche et developpement
214 211
                     </div>
215 212
                   </div>
216 213
 
@@ -219,7 +216,7 @@ class Dashboard extends Component {
219 216
                       <i className='fa fa-file-text-o' />
220 217
                     </div>
221 218
                     <div className='dashboard__activity__workspace__name'>
222
-                      <span>Workspace 4</span>
219
+                      <span>Marketing</span>
223 220
                     </div>
224 221
                   </div>
225 222
 
@@ -228,7 +225,7 @@ class Dashboard extends Component {
228 225
                       <i className='fa fa-comments-o' />
229 226
                     </div>
230 227
                     <div className='dashboard__activity__workspace__name'>
231
-                      <span>Workspace 5</span>
228
+                      <span>Évolution</span>
232 229
                     </div>
233 230
                   </div>
234 231
 
@@ -237,7 +234,7 @@ class Dashboard extends Component {
237 234
                       <i className='fa fa-file-text-o' />
238 235
                     </div>
239 236
                     <div className='dashboard__activity__workspace__name'>
240
-                      Workspace 6
237
+                      Commercialisation
241 238
                     </div>
242 239
                   </div>
243 240
 
@@ -285,7 +282,7 @@ class Dashboard extends Component {
285 282
                               Aldwin Vinel
286 283
                             </div>
287 284
                             <div className='dashboard__memberlist__list__item__info__role'>
288
-                              lecteur
285
+                              Lecteur
289 286
                             </div>
290 287
                           </div>
291 288
                           <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>
@@ -302,7 +299,7 @@ class Dashboard extends Component {
302 299
                               William Himme
303 300
                             </div>
304 301
                             <div className='dashboard__memberlist__list__item__info__role'>
305
-                              contributeur
302
+                              Contributeur
306 303
                             </div>
307 304
                           </div>
308 305
                           <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>
@@ -319,7 +316,7 @@ class Dashboard extends Component {
319 316
                               Yacine Lite
320 317
                             </div>
321 318
                             <div className='dashboard__memberlist__list__item__info__role'>
322
-                              Gestionnaire de contenu
319
+                              Contributeur
323 320
                             </div>
324 321
                           </div>
325 322
                           <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>
@@ -333,10 +330,10 @@ class Dashboard extends Component {
333 330
                           </div>
334 331
                           <div className='dashboard__memberlist__list__item__info mr-auto'>
335 332
                             <div className='dashboard__memberlist__list__item__info__name'>
336
-                              Yacine Lite
333
+                              Alexi Falcin
337 334
                             </div>
338 335
                             <div className='dashboard__memberlist__list__item__info__role'>
339
-                              Gestionnaire de contenu
336
+                              Gestionnaire
340 337
                             </div>
341 338
                           </div>
342 339
                           <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>
@@ -350,10 +347,27 @@ class Dashboard extends Component {
350 347
                           </div>
351 348
                           <div className='dashboard__memberlist__list__item__info mr-auto'>
352 349
                             <div className='dashboard__memberlist__list__item__info__name'>
353
-                              Yacine Lite
350
+                              Mickaël Fonati
351
+                            </div>
352
+                            <div className='dashboard__memberlist__list__item__info__role'>
353
+                              Gestionnaire
354
+                            </div>
355
+                          </div>
356
+                          <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>
357
+                            <i className='fa fa-trash-o' />
358
+                          </div>
359
+                        </li>
360
+
361
+                        <li className='dashboard__memberlist__list__item'>
362
+                          <div className='dashboard__memberlist__list__item__avatar'>
363
+                            <img src={imgProfil} alt='avatar' />
364
+                          </div>
365
+                          <div className='dashboard__memberlist__list__item__info mr-auto'>
366
+                            <div className='dashboard__memberlist__list__item__info__name'>
367
+                              Eva Lonbard
354 368
                             </div>
355 369
                             <div className='dashboard__memberlist__list__item__info__role'>
356
-                              Gestionnaire de contenu
370
+                              Gestionnaire
357 371
                             </div>
358 372
                           </div>
359 373
                           <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>

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

@@ -16,7 +16,7 @@ import {
16 16
   newFlashMessage,
17 17
   setUserConnected
18 18
 } from '../action-creator.sync.js'
19
-import {PAGE_NAME} from '../helper.js'
19
+import {PAGE} from '../helper.js'
20 20
 
21 21
 class Login extends React.Component {
22 22
   constructor (props) {
@@ -46,7 +46,7 @@ class Login extends React.Component {
46 46
 
47 47
     if (fetchPostUserLogin.status === 200) {
48 48
       dispatch(setUserConnected({...fetchPostUserLogin.json, logged: true}))
49
-      history.push(PAGE_NAME.HOME)
49
+      history.push(PAGE.HOME)
50 50
     } else if (fetchPostUserLogin.status === 400) {
51 51
       dispatch(newFlashMessage(t('Login.fail'), 'danger'))
52 52
     }

+ 7 - 7
src/container/Sidebar.jsx View File

@@ -9,7 +9,7 @@ import {
9 9
   setWorkspaceListIsOpenInSidebar,
10 10
   updateWorkspaceFilter
11 11
 } from '../action-creator.sync.js'
12
-import { PAGE_NAME } from '../helper.js'
12
+import { PAGE } from '../helper.js'
13 13
 
14 14
 class Sidebar extends React.Component {
15 15
   constructor (props) {
@@ -38,22 +38,22 @@ class Sidebar extends React.Component {
38 38
     user.id !== -1 && prevProps.user.id !== user.id && dispatch(getWorkspaceList(user.id, newWorkspaceId))
39 39
   }
40 40
 
41
-  handleClickWorkspace = (wsId, newIsOpenInSidebar) => this.props.dispatch(setWorkspaceListIsOpenInSidebar(wsId, newIsOpenInSidebar))
41
+  handleClickWorkspace = (idWs, newIsOpenInSidebar) => this.props.dispatch(setWorkspaceListIsOpenInSidebar(idWs, newIsOpenInSidebar))
42 42
 
43
-  handleClickAllContent = wsId => {
43
+  handleClickAllContent = idWs => {
44 44
     this.props.dispatch(updateWorkspaceFilter([]))
45 45
 
46
-    this.props.history.push(`${PAGE_NAME.WS_CONTENT}/${wsId}`)
46
+    this.props.history.push(PAGE.WORKSPACE.CONTENT_LIST(idWs))
47 47
   }
48 48
 
49
-  handleClickContentFilter = (wsId, filter) => {
49
+  handleClickContentFilter = (idWs, filter) => {
50 50
     const { workspace, history, dispatch } = this.props
51 51
 
52 52
     const newFilter = workspace.filter.includes(filter) ? [] : [filter] // use an array to allow multiple filters (NYI)
53 53
 
54 54
     dispatch(updateWorkspaceFilter(newFilter))
55 55
 
56
-    history.push(`${PAGE_NAME.WS_CONTENT}/${wsId}/${newFilter.join(';')}`) // workspace.filter gets updated on react redraw from match.params
56
+    history.push(`${PAGE.WORKSPACE.CONTENT_LIST(idWs)}?type=${newFilter.join(';')}`) // workspace.filter gets updated on react redraw from match.params
57 57
   }
58 58
 
59 59
   handleClickToggleSidebar = () => this.setState(prev => ({sidebarClose: !prev.sidebarClose}))
@@ -74,7 +74,7 @@ class Sidebar extends React.Component {
74 74
               { workspaceList.map((ws, i) =>
75 75
                 <WorkspaceListItem
76 76
                   number={++i}
77
-                  wsId={ws.id}
77
+                  idWs={ws.id}
78 78
                   name={ws.title}
79 79
                   app={app}
80 80
                   lang={activeLang}

+ 7 - 6
src/container/Tracim.jsx View File

@@ -14,7 +14,7 @@ import {
14 14
   withRouter
15 15
 } from 'react-router-dom'
16 16
 import PrivateRoute from './PrivateRoute.jsx'
17
-import { PAGE_NAME } from '../helper.js'
17
+import { PAGE } from '../helper.js'
18 18
 import {
19 19
   getLangList,
20 20
   getUserIsConnected
@@ -55,12 +55,13 @@ class Tracim extends React.Component {
55 55
           ? (<div />) // while we dont know if user is connected, display nothing but the header @TODO show loader
56 56
           : (
57 57
             <div className='tracim__content'>
58
-              <Route path={PAGE_NAME.LOGIN} component={Login} />
58
+              <Route path={PAGE.LOGIN} component={Login} />
59 59
 
60
-              <PrivateRoute exact path={PAGE_NAME.HOME} component={WorkspaceContent} />
61
-              <PrivateRoute path={`${PAGE_NAME.WS_CONTENT}/:idws/:filter?`} component={WorkspaceContent} />
62
-              <PrivateRoute exact path={PAGE_NAME.ACCOUNT} component={Account} />
63
-              <PrivateRoute exact path={PAGE_NAME.DASHBOARD} component={Dashboard} />
60
+              <PrivateRoute exact path={PAGE.HOME} component={WorkspaceContent} />
61
+              <PrivateRoute exact path={PAGE.WORKSPACE.CONTENT_LIST(':idws')} component={WorkspaceContent} /> {/* "exact" here to not double match Route WORKSPACE.CONTENT */}
62
+              <PrivateRoute path={PAGE.WORKSPACE.CONTENT(':idws', ':idcts')} component={WorkspaceContent} />
63
+              <PrivateRoute path={PAGE.ACCOUNT} component={Account} />
64
+              <PrivateRoute path={PAGE.WORKSPACE.DASHBOARD(':idws')} component={Dashboard} />
64 65
               <PrivateRoute path={'/wip/:cp'} component={WIPcomponent} /> {/* for testing purpose only */}
65 66
 
66 67
               <Footer />

+ 24 - 16
src/container/WorkspaceContent.jsx View File

@@ -14,33 +14,41 @@ import {
14 14
   getWorkspaceContent,
15 15
   getFolderContent
16 16
 } from '../action-creator.async.js'
17
+import {newFlashMessage, setWorkspaceData} from '../action-creator.sync.js'
18
+import { PAGE } from '../helper.js'
19
+
20
+const qs = require('query-string')
17 21
 
18 22
 class WorkspaceContent extends React.Component {
19
-  componentDidMount () {
20
-    const { workspaceList, app, match, dispatch } = this.props
23
+  async componentDidMount () {
24
+    const { workspaceList, app, match, location, dispatch } = this.props
21 25
 
22
-    if (match.params.idws !== undefined) dispatch(getWorkspaceContent(match.params.idws, match.params.filter))
23
-    else if (workspaceList.length > 0) dispatch(getWorkspaceContent(workspaceList[0].id, match.params.filter)) // load first ws if none specified
26
+    if (Object.keys(app).length === 0) await dispatch(getAppList())
24 27
 
25
-    if (Object.keys(app).length === 0) dispatch(getAppList())
26
-  }
28
+    const wsToLoad = (() => {
29
+      if (match.params.idws !== undefined) return match.params.idws
30
+      if (workspaceList.length > 0) return workspaceList[0].id // load first ws if none specified
31
+      return null
32
+    })()
33
+
34
+    if (wsToLoad === null) return
27 35
 
28
-  componentDidUpdate (prevProps) {
29
-    const { workspace, workspaceList, match, dispatch } = this.props
36
+    const wsContent = await dispatch(getWorkspaceContent(wsToLoad))
37
+    if (wsContent.status === 200) {
38
+      dispatch(setWorkspaceData(wsContent.json, qs.parse(location.search).type))
30 39
 
31
-    // if a workspace is already loaded and the idws in url hasn't changed, do nothing
32
-    if (workspace.id !== -1 && prevProps.match.params.idws === match.params.idws) return
40
+      if (match.params.idcts) { // if a content id is in url, open it
41
+        const contentToOpen = wsContent.json.content.find(wsc => wsc.id === parseInt(match.params.idcts))
42
+        if (contentToOpen === undefined) return
33 43
 
34
-    // if the idws in url has changed, load the new workspace
35
-    if (match.params.idws !== undefined) dispatch(getWorkspaceContent(match.params.idws, match.params.filter))
36
-    // else bellow is for loading url PAGE_NAME.HOME (without an idws), when workspaceList is loaded, load the first workspace
37
-    else if (workspace.id === -1 && workspaceList.length > 0) dispatch(getWorkspaceContent(workspaceList[0].id))
44
+        this.handleClickContentItem(contentToOpen)
45
+      }
46
+    } else dispatch(newFlashMessage('Error while loading workspace', 'danger'))
38 47
   }
39 48
 
40 49
   handleClickContentItem = content => {
50
+    this.props.history.push(`${PAGE.WORKSPACE.CONTENT(content.workspace_id, content.id)}${this.props.location.search}`)
41 51
     this.props.renderApp(this.props.app[content.type], this.props.user, {...content, workspace: this.props.workspace})
42
-    // Côme - 2018/03/08 - line bellow is useless because we cannot call the reducer again when hiding app since the call comes from the app
43
-    // dispatch(setActiveFileContentActive(content))
44 52
   }
45 53
 
46 54
   handleClickEditContentItem = (e, content) => {

+ 12 - 3
src/helper.js View File

@@ -7,11 +7,20 @@ export const FETCH_CONFIG = {
7 7
   mockApiUrl: 'http://localhost:3001'
8 8
 }
9 9
 
10
-export const PAGE_NAME = {
10
+export const PAGE = {
11 11
   HOME: '/',
12
-  WS_CONTENT: '/workspace',
12
+  WORKSPACE: {
13
+    DASHBOARD: idws => `/workspace/${idws}`,
14
+    NEW: '/workspace/new',
15
+    CALENDAR: idws => `/workspace/${idws}/apps/calendar`,
16
+    CONTENT_LIST: idws => `/workspace/${idws}/apps/contents`,
17
+    CONTENT: (idws, idcts) => `/workspace/${idws}/apps/contents/${idcts}`,
18
+    CONTENT_NEW: (idws, ctstype) => `/workspace/${idws}/apps/contents/${ctstype}/new`,
19
+    CONTENT_EDIT: (idws, idcts) => `/workspace/${idws}/apps/contents/${idcts}/edit`,
20
+    CONTENT_TITLE_EDIT: (idws, idcts) => `/workspace/${idws}/apps/contents/${idcts}/title/edit`,
21
+    ADMIN: idws => `/workspace/${idws}/admin`
22
+  },
13 23
   LOGIN: '/login',
14
-  DASHBOARD: '/dashboard',
15 24
   ACCOUNT: '/account'
16 25
 }
17 26
 

+ 0 - 19
src/reducer/activeFileContent.js View File

@@ -1,19 +0,0 @@
1
-import { FILE_CONTENT } from '../action-creator.sync.js'
2
-
3
-export default function activeFileContent (state = {
4
-  display: false,
5
-  type: '',
6
-  title: '',
7
-  status: ''
8
-}, action) {
9
-  switch (action.type) {
10
-    case `Set/${FILE_CONTENT}/Active`:
11
-      return {...action.file, display: true}
12
-
13
-    case `Set/${FILE_CONTENT}/Hide`:
14
-      return {...state, display: false}
15
-
16
-    default:
17
-      return state
18
-  }
19
-}

+ 1 - 2
src/reducer/root.js View File

@@ -4,10 +4,9 @@ import flashMessage from './flashMessage.js'
4 4
 import user from './user.js'
5 5
 import workspace from './workspace.js'
6 6
 import workspaceList from './workspaceList.js'
7
-import activeFileContent from './activeFileContent.js'
8 7
 import app from './app.js'
9 8
 import timezone from './timezone.js'
10 9
 
11
-const rootReducer = combineReducers({ lang, flashMessage, user, workspace, workspaceList, activeFileContent, app, timezone })
10
+const rootReducer = combineReducers({ lang, flashMessage, user, workspace, workspaceList, app, timezone })
12 11
 
13 12
 export default rootReducer