Bladeren bron

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

AlexiCauvin 6 jaren geleden
bovenliggende
commit
1621e4c134

+ 21 - 21
jsonserver/static_db.json Bestand weergeven

114
         "id": 2,
114
         "id": 2,
115
         "parent_id": null,
115
         "parent_id": null,
116
         "workspace_id": 1,
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
         "type": "Thread",
118
         "type": "Thread",
119
         "status": "current"
119
         "status": "current"
120
       },
120
       },
122
         "id": 6,
122
         "id": 6,
123
         "parent_id": null,
123
         "parent_id": null,
124
         "workspace_id": 1,
124
         "workspace_id": 1,
125
-        "title": "Maquette.png Tracim v3",
125
+        "title": "Maquette.png",
126
         "type": "File",
126
         "type": "File",
127
         "status": "outdated"
127
         "status": "outdated"
128
       },
128
       },
130
         "id": 10,
130
         "id": 10,
131
         "parent_id": null,
131
         "parent_id": null,
132
         "workspace_id": 1,
132
         "workspace_id": 1,
133
-        "title": "README.md de tracim_lib",
133
+        "title": "README.md",
134
         "type": "PageMarkdown",
134
         "type": "PageMarkdown",
135
         "status": "validated"
135
         "status": "validated"
136
       },
136
       },
138
         "id": 7,
138
         "id": 7,
139
         "parent_id": null,
139
         "parent_id": null,
140
         "workspace_id": 1,
140
         "workspace_id": 1,
141
-        "title": "Etape d'installation de Tracim",
141
+        "title": "Les etapes pour installer le logiciel",
142
         "type": "Task",
142
         "type": "Task",
143
         "status": "canceled"
143
         "status": "canceled"
144
       },
144
       },
146
         "id": 8,
146
         "id": 8,
147
         "parent_id": null,
147
         "parent_id": null,
148
         "workspace_id": 1,
148
         "workspace_id": 1,
149
-        "title": "Correction du fichier css",
149
+        "title": "Correction du fichier CSS",
150
         "type": "Issue",
150
         "type": "Issue",
151
         "status": "current"
151
         "status": "current"
152
       },
152
       },
154
         "id": 3,
154
         "id": 3,
155
         "parent_id": null,
155
         "parent_id": null,
156
         "workspace_id": 1,
156
         "workspace_id": 1,
157
-        "title": "Correction bug tracim",
157
+        "title": "Correction bug",
158
         "type": "folder",
158
         "type": "folder",
159
         "allowed_app": ["PageHtml", "Thread", "File", "PageMarkdown", "Task", "Issue"],
159
         "allowed_app": ["PageHtml", "Thread", "File", "PageMarkdown", "Task", "Issue"],
160
         "content": []
160
         "content": []
166
       "id": 4,
166
       "id": 4,
167
       "parent_id": 3,
167
       "parent_id": 3,
168
       "workspace_id": 1,
168
       "workspace_id": 1,
169
-      "title": "Schema Backend tracim v2",
169
+      "title": "Schema Backend",
170
       "type": "File",
170
       "type": "File",
171
       "status": "outdated"
171
       "status": "outdated"
172
     },
172
     },
182
       "id": 11,
182
       "id": 11,
183
       "parent_id": 3,
183
       "parent_id": 3,
184
       "workspace_id": 1,
184
       "workspace_id": 1,
185
-      "title": "Correction à effectuer sur le frontend de Tracim v2",
185
+      "title": "Correction à effectuer",
186
       "type": "folder",
186
       "type": "folder",
187
       "allowed_app": ["PageHtml", "Thread", "File", "PageMarkdown", "Task", "Issue"],
187
       "allowed_app": ["PageHtml", "Thread", "File", "PageMarkdown", "Task", "Issue"],
188
       "content": []
188
       "content": []
193
       "id": 12,
193
       "id": 12,
194
       "parent_id": 11,
194
       "parent_id": 11,
195
       "workspace_id": 1,
195
       "workspace_id": 1,
196
-      "title": "Liste des correction à effectuer",
196
+      "title": "Liste des corrections à effectuer",
197
       "type": "PageHtml",
197
       "type": "PageHtml",
198
       "status": "current"
198
       "status": "current"
199
     },
199
     },
218
       "day": "27/11/17",
218
       "day": "27/11/17",
219
       "hour": "11h45"
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
     "id": 1,
223
     "id": 1,
224
     "type": "message",
224
     "type": "message",
229
     },
229
     },
230
     "createdAt": {
230
     "createdAt": {
231
       "day": "27/11/16",
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
     "id": 2,
236
     "id": 2,
237
     "type": "message",
237
     "type": "message",
244
       "day": "27/11/15",
244
       "day": "27/11/15",
245
       "hour": "10h30"
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
     "id": 3,
249
     "id": 3,
250
     "type": "version",
250
     "type": "version",
254
       "avatar": "https://www.algoo.fr/static/images/algoo_images/algoo-logo.jpg"
254
       "avatar": "https://www.algoo.fr/static/images/algoo_images/algoo-logo.jpg"
255
     },
255
     },
256
     "createdAt": {
256
     "createdAt": {
257
-      "day": "27/11/11"
257
+      "day": "24/11/11"
258
     },
258
     },
259
     "number": "5"
259
     "number": "5"
260
   }],
260
   }],
265
     "status": "validated",
265
     "status": "validated",
266
     "icon": "fa fa-fw fa-code-fork",
266
     "icon": "fa fa-fw fa-code-fork",
267
     "version": "version n°5",
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
     "workspace": {
269
     "workspace": {
270
       "id": 1,
270
       "id": 1,
271
       "title": "Liste des contenus",
271
       "title": "Liste des contenus",
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.",
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
       "createdAt": {
288
       "createdAt": {
289
         "day": "05/03/18",
289
         "day": "05/03/18",
290
-        "hour": "10h00"
290
+        "hour": "9h33"
291
       }
291
       }
292
     }, {
292
     }, {
293
       "id": 1,
293
       "id": 1,
298
       },
298
       },
299
       "createdAt": {
299
       "createdAt": {
300
         "day": "05/03/18",
300
         "day": "05/03/18",
301
-        "hour": "09h59"
301
+        "hour": "09h40"
302
       },
302
       },
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"
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
       "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é  .",
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
       "createdAt": {
312
       "createdAt": {
313
         "day": "05/03/18",
313
         "day": "05/03/18",
314
-        "hour": "09h59"
314
+        "hour": "09h46"
315
       }
315
       }
316
     }, {
316
     }, {
317
       "id": 3,
317
       "id": 3,
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.",
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
       "createdAt": {
324
       "createdAt": {
325
         "day": "05/03/18",
325
         "day": "05/03/18",
326
-        "hour": "09h59"
326
+        "hour": "09h50"
327
       }
327
       }
328
     }, {
328
     }, {
329
       "id": 4,
329
       "id": 4,
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 ?!",
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
       "createdAt": {
336
       "createdAt": {
337
         "day": "05/03/18",
337
         "day": "05/03/18",
338
-        "hour": "09h59"
338
+        "hour": "10h00"
339
       }
339
       }
340
     }]
340
     }]
341
   },
341
   },
342
   "workspace_list": [{
342
   "workspace_list": [{
343
     "id": 0,
343
     "id": 0,
344
-    "title": "Dev Tracim"
344
+    "title": "Developpement Tracim"
345
   }, {
345
   }, {
346
     "id": 1,
346
     "id": 1,
347
     "title": "Marketing"
347
     "title": "Marketing"

+ 1 - 0
package.json Bestand weergeven

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

+ 2 - 4
src/action-creator.async.js Bestand weergeven

12
   updateUserData,
12
   updateUserData,
13
   setUserRole,
13
   setUserRole,
14
   WORKSPACE,
14
   WORKSPACE,
15
-  setWorkspaceData,
16
   WORKSPACE_LIST,
15
   WORKSPACE_LIST,
17
   updateWorkspaceListData,
16
   updateWorkspaceListData,
18
   FOLDER,
17
   FOLDER,
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
     url: `${FETCH_CONFIG.mockApiUrl}/workspace/${workspaceId}`,
173
     url: `${FETCH_CONFIG.mockApiUrl}/workspace/${workspaceId}`,
175
     param: {...FETCH_CONFIG.header, method: 'GET'},
174
     param: {...FETCH_CONFIG.header, method: 'GET'},
176
     actionName: WORKSPACE,
175
     actionName: WORKSPACE,
177
     dispatch
176
     dispatch
178
   })
177
   })
179
-  if (fetchGetWorkspaceContent.status === 200) dispatch(setWorkspaceData(fetchGetWorkspaceContent.json, filterStr))
180
 }
178
 }
181
 
179
 
182
 export const getFolderContent = (workspaceId, folderId) => async dispatch => {
180
 export const getFolderContent = (workspaceId, folderId) => async dispatch => {

+ 0 - 4
src/action-creator.sync.js Bestand weergeven

33
 export const updateWorkspaceListData = workspaceList => ({ type: `Update/${WORKSPACE_LIST}`, workspaceList })
33
 export const updateWorkspaceListData = workspaceList => ({ type: `Update/${WORKSPACE_LIST}`, workspaceList })
34
 export const setWorkspaceListIsOpenInSidebar = (workspaceId, isOpenInSidebar) => ({ type: `Set/${WORKSPACE_LIST}/isOpenInSidebar`, workspaceId, isOpenInSidebar })
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
 export const APP_LIST = 'App/List'
36
 export const APP_LIST = 'App/List'
41
 export const setAppList = appList => ({ type: `Set/${APP_LIST}`, appList })
37
 export const setAppList = appList => ({ type: `Set/${APP_LIST}`, appList })
42
 
38
 

+ 2 - 2
src/component/Header/MenuActionListItem/MenuProfil.jsx Bestand weergeven

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

+ 2 - 2
src/component/Sidebar/WorkspaceListItem.jsx Bestand weergeven

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

+ 34 - 20
src/container/Dashboard.jsx Bestand weergeven

41
                 <div className='pageTitleGeneric__title dashboard__header__title__text mr-3'>
41
                 <div className='pageTitleGeneric__title dashboard__header__title__text mr-3'>
42
                   Dashboard
42
                   Dashboard
43
                 </div>
43
                 </div>
44
-                <div className='dashboard__header__acces'>
45
-                  (privé)
46
-                </div>
44
+                <div className='dashboard__header__acces' />
47
               </div>
45
               </div>
48
               <div className='dashboard__header__advancedmode mr-3'>
46
               <div className='dashboard__header__advancedmode mr-3'>
49
                 <button type='button' className='btn btn-primary'>Activer édition avancé</button>
47
                 <button type='button' className='btn btn-primary'>Activer édition avancé</button>
53
             <div className='dashboard__wkswrapper'>
51
             <div className='dashboard__wkswrapper'>
54
               <div className='dashboard__workspace'>
52
               <div className='dashboard__workspace'>
55
                 <div className='dashboard__workspace__title'>
53
                 <div className='dashboard__workspace__title'>
56
-                  Nouvelle ligne directive sur le nouveau design de Tracim
54
+                  Développement tracim
57
                 </div>
55
                 </div>
58
 
56
 
59
                 <div className='dashboard__workspace__detail'>
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
                 </div>
59
                 </div>
63
               </div>
60
               </div>
64
               <div className='dashboard__userstatut'>
61
               <div className='dashboard__userstatut'>
147
                     <i className='fa fa-video-camera' />
144
                     <i className='fa fa-video-camera' />
148
                   </div>
145
                   </div>
149
                   <div className='dashboard__calltoaction__button__text__title'>
146
                   <div className='dashboard__calltoaction__button__text__title'>
150
-                    débuter une visioconférence
147
+                    Débuter une visioconférence
151
                   </div>
148
                   </div>
152
                 </div>
149
                 </div>
153
               </div>
150
               </div>
192
                       <i className='fa fa-comments-o' />
189
                       <i className='fa fa-comments-o' />
193
                     </div>
190
                     </div>
194
                     <div className='dashboard__activity__workspace__name'>
191
                     <div className='dashboard__activity__workspace__name'>
195
-                      <span>Workspace 1</span>
192
+                      <span>Développement Tracim</span>
196
                     </div>
193
                     </div>
197
                   </div>
194
                   </div>
198
 
195
 
201
                       <i className='fa fa-list-ul' />
198
                       <i className='fa fa-list-ul' />
202
                     </div>
199
                     </div>
203
                     <div className='dashboard__activity__workspace__name'>
200
                     <div className='dashboard__activity__workspace__name'>
204
-                      Workspace 2
201
+                      Mission externe
205
                     </div>
202
                     </div>
206
                   </div>
203
                   </div>
207
 
204
 
210
                       <i className='fa fa-list-ul' />
207
                       <i className='fa fa-list-ul' />
211
                     </div>
208
                     </div>
212
                     <div className='dashboard__activity__workspace__name'>
209
                     <div className='dashboard__activity__workspace__name'>
213
-                      Workspace 3
210
+                      Recherche et developpement
214
                     </div>
211
                     </div>
215
                   </div>
212
                   </div>
216
 
213
 
219
                       <i className='fa fa-file-text-o' />
216
                       <i className='fa fa-file-text-o' />
220
                     </div>
217
                     </div>
221
                     <div className='dashboard__activity__workspace__name'>
218
                     <div className='dashboard__activity__workspace__name'>
222
-                      <span>Workspace 4</span>
219
+                      <span>Marketing</span>
223
                     </div>
220
                     </div>
224
                   </div>
221
                   </div>
225
 
222
 
228
                       <i className='fa fa-comments-o' />
225
                       <i className='fa fa-comments-o' />
229
                     </div>
226
                     </div>
230
                     <div className='dashboard__activity__workspace__name'>
227
                     <div className='dashboard__activity__workspace__name'>
231
-                      <span>Workspace 5</span>
228
+                      <span>Évolution</span>
232
                     </div>
229
                     </div>
233
                   </div>
230
                   </div>
234
 
231
 
237
                       <i className='fa fa-file-text-o' />
234
                       <i className='fa fa-file-text-o' />
238
                     </div>
235
                     </div>
239
                     <div className='dashboard__activity__workspace__name'>
236
                     <div className='dashboard__activity__workspace__name'>
240
-                      Workspace 6
237
+                      Commercialisation
241
                     </div>
238
                     </div>
242
                   </div>
239
                   </div>
243
 
240
 
285
                               Aldwin Vinel
282
                               Aldwin Vinel
286
                             </div>
283
                             </div>
287
                             <div className='dashboard__memberlist__list__item__info__role'>
284
                             <div className='dashboard__memberlist__list__item__info__role'>
288
-                              lecteur
285
+                              Lecteur
289
                             </div>
286
                             </div>
290
                           </div>
287
                           </div>
291
                           <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>
288
                           <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>
302
                               William Himme
299
                               William Himme
303
                             </div>
300
                             </div>
304
                             <div className='dashboard__memberlist__list__item__info__role'>
301
                             <div className='dashboard__memberlist__list__item__info__role'>
305
-                              contributeur
302
+                              Contributeur
306
                             </div>
303
                             </div>
307
                           </div>
304
                           </div>
308
                           <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>
305
                           <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>
319
                               Yacine Lite
316
                               Yacine Lite
320
                             </div>
317
                             </div>
321
                             <div className='dashboard__memberlist__list__item__info__role'>
318
                             <div className='dashboard__memberlist__list__item__info__role'>
322
-                              Gestionnaire de contenu
319
+                              Contributeur
323
                             </div>
320
                             </div>
324
                           </div>
321
                           </div>
325
                           <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>
322
                           <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>
333
                           </div>
330
                           </div>
334
                           <div className='dashboard__memberlist__list__item__info mr-auto'>
331
                           <div className='dashboard__memberlist__list__item__info mr-auto'>
335
                             <div className='dashboard__memberlist__list__item__info__name'>
332
                             <div className='dashboard__memberlist__list__item__info__name'>
336
-                              Yacine Lite
333
+                              Alexi Falcin
337
                             </div>
334
                             </div>
338
                             <div className='dashboard__memberlist__list__item__info__role'>
335
                             <div className='dashboard__memberlist__list__item__info__role'>
339
-                              Gestionnaire de contenu
336
+                              Gestionnaire
340
                             </div>
337
                             </div>
341
                           </div>
338
                           </div>
342
                           <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>
339
                           <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>
350
                           </div>
347
                           </div>
351
                           <div className='dashboard__memberlist__list__item__info mr-auto'>
348
                           <div className='dashboard__memberlist__list__item__info mr-auto'>
352
                             <div className='dashboard__memberlist__list__item__info__name'>
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
                             </div>
368
                             </div>
355
                             <div className='dashboard__memberlist__list__item__info__role'>
369
                             <div className='dashboard__memberlist__list__item__info__role'>
356
-                              Gestionnaire de contenu
370
+                              Gestionnaire
357
                             </div>
371
                             </div>
358
                           </div>
372
                           </div>
359
                           <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>
373
                           <div className='dashboard__memberlist__list__item__delete d-flex justify-content-end'>

+ 2 - 2
src/container/Login.jsx Bestand weergeven

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

+ 7 - 7
src/container/Sidebar.jsx Bestand weergeven

9
   setWorkspaceListIsOpenInSidebar,
9
   setWorkspaceListIsOpenInSidebar,
10
   updateWorkspaceFilter
10
   updateWorkspaceFilter
11
 } from '../action-creator.sync.js'
11
 } from '../action-creator.sync.js'
12
-import { PAGE_NAME } from '../helper.js'
12
+import { PAGE } from '../helper.js'
13
 
13
 
14
 class Sidebar extends React.Component {
14
 class Sidebar extends React.Component {
15
   constructor (props) {
15
   constructor (props) {
38
     user.id !== -1 && prevProps.user.id !== user.id && dispatch(getWorkspaceList(user.id, newWorkspaceId))
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
     this.props.dispatch(updateWorkspaceFilter([]))
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
     const { workspace, history, dispatch } = this.props
50
     const { workspace, history, dispatch } = this.props
51
 
51
 
52
     const newFilter = workspace.filter.includes(filter) ? [] : [filter] // use an array to allow multiple filters (NYI)
52
     const newFilter = workspace.filter.includes(filter) ? [] : [filter] // use an array to allow multiple filters (NYI)
53
 
53
 
54
     dispatch(updateWorkspaceFilter(newFilter))
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
   handleClickToggleSidebar = () => this.setState(prev => ({sidebarClose: !prev.sidebarClose}))
59
   handleClickToggleSidebar = () => this.setState(prev => ({sidebarClose: !prev.sidebarClose}))
74
               { workspaceList.map((ws, i) =>
74
               { workspaceList.map((ws, i) =>
75
                 <WorkspaceListItem
75
                 <WorkspaceListItem
76
                   number={++i}
76
                   number={++i}
77
-                  wsId={ws.id}
77
+                  idWs={ws.id}
78
                   name={ws.title}
78
                   name={ws.title}
79
                   app={app}
79
                   app={app}
80
                   lang={activeLang}
80
                   lang={activeLang}

+ 7 - 6
src/container/Tracim.jsx Bestand weergeven

14
   withRouter
14
   withRouter
15
 } from 'react-router-dom'
15
 } from 'react-router-dom'
16
 import PrivateRoute from './PrivateRoute.jsx'
16
 import PrivateRoute from './PrivateRoute.jsx'
17
-import { PAGE_NAME } from '../helper.js'
17
+import { PAGE } from '../helper.js'
18
 import {
18
 import {
19
   getLangList,
19
   getLangList,
20
   getUserIsConnected
20
   getUserIsConnected
55
           ? (<div />) // while we dont know if user is connected, display nothing but the header @TODO show loader
55
           ? (<div />) // while we dont know if user is connected, display nothing but the header @TODO show loader
56
           : (
56
           : (
57
             <div className='tracim__content'>
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
               <PrivateRoute path={'/wip/:cp'} component={WIPcomponent} /> {/* for testing purpose only */}
65
               <PrivateRoute path={'/wip/:cp'} component={WIPcomponent} /> {/* for testing purpose only */}
65
 
66
 
66
               <Footer />
67
               <Footer />

+ 24 - 16
src/container/WorkspaceContent.jsx Bestand weergeven

14
   getWorkspaceContent,
14
   getWorkspaceContent,
15
   getFolderContent
15
   getFolderContent
16
 } from '../action-creator.async.js'
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
 class WorkspaceContent extends React.Component {
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
   handleClickContentItem = content => {
49
   handleClickContentItem = content => {
50
+    this.props.history.push(`${PAGE.WORKSPACE.CONTENT(content.workspace_id, content.id)}${this.props.location.search}`)
41
     this.props.renderApp(this.props.app[content.type], this.props.user, {...content, workspace: this.props.workspace})
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
   handleClickEditContentItem = (e, content) => {
54
   handleClickEditContentItem = (e, content) => {

+ 12 - 3
src/helper.js Bestand weergeven

7
   mockApiUrl: 'http://localhost:3001'
7
   mockApiUrl: 'http://localhost:3001'
8
 }
8
 }
9
 
9
 
10
-export const PAGE_NAME = {
10
+export const PAGE = {
11
   HOME: '/',
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
   LOGIN: '/login',
23
   LOGIN: '/login',
14
-  DASHBOARD: '/dashboard',
15
   ACCOUNT: '/account'
24
   ACCOUNT: '/account'
16
 }
25
 }
17
 
26
 

+ 0 - 19
src/reducer/activeFileContent.js Bestand weergeven

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 Bestand weergeven

4
 import user from './user.js'
4
 import user from './user.js'
5
 import workspace from './workspace.js'
5
 import workspace from './workspace.js'
6
 import workspaceList from './workspaceList.js'
6
 import workspaceList from './workspaceList.js'
7
-import activeFileContent from './activeFileContent.js'
8
 import app from './app.js'
7
 import app from './app.js'
9
 import timezone from './timezone.js'
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
 export default rootReducer
12
 export default rootReducer