Просмотр исходного кода

added sidebar sub menu + bugfix

Skylsmoi 6 лет назад
Родитель
Сommit
80fab14e27

+ 9 - 6
src/action-creator.async.js Просмотреть файл

12
   updateUserData,
12
   updateUserData,
13
   setUserRole,
13
   setUserRole,
14
   WORKSPACE,
14
   WORKSPACE,
15
-  updateWorkspaceData,
15
+  setWorkspaceData,
16
   WORKSPACE_LIST,
16
   WORKSPACE_LIST,
17
   updateWorkspaceListData,
17
   updateWorkspaceListData,
18
   APP_LIST,
18
   APP_LIST,
19
-  setAppList
19
+  setAppList, setWorkspaceListIsOpenInSidebar
20
 } from './action-creator.sync.js'
20
 } from './action-creator.sync.js'
21
 
21
 
22
 /*
22
 /*
143
 //   console.log('jsonResponseNoData', fetchResponseNoData)
143
 //   console.log('jsonResponseNoData', fetchResponseNoData)
144
 // }
144
 // }
145
 
145
 
146
-export const getWorkspaceList = userId => async dispatch => {
146
+export const getWorkspaceList = (userId, workspaceIdToOpen) => async dispatch => {
147
   const fetchGetWorkspaceList = await fetchWrapper({
147
   const fetchGetWorkspaceList = await fetchWrapper({
148
     url: `${FETCH_CONFIG.apiUrl}/user/${userId}/workspace`,
148
     url: `${FETCH_CONFIG.apiUrl}/user/${userId}/workspace`,
149
     param: {...FETCH_CONFIG.header, method: 'GET'},
149
     param: {...FETCH_CONFIG.header, method: 'GET'},
150
     actionName: WORKSPACE_LIST,
150
     actionName: WORKSPACE_LIST,
151
     dispatch
151
     dispatch
152
   })
152
   })
153
-  if (fetchGetWorkspaceList.status === 200) dispatch(updateWorkspaceListData(fetchGetWorkspaceList.json))
153
+  if (fetchGetWorkspaceList.status === 200) {
154
+    dispatch(updateWorkspaceListData(fetchGetWorkspaceList.json))
155
+    dispatch(setWorkspaceListIsOpenInSidebar(workspaceIdToOpen, true))
156
+  }
154
 }
157
 }
155
 
158
 
156
-export const getWorkspaceContent = workspaceId => async dispatch => {
159
+export const getWorkspaceContent = (workspaceId, filterStr) => async dispatch => {
157
   const fetchGetWorkspaceContent = await fetchWrapper({
160
   const fetchGetWorkspaceContent = await fetchWrapper({
158
     url: `${FETCH_CONFIG.apiUrl}/workspace/${workspaceId}`,
161
     url: `${FETCH_CONFIG.apiUrl}/workspace/${workspaceId}`,
159
     param: {...FETCH_CONFIG.header, method: 'GET'},
162
     param: {...FETCH_CONFIG.header, method: 'GET'},
160
     actionName: WORKSPACE,
163
     actionName: WORKSPACE,
161
     dispatch
164
     dispatch
162
   })
165
   })
163
-  if (fetchGetWorkspaceContent.status === 200) dispatch(updateWorkspaceData(fetchGetWorkspaceContent.json))
166
+  if (fetchGetWorkspaceContent.status === 200) dispatch(setWorkspaceData(fetchGetWorkspaceContent.json, filterStr))
164
 }
167
 }
165
 
168
 
166
 export const getAppList = () => async dispatch => {
169
 export const getAppList = () => async dispatch => {

+ 3 - 2
src/action-creator.sync.js Просмотреть файл

12
   ({ type: `Update/${USER_ROLE}/SubscriptionNotif`, workspaceId, subscriptionNotif })
12
   ({ type: `Update/${USER_ROLE}/SubscriptionNotif`, workspaceId, subscriptionNotif })
13
 
13
 
14
 export const WORKSPACE = 'Workspace'
14
 export const WORKSPACE = 'Workspace'
15
-export const updateWorkspaceData = workspace => ({ type: `Update/${WORKSPACE}`, workspace })
15
+export const setWorkspaceData = (workspace, filterStr = '') => ({ type: `Set/${WORKSPACE}`, workspace, filterStr })
16
+export const updateWorkspaceFilter = filterList => ({ type: `Update/${WORKSPACE}/Filter`, filterList })
16
 
17
 
17
 export const WORKSPACE_LIST = 'WorkspaceList'
18
 export const WORKSPACE_LIST = 'WorkspaceList'
18
 export const updateWorkspaceListData = workspaceList => ({ type: `Update/${WORKSPACE_LIST}`, workspaceList })
19
 export const updateWorkspaceListData = workspaceList => ({ type: `Update/${WORKSPACE_LIST}`, workspaceList })
19
-export const setWorkspaceListisOpenInSidebar = (workspaceId, isOpenInSidebar) => ({ type: `Set/${WORKSPACE_LIST}/isOpenInSidebar`, workspaceId, isOpenInSidebar })
20
+export const setWorkspaceListIsOpenInSidebar = (workspaceId, isOpenInSidebar) => ({ type: `Set/${WORKSPACE_LIST}/isOpenInSidebar`, workspaceId, isOpenInSidebar })
20
 
21
 
21
 export const FILE_CONTENT = 'FileContent'
22
 export const FILE_CONTENT = 'FileContent'
22
 export const setActiveFileContentActive = file => ({ type: `Set/${FILE_CONTENT}/Active`, file })
23
 export const setActiveFileContentActive = file => ({ type: `Set/${FILE_CONTENT}/Active`, file })

+ 20 - 59
src/component/Sidebar/WorkspaceListItem.jsx Просмотреть файл

1
 import React from 'react'
1
 import React from 'react'
2
-// import classnames from 'classnames'
2
+import classnames from 'classnames'
3
+import { translate } from 'react-i18next'
3
 import PropTypes from 'prop-types'
4
 import PropTypes from 'prop-types'
4
 import AnimateHeight from 'react-animate-height'
5
 import AnimateHeight from 'react-animate-height'
5
 
6
 
72
           </li>
73
           </li>
73
 
74
 
74
           <li className='sidebar__navigation__workspace__item__submenu__dropdown'>
75
           <li className='sidebar__navigation__workspace__item__submenu__dropdown'>
75
-
76
             <div className='dropdown__icon'>
76
             <div className='dropdown__icon'>
77
               <i className='fa fa-signal dashboard-color' />
77
               <i className='fa fa-signal dashboard-color' />
78
             </div>
78
             </div>
86
             </div>
86
             </div>
87
           </li>
87
           </li>
88
 
88
 
89
-          <li className='sidebar__navigation__workspace__item__submenu__dropdown'>
90
-
91
-            <div className='dropdown__icon'>
92
-              <i className='fa fa-list-ul task-color' />
93
-            </div>
94
-
95
-            <div className='sidebar__navigation__workspace__item__submenu__dropdown__showdropdown'>
96
-
97
-              <div className='dropdown__title' id='navbarDropdown'>
98
-                <div className='dropdown__title__text'>
99
-                  Liste de tâches
100
-                </div>
101
-              </div>
102
-            </div>
103
-          </li>
104
-
105
-          <li className='sidebar__navigation__workspace__item__submenu__dropdown'>
106
-
107
-            <div className='dropdown__icon'>
108
-              <i className='fa fa-folder-o docandfile-color' />
109
-            </div>
110
-
111
-            <div
112
-              className='sidebar__navigation__workspace__item__submenu__dropdown__showdropdown'
113
-              aria-haspopup='true'
114
-              aria-expanded='false'
89
+          { Object.keys(props.app).map(a =>
90
+            <li
91
+              className={classnames('sidebar__navigation__workspace__item__submenu__dropdown', {'activeFilter': props.activeFilterList.includes(a)})}
92
+              onClick={() => props.onClickContentFilter(props.wsId, a)}
93
+              key={a}
115
             >
94
             >
116
-
117
-              <div className='dropdown__title' id='navbarDropdown'>
118
-                <div className='dropdown__title__text'>
119
-                  Documents & fichiers
120
-                </div>
95
+              <div className='dropdown__icon'>
96
+                <i className={classnames(props.app[a].icon)} style={{backgroudColor: props.app[a].color}} />
121
               </div>
97
               </div>
122
-            </div>
123
-          </li>
124
-
125
-          <li className='sidebar__navigation__workspace__item__submenu__dropdown'>
126
-
127
-            <div className='dropdown__icon'>
128
-              <i className='fa fa-comments talk-color' />
129
-            </div>
130
 
98
 
131
-            <div
132
-              className='sidebar__navigation__workspace__item__submenu__dropdown__showdropdown'
133
-              aria-haspopup='true'
134
-              aria-expanded='false'
135
-            >
99
+              <div className='sidebar__navigation__workspace__item__submenu__dropdown__showdropdown'>
136
 
100
 
137
-              <div className='dropdown__title' id='navbarDropdown'>
138
-                <div className='dropdown__title__text'>
139
-                  Discussions
101
+                <div className='dropdown__title' id='navbarDropdown'>
102
+                  <div className='dropdown__title__text'>
103
+                    { props.app[a].label[props.lang.id] }
104
+                  </div>
140
                 </div>
105
                 </div>
141
               </div>
106
               </div>
142
-            </div>
143
-          </li>
107
+            </li>
108
+          )}
144
 
109
 
145
           <li className='sidebar__navigation__workspace__item__submenu__dropdown'>
110
           <li className='sidebar__navigation__workspace__item__submenu__dropdown'>
146
 
111
 
148
               <i className='fa fa-calendar calendar-color' />
113
               <i className='fa fa-calendar calendar-color' />
149
             </div>
114
             </div>
150
 
115
 
151
-            <div
152
-              className='sidebar__navigation__workspace__item__submenu__dropdown__showdropdown'
153
-              aria-haspopup='true'
154
-              aria-expanded='false'
155
-            >
156
-
157
-              <div className='dropdown__title' id='navbarDropdown'>
116
+            <div className='sidebar__navigation__workspace__item__submenu__dropdown__showdropdown'>
117
+              <div className='dropdown__title'>
158
                 <div className='dropdown__title__text'>
118
                 <div className='dropdown__title__text'>
159
                   Calendrier
119
                   Calendrier
160
                 </div>
120
                 </div>
167
   )
127
   )
168
 }
128
 }
169
 
129
 
170
-export default WorkspaceListItem
130
+export default translate()(WorkspaceListItem)
171
 
131
 
172
 WorkspaceListItem.propTypes = {
132
 WorkspaceListItem.propTypes = {
173
   number: PropTypes.number.isRequired,
133
   number: PropTypes.number.isRequired,
174
   name: PropTypes.string.isRequired,
134
   name: PropTypes.string.isRequired,
135
+  app: PropTypes.object,
175
   onClickTitle: PropTypes.func,
136
   onClickTitle: PropTypes.func,
176
   onClickAllContent: PropTypes.func,
137
   onClickAllContent: PropTypes.func,
177
   isOpenInSidebar: PropTypes.bool
138
   isOpenInSidebar: PropTypes.bool

+ 20 - 15
src/container/Account.jsx Просмотреть файл

1
 import React from 'react'
1
 import React from 'react'
2
 import { connect } from 'react-redux'
2
 import { connect } from 'react-redux'
3
+import Sidebar from './Sidebar.jsx'
3
 import PageWrapper from '../component/common/layout/PageWrapper.jsx'
4
 import PageWrapper from '../component/common/layout/PageWrapper.jsx'
4
 import PageTitle from '../component/common/layout/PageTitle.jsx'
5
 import PageTitle from '../component/common/layout/PageTitle.jsx'
5
 import PageContent from '../component/common/layout/PageContent.jsx'
6
 import PageContent from '../component/common/layout/PageContent.jsx'
73
     })()
74
     })()
74
 
75
 
75
     return (
76
     return (
76
-      <PageWrapper customClass='account'>
77
-        <PageTitle
78
-          parentClass={'account'}
79
-          title={'Mon Compte'}
80
-        />
77
+      <div className='sidebarpagecontainer'>
78
+        <Sidebar />
81
 
79
 
82
-        <PageContent parentClass='account'>
83
-          <UserInfo user={this.props.user} />
80
+        <PageWrapper customClass='account'>
81
+          <PageTitle
82
+            parentClass={'account'}
83
+            title={'Mon Compte'}
84
+          />
85
+
86
+          <PageContent parentClass='account'>
87
+            <UserInfo user={this.props.user} />
84
 
88
 
85
-          <Delimiter customClass={'account__delimiter'} />
89
+            <Delimiter customClass={'account__delimiter'} />
86
 
90
 
87
-          <div className='account__userpreference'>
88
-            <MenuSubComponent subMenuList={this.state.subComponentMenu} onClickMenuItem={this.handleClickSubComponentMenuItem} />
91
+            <div className='account__userpreference'>
92
+              <MenuSubComponent subMenuList={this.state.subComponentMenu} onClickMenuItem={this.handleClickSubComponentMenuItem} />
89
 
93
 
90
-            <div className='account__userpreference__setting'>
91
-              { subComponent }
94
+              <div className='account__userpreference__setting'>
95
+                { subComponent }
96
+              </div>
92
             </div>
97
             </div>
93
-          </div>
94
 
98
 
95
-        </PageContent>
96
-      </PageWrapper>
99
+          </PageContent>
100
+        </PageWrapper>
101
+      </div>
97
     )
102
     )
98
   }
103
   }
99
 }
104
 }

+ 271 - 266
src/container/Dashboard.jsx Просмотреть файл

1
 import React, { Component } from 'react'
1
 import React, { Component } from 'react'
2
+import Sidebar from './Sidebar.jsx'
2
 import listMemberBtn from '../img/listmemberbtn.png'
3
 import listMemberBtn from '../img/listmemberbtn.png'
3
 import imgProfil from '../img/imgProfil.png'
4
 import imgProfil from '../img/imgProfil.png'
4
 
5
 
5
 class Dashboard extends Component {
6
 class Dashboard extends Component {
6
   render () {
7
   render () {
7
     return (
8
     return (
8
-      <div className='dashboard'>
9
-        <div className='container-fluid nopadding'>
10
-          <div className='pageTitleGeneric'>
11
-            <div className='pageTitleGeneric__title dashboard__title'>
12
-              Dashboard
13
-            </div>
14
-          </div>
15
-
16
-          <div className='dashboard__wkswrapper'>
17
-            <div className='dashboard__workspace'>
18
-              <div className='dashboard__workspace__title'>
19
-                Nouvelle ligne directive sur le nouveau design de Tracim
20
-              </div>
21
-
22
-              <div className='dashboard__workspace__detail'>
23
-                Ut in et sit adipisicing mollit amet ut exercitation proident laborum duis occaecat eu aute qui ut.
24
-                Dolore veniam eu consectetur occaecat est elit dolor nulla est ut amet do reprehenderit eiusmod tempor.
9
+      <div className='sidebarpagecontainer'>
10
+        <Sidebar />
11
+
12
+        <div className='dashboard'>
13
+          <div className='container-fluid nopadding'>
14
+            <div className='pageTitleGeneric'>
15
+              <div className='pageTitleGeneric__title dashboard__title'>
16
+                Dashboard
25
               </div>
17
               </div>
26
             </div>
18
             </div>
27
-            <div className='dashboard__userstatut'>
28
 
19
 
29
-              <div className='dashboard__userstatut__role'>
30
-                <div className='dashboard__userstatut__role__text'>
31
-                  Hi ! Alexi, vous êtes actuellement
32
-                </div>
33
-                <div className='dashboard__userstatut__role__rank'>
34
-                  <div className='dashboard__userstatut__role__rank__icon'>
35
-                    <i className='fa fa-graduation-cap' />
36
-                  </div>
37
-                  <div className='dashboard__userstatut__role__rank__rolename'>
38
-                    Gestionnaire de projet
39
-                  </div>
20
+            <div className='dashboard__wkswrapper'>
21
+              <div className='dashboard__workspace'>
22
+                <div className='dashboard__workspace__title'>
23
+                  Nouvelle ligne directive sur le nouveau design de Tracim
40
                 </div>
24
                 </div>
41
-              </div>
42
 
25
 
43
-              <div className='dashboard__userstatut__notification'>
44
-                <div className='dashboard__userstatut__notification__text'>
45
-                  Vous êtes abonné(e) aux notifications de ce workspace
46
-                </div>
47
-                <div className='dashboard__userstatut__notification__btn btn btn-primary'>
48
-                  Changer de statut
26
+                <div className='dashboard__workspace__detail'>
27
+                  Ut in et sit adipisicing mollit amet ut exercitation proident laborum duis occaecat eu aute qui ut.
28
+                  Dolore veniam eu consectetur occaecat est elit dolor nulla est ut amet do reprehenderit eiusmod tempor.
49
                 </div>
29
                 </div>
30
+              </div>
31
+              <div className='dashboard__userstatut'>
50
 
32
 
51
-                <div className='dashboard__userstatut__notification__subscribe dropdown'>
52
-                  <button className='dashboard__userstatut__notification__subscribe__btn btn btn-primary dropdown-toggle' type='button' id='dropdownMenuButton' data-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>
53
-                    Abonné(e)
54
-                  </button>
55
-                  <div className='dashboard__userstatut__notification__subscribe__submenu dropdown-menu'>
56
-                    <div className='dashboard__userstatut__notification__subscribe__submenu__item dropdown-item'>Abonné(e)
33
+                <div className='dashboard__userstatut__role'>
34
+                  <div className='dashboard__userstatut__role__text'>
35
+                    Hi ! Alexi, vous êtes actuellement
36
+                  </div>
37
+                  <div className='dashboard__userstatut__role__rank'>
38
+                    <div className='dashboard__userstatut__role__rank__icon'>
39
+                      <i className='fa fa-graduation-cap' />
57
                     </div>
40
                     </div>
58
-                    <div className='dashboard__userstatut__notification__subscribe__submenu__item dropdown-item dropdown-item'>Non Abonné(e)
41
+                    <div className='dashboard__userstatut__role__rank__rolename'>
42
+                      Gestionnaire de projet
59
                     </div>
43
                     </div>
60
                   </div>
44
                   </div>
61
                 </div>
45
                 </div>
62
-              </div>
63
-            </div>
64
-          </div>
65
 
46
 
66
-          <div className='dashboard__calltoaction'>
67
-            <div className='dashboard__calltoaction__button btnaction thread'>
68
-              <div className='dashboard__calltoaction__button__text'>
69
-                <div className='dashboard__calltoaction__button__text__icon'>
70
-                  <i className='fa fa-comments-o' />
71
-                </div>
72
-                <div className='dashboard__calltoaction__button__text__title'>
73
-                  Débuter une nouvelle discussion
74
-                </div>
75
-              </div>
76
-            </div>
47
+                <div className='dashboard__userstatut__notification'>
48
+                  <div className='dashboard__userstatut__notification__text'>
49
+                    Vous êtes abonné(e) aux notifications de ce workspace
50
+                  </div>
51
+                  <div className='dashboard__userstatut__notification__btn btn btn-primary'>
52
+                    Changer de statut
53
+                  </div>
77
 
54
 
78
-            <div className='dashboard__calltoaction__button btnaction writefile'>
79
-              <div className='dashboard__calltoaction__button__text'>
80
-                <div className='dashboard__calltoaction__button__text__icon'>
81
-                  <i className='fa fa-file-text-o' />
82
-                </div>
83
-                <div className='dashboard__calltoaction__button__text__title'>
84
-                  Rédiger un document
55
+                  <div className='dashboard__userstatut__notification__subscribe dropdown'>
56
+                    <button className='dashboard__userstatut__notification__subscribe__btn btn btn-primary dropdown-toggle' type='button' id='dropdownMenuButton' data-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>
57
+                      Abonné(e)
58
+                    </button>
59
+                    <div className='dashboard__userstatut__notification__subscribe__submenu dropdown-menu'>
60
+                      <div className='dashboard__userstatut__notification__subscribe__submenu__item dropdown-item'>Abonné(e)
61
+                      </div>
62
+                      <div className='dashboard__userstatut__notification__subscribe__submenu__item dropdown-item dropdown-item'>Non Abonné(e)
63
+                      </div>
64
+                    </div>
65
+                  </div>
85
                 </div>
66
                 </div>
86
               </div>
67
               </div>
87
             </div>
68
             </div>
88
 
69
 
89
-            <div className='dashboard__calltoaction__button btnaction importfile'>
90
-              <div className='dashboard__calltoaction__button__text'>
91
-                <div className='dashboard__calltoaction__button__text__icon'>
92
-                  <i className='fa fa-paperclip' />
93
-                </div>
94
-                <div className='dashboard__calltoaction__button__text__title'>
95
-                  Importer un fichier
70
+            <div className='dashboard__calltoaction'>
71
+              <div className='dashboard__calltoaction__button btnaction thread'>
72
+                <div className='dashboard__calltoaction__button__text'>
73
+                  <div className='dashboard__calltoaction__button__text__icon'>
74
+                    <i className='fa fa-comments-o' />
75
+                  </div>
76
+                  <div className='dashboard__calltoaction__button__text__title'>
77
+                    Débuter une nouvelle discussion
78
+                  </div>
96
                 </div>
79
                 </div>
97
               </div>
80
               </div>
98
-            </div>
99
 
81
 
100
-            <div className='dashboard__calltoaction__button btnaction calendar'>
101
-              <div className='dashboard__calltoaction__button__text'>
102
-                <div className='dashboard__calltoaction__button__text__icon'>
103
-                  <i className='fa fa-calendar' />
104
-                </div>
105
-                <div className='dashboard__calltoaction__button__text__title'>
106
-                  Voir le Calendrier
82
+              <div className='dashboard__calltoaction__button btnaction writefile'>
83
+                <div className='dashboard__calltoaction__button__text'>
84
+                  <div className='dashboard__calltoaction__button__text__icon'>
85
+                    <i className='fa fa-file-text-o' />
86
+                  </div>
87
+                  <div className='dashboard__calltoaction__button__text__title'>
88
+                    Rédiger un document
89
+                  </div>
107
                 </div>
90
                 </div>
108
               </div>
91
               </div>
109
-            </div>
110
 
92
 
111
-            <div className='dashboard__calltoaction__button btnaction explore'>
112
-              <div className='dashboard__calltoaction__button__text'>
113
-                <div className='dashboard__calltoaction__button__text__icon'>
114
-                  <i className='fa fa-folder-open-o' />
115
-                </div>
116
-                <div className='dashboard__calltoaction__button__text__title'>
117
-                  Explorer le Workspace
93
+              <div className='dashboard__calltoaction__button btnaction importfile'>
94
+                <div className='dashboard__calltoaction__button__text'>
95
+                  <div className='dashboard__calltoaction__button__text__icon'>
96
+                    <i className='fa fa-paperclip' />
97
+                  </div>
98
+                  <div className='dashboard__calltoaction__button__text__title'>
99
+                    Importer un fichier
100
+                  </div>
118
                 </div>
101
                 </div>
119
               </div>
102
               </div>
120
-            </div>
121
-          </div>
122
-
123
-          <div className='dashboard__wksinfo'>
124
-            <div className='dashboard__activity'>
125
-              <div className='dashboard__activity__header'>
126
-                <div className='dashboard__activity__header__title subTitle'>
127
-                  Activité récente
128
-                </div>
129
 
103
 
130
-                <div className='dashboard__activity__header__allread btn btn-primary'>
131
-                  Tout marquer comme lu
132
-                </div>
133
-              </div>
134
-              <div className='dashboard__activity__wrapper'>
135
-                <div className='dashboard__activity__workspace'>
136
-                  <div className='dashboard__activity__workspace__icon'>
137
-                    <i className='fa fa-comments-o' />
104
+              <div className='dashboard__calltoaction__button btnaction calendar'>
105
+                <div className='dashboard__calltoaction__button__text'>
106
+                  <div className='dashboard__calltoaction__button__text__icon'>
107
+                    <i className='fa fa-calendar' />
138
                   </div>
108
                   </div>
139
-                  <div className='dashboard__activity__workspace__name'>
140
-                    <span>Workspace 1</span>
109
+                  <div className='dashboard__calltoaction__button__text__title'>
110
+                    Voir le Calendrier
141
                   </div>
111
                   </div>
142
                 </div>
112
                 </div>
113
+              </div>
143
 
114
 
144
-                <div className='dashboard__activity__workspace'>
145
-                  <div className='dashboard__activity__workspace__icon'>
146
-                    <i className='fa fa-list-ul' />
115
+              <div className='dashboard__calltoaction__button btnaction explore'>
116
+                <div className='dashboard__calltoaction__button__text'>
117
+                  <div className='dashboard__calltoaction__button__text__icon'>
118
+                    <i className='fa fa-folder-open-o' />
147
                   </div>
119
                   </div>
148
-                  <div className='dashboard__activity__workspace__name'>
149
-                    Workspace 2
120
+                  <div className='dashboard__calltoaction__button__text__title'>
121
+                    Explorer le Workspace
150
                   </div>
122
                   </div>
151
                 </div>
123
                 </div>
124
+              </div>
125
+            </div>
152
 
126
 
153
-                <div className='dashboard__activity__workspace'>
154
-                  <div className='dashboard__activity__workspace__icon'>
155
-                    <i className='fa fa-list-ul' />
127
+            <div className='dashboard__wksinfo'>
128
+              <div className='dashboard__activity'>
129
+                <div className='dashboard__activity__header'>
130
+                  <div className='dashboard__activity__header__title subTitle'>
131
+                    Activité récente
156
                   </div>
132
                   </div>
157
-                  <div className='dashboard__activity__workspace__name'>
158
-                    Workspace 3
133
+
134
+                  <div className='dashboard__activity__header__allread btn btn-primary'>
135
+                    Tout marquer comme lu
159
                   </div>
136
                   </div>
160
                 </div>
137
                 </div>
161
-
162
-                <div className='dashboard__activity__workspace'>
163
-                  <div className='dashboard__activity__workspace__icon'>
164
-                    <i className='fa fa-file-text-o' />
138
+                <div className='dashboard__activity__wrapper'>
139
+                  <div className='dashboard__activity__workspace'>
140
+                    <div className='dashboard__activity__workspace__icon'>
141
+                      <i className='fa fa-comments-o' />
142
+                    </div>
143
+                    <div className='dashboard__activity__workspace__name'>
144
+                      <span>Workspace 1</span>
145
+                    </div>
165
                   </div>
146
                   </div>
166
-                  <div className='dashboard__activity__workspace__name'>
167
-                    <span>Workspace 4</span>
147
+
148
+                  <div className='dashboard__activity__workspace'>
149
+                    <div className='dashboard__activity__workspace__icon'>
150
+                      <i className='fa fa-list-ul' />
151
+                    </div>
152
+                    <div className='dashboard__activity__workspace__name'>
153
+                      Workspace 2
154
+                    </div>
168
                   </div>
155
                   </div>
169
-                </div>
170
 
156
 
171
-                <div className='dashboard__activity__workspace'>
172
-                  <div className='dashboard__activity__workspace__icon'>
173
-                    <i className='fa fa-comments-o' />
157
+                  <div className='dashboard__activity__workspace'>
158
+                    <div className='dashboard__activity__workspace__icon'>
159
+                      <i className='fa fa-list-ul' />
160
+                    </div>
161
+                    <div className='dashboard__activity__workspace__name'>
162
+                      Workspace 3
163
+                    </div>
174
                   </div>
164
                   </div>
175
-                  <div className='dashboard__activity__workspace__name'>
176
-                    <span>Workspace 5</span>
165
+
166
+                  <div className='dashboard__activity__workspace'>
167
+                    <div className='dashboard__activity__workspace__icon'>
168
+                      <i className='fa fa-file-text-o' />
169
+                    </div>
170
+                    <div className='dashboard__activity__workspace__name'>
171
+                      <span>Workspace 4</span>
172
+                    </div>
177
                   </div>
173
                   </div>
178
-                </div>
179
 
174
 
180
-                <div className='dashboard__activity__workspace'>
181
-                  <div className='dashboard__activity__workspace__icon'>
182
-                    <i className='fa fa-file-text-o' />
175
+                  <div className='dashboard__activity__workspace'>
176
+                    <div className='dashboard__activity__workspace__icon'>
177
+                      <i className='fa fa-comments-o' />
178
+                    </div>
179
+                    <div className='dashboard__activity__workspace__name'>
180
+                      <span>Workspace 5</span>
181
+                    </div>
183
                   </div>
182
                   </div>
184
-                  <div className='dashboard__activity__workspace__name'>
185
-                    Workspace 6
183
+
184
+                  <div className='dashboard__activity__workspace'>
185
+                    <div className='dashboard__activity__workspace__icon'>
186
+                      <i className='fa fa-file-text-o' />
187
+                    </div>
188
+                    <div className='dashboard__activity__workspace__name'>
189
+                      Workspace 6
190
+                    </div>
186
                   </div>
191
                   </div>
187
-                </div>
188
 
192
 
189
-                <div className='dashboard__activity__more d-flex flex-row-reverse'>
190
-                  <div className='dashboard__activity__more__btn btn btn-primary'>
191
-                    Voir plus
193
+                  <div className='dashboard__activity__more d-flex flex-row-reverse'>
194
+                    <div className='dashboard__activity__more__btn btn btn-primary'>
195
+                      Voir plus
196
+                    </div>
192
                   </div>
197
                   </div>
193
                 </div>
198
                 </div>
194
               </div>
199
               </div>
195
-            </div>
196
 
200
 
197
-            <div className='dashboard__memberlist'>
201
+              <div className='dashboard__memberlist'>
198
 
202
 
199
-              <div className='dashboard__memberlist__title subTitle'>
200
-                Liste des membres
201
-              </div>
203
+                <div className='dashboard__memberlist__title subTitle'>
204
+                  Liste des membres
205
+                </div>
202
 
206
 
203
-              <div className='dashboard__memberlist__wrapper'>
204
-                <ul className='dashboard__memberlist__list'>
205
-                  <li className='dashboard__memberlist__list__item'>
206
-                    <div className='dashboard__memberlist__list__item__avatar'>
207
-                      <img src={imgProfil} alt='avatar' />
208
-                    </div>
209
-                    <div className='dashboard__memberlist__list__item__info'>
210
-                      <div className='dashboard__memberlist__list__item__info__name'>
211
-                        Jean Dupont
207
+                <div className='dashboard__memberlist__wrapper'>
208
+                  <ul className='dashboard__memberlist__list'>
209
+                    <li className='dashboard__memberlist__list__item'>
210
+                      <div className='dashboard__memberlist__list__item__avatar'>
211
+                        <img src={imgProfil} alt='avatar' />
212
                       </div>
212
                       </div>
213
-                      <div className='dashboard__memberlist__list__item__info__role'>
214
-                        Responsable
213
+                      <div className='dashboard__memberlist__list__item__info'>
214
+                        <div className='dashboard__memberlist__list__item__info__name'>
215
+                          Jean Dupont
216
+                        </div>
217
+                        <div className='dashboard__memberlist__list__item__info__role'>
218
+                          Responsable
219
+                        </div>
215
                       </div>
220
                       </div>
216
-                    </div>
217
-                  </li>
221
+                    </li>
218
 
222
 
219
-                  <li className='dashboard__memberlist__list__item'>
220
-                    <div className='dashboard__memberlist__list__item__avatar'>
221
-                      <img src={imgProfil} alt='avatar' />
222
-                    </div>
223
-                    <div className='dashboard__memberlist__list__item__info'>
224
-                      <div className='dashboard__memberlist__list__item__info__name'>
225
-                        Aldwin Vinel
223
+                    <li className='dashboard__memberlist__list__item'>
224
+                      <div className='dashboard__memberlist__list__item__avatar'>
225
+                        <img src={imgProfil} alt='avatar' />
226
                       </div>
226
                       </div>
227
-                      <div className='dashboard__memberlist__list__item__info__role'>
228
-                        lecteur
227
+                      <div className='dashboard__memberlist__list__item__info'>
228
+                        <div className='dashboard__memberlist__list__item__info__name'>
229
+                          Aldwin Vinel
230
+                        </div>
231
+                        <div className='dashboard__memberlist__list__item__info__role'>
232
+                          lecteur
233
+                        </div>
229
                       </div>
234
                       </div>
230
-                    </div>
231
-                  </li>
235
+                    </li>
232
 
236
 
233
-                  <li className='dashboard__memberlist__list__item'>
234
-                    <div className='dashboard__memberlist__list__item__avatar'>
235
-                      <img src={imgProfil} alt='avatar' />
236
-                    </div>
237
-                    <div className='dashboard__memberlist__list__item__info'>
238
-                      <div className='dashboard__memberlist__list__item__info__name'>
239
-                        William Himme
237
+                    <li className='dashboard__memberlist__list__item'>
238
+                      <div className='dashboard__memberlist__list__item__avatar'>
239
+                        <img src={imgProfil} alt='avatar' />
240
                       </div>
240
                       </div>
241
-                      <div className='dashboard__memberlist__list__item__info__role'>
242
-                        contributeur
241
+                      <div className='dashboard__memberlist__list__item__info'>
242
+                        <div className='dashboard__memberlist__list__item__info__name'>
243
+                          William Himme
244
+                        </div>
245
+                        <div className='dashboard__memberlist__list__item__info__role'>
246
+                          contributeur
247
+                        </div>
243
                       </div>
248
                       </div>
244
-                    </div>
245
-                  </li>
249
+                    </li>
246
 
250
 
247
-                  <li className='dashboard__memberlist__list__item'>
248
-                    <div className='dashboard__memberlist__list__item__avatar'>
249
-                      <img src={imgProfil} alt='avatar' />
250
-                    </div>
251
-                    <div className='dashboard__memberlist__list__item__info'>
252
-                      <div className='dashboard__memberlist__list__item__info__name'>
253
-                        Yacine Lite
251
+                    <li className='dashboard__memberlist__list__item'>
252
+                      <div className='dashboard__memberlist__list__item__avatar'>
253
+                        <img src={imgProfil} alt='avatar' />
254
                       </div>
254
                       </div>
255
-                      <div className='dashboard__memberlist__list__item__info__role'>
256
-                        Gestionnaire de contenu
255
+                      <div className='dashboard__memberlist__list__item__info'>
256
+                        <div className='dashboard__memberlist__list__item__info__name'>
257
+                          Yacine Lite
258
+                        </div>
259
+                        <div className='dashboard__memberlist__list__item__info__role'>
260
+                          Gestionnaire de contenu
261
+                        </div>
257
                       </div>
262
                       </div>
258
-                    </div>
259
-                  </li>
263
+                    </li>
260
 
264
 
261
-                  <li className='dashboard__memberlist__list__item'>
262
-                    <div className='dashboard__memberlist__list__item__avatar'>
263
-                      <img src={imgProfil} alt='avatar' />
264
-                    </div>
265
-                    <div className='dashboard__memberlist__list__item__info'>
266
-                      <div className='dashboard__memberlist__list__item__info__name'>
267
-                        Yacine Lite
265
+                    <li className='dashboard__memberlist__list__item'>
266
+                      <div className='dashboard__memberlist__list__item__avatar'>
267
+                        <img src={imgProfil} alt='avatar' />
268
                       </div>
268
                       </div>
269
-                      <div className='dashboard__memberlist__list__item__info__role'>
270
-                        Gestionnaire de contenu
269
+                      <div className='dashboard__memberlist__list__item__info'>
270
+                        <div className='dashboard__memberlist__list__item__info__name'>
271
+                          Yacine Lite
272
+                        </div>
273
+                        <div className='dashboard__memberlist__list__item__info__role'>
274
+                          Gestionnaire de contenu
275
+                        </div>
271
                       </div>
276
                       </div>
272
-                    </div>
273
-                  </li>
277
+                    </li>
274
 
278
 
275
-                  <li className='dashboard__memberlist__list__item'>
276
-                    <div className='dashboard__memberlist__list__item__avatar'>
277
-                      <img src={imgProfil} alt='avatar' />
278
-                    </div>
279
-                    <div className='dashboard__memberlist__list__item__info'>
280
-                      <div className='dashboard__memberlist__list__item__info__name'>
281
-                        Yacine Lite
279
+                    <li className='dashboard__memberlist__list__item'>
280
+                      <div className='dashboard__memberlist__list__item__avatar'>
281
+                        <img src={imgProfil} alt='avatar' />
282
                       </div>
282
                       </div>
283
-                      <div className='dashboard__memberlist__list__item__info__role'>
284
-                        Gestionnaire de contenu
283
+                      <div className='dashboard__memberlist__list__item__info'>
284
+                        <div className='dashboard__memberlist__list__item__info__name'>
285
+                          Yacine Lite
286
+                        </div>
287
+                        <div className='dashboard__memberlist__list__item__info__role'>
288
+                          Gestionnaire de contenu
289
+                        </div>
285
                       </div>
290
                       </div>
286
-                    </div>
287
-                  </li>
291
+                    </li>
288
 
292
 
289
-                </ul>
290
-                <div className='dashboard__memberlist__btnadd'>
291
-                  <div className='dashboard__memberlist__btnadd__button'>
292
-                    <div className='dashboard__memberlist__btnadd__button__avatar'>
293
-                      <img src={listMemberBtn} alt='avatar' />
294
-                    </div>
295
-                    <div className='dashboard__memberlist__btnadd__button__text'>
296
-                       Ajouter un membre
293
+                  </ul>
294
+                  <div className='dashboard__memberlist__btnadd'>
295
+                    <div className='dashboard__memberlist__btnadd__button'>
296
+                      <div className='dashboard__memberlist__btnadd__button__avatar'>
297
+                        <img src={listMemberBtn} alt='avatar' />
298
+                      </div>
299
+                      <div className='dashboard__memberlist__btnadd__button__text'>
300
+                         Ajouter un membre
301
+                      </div>
297
                     </div>
302
                     </div>
298
                   </div>
303
                   </div>
299
-                </div>
300
 
304
 
301
-                <form className='dashboard__memberlist__addmember'>
302
-                  <input type='text' className='dashboard__memberlist__addmember__name form-control' placeholder='Name' />
303
-                  <div className='dashboard__memberlist__addmember__role'>
304
-                    <div className='dashboard__memberlist__addmember__role__dropdown dropdown'>
305
-                      <button className='dashboard__memberlist__addmember__role__dropdown__button btn btn-primary dropdown-toggle' type='button' id='dropdownMenuButton' data-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>
306
-                        Rôle du membre
307
-                      </button>
308
-                      <div className='dashboard__memberlist__addmember__role__dropdown__submenu dropdown-menu'>
309
-                        <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item dropdown-item'>
310
-                          <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item__icon'>
311
-                            <i className='fa fa-eye' />
305
+                  <form className='dashboard__memberlist__addmember'>
306
+                    <input type='text' className='dashboard__memberlist__addmember__name form-control' placeholder='Name' />
307
+                    <div className='dashboard__memberlist__addmember__role'>
308
+                      <div className='dashboard__memberlist__addmember__role__dropdown dropdown'>
309
+                        <button className='dashboard__memberlist__addmember__role__dropdown__button btn btn-primary dropdown-toggle' type='button' id='dropdownMenuButton' data-toggle='dropdown' aria-haspopup='true' aria-expanded='false'>
310
+                          Rôle du membre
311
+                        </button>
312
+                        <div className='dashboard__memberlist__addmember__role__dropdown__submenu dropdown-menu'>
313
+                          <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item dropdown-item'>
314
+                            <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item__icon'>
315
+                              <i className='fa fa-eye' />
316
+                            </div>
317
+                            Lecteur
312
                           </div>
318
                           </div>
313
-                          Lecteur
314
-                        </div>
315
-                        <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item dropdown-item'>
316
-                          <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item__icon'>
317
-                            <i className='fa fa-pencil' />
319
+                          <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item dropdown-item'>
320
+                            <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item__icon'>
321
+                              <i className='fa fa-pencil' />
322
+                            </div>
323
+                            contributeur
318
                           </div>
324
                           </div>
319
-                          contributeur
320
-                        </div>
321
-                        <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item dropdown-item'>
322
-                          <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item__icon'>
323
-                            <i className='fa fa-graduation-cap' />
325
+                          <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item dropdown-item'>
326
+                            <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item__icon'>
327
+                              <i className='fa fa-graduation-cap' />
328
+                            </div>
329
+                            Gestionnaire de contenu
324
                           </div>
330
                           </div>
325
-                          Gestionnaire de contenu
326
-                        </div>
327
-                        <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item dropdown-item'>
328
-                          <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item__icon'>
329
-                            <i className='fa fa-gavel' />
331
+                          <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item dropdown-item'>
332
+                            <div className='dashboard__memberlist__addmember__role__dropdown__submenu__item__icon'>
333
+                              <i className='fa fa-gavel' />
334
+                            </div>
335
+                            Responsable
330
                           </div>
336
                           </div>
331
-                          Responsable
332
                         </div>
337
                         </div>
333
                       </div>
338
                       </div>
334
                     </div>
339
                     </div>
335
-                  </div>
336
-                  <input type='submit' className='dashboard__memberlist__addmember__submitbtn' />
337
-                </form>
340
+                    <input type='submit' className='dashboard__memberlist__addmember__submitbtn' />
341
+                  </form>
338
 
342
 
343
+                </div>
339
               </div>
344
               </div>
340
             </div>
345
             </div>
341
-          </div>
342
 
346
 
343
-          <div className='dashboard__webdav genericWebdav'>
347
+            <div className='dashboard__webdav genericWebdav'>
344
 
348
 
345
-            <div className='dashboard__webdav__btn genericWebdav__btn'>
346
-              <div className='dashboard__webdav__btn__icon genericWebdav__btn__icon'>
347
-                <i className='fa fa-windows' />
348
-              </div>
349
+              <div className='dashboard__webdav__btn genericWebdav__btn'>
350
+                <div className='dashboard__webdav__btn__icon genericWebdav__btn__icon'>
351
+                  <i className='fa fa-windows' />
352
+                </div>
349
 
353
 
350
-              <div className='dashboard__webdav__btn__text genericWebdav__btn__text'>
351
-                Implémenter Tracim dans votre explorateur
354
+                <div className='dashboard__webdav__btn__text genericWebdav__btn__text'>
355
+                  Implémenter Tracim dans votre explorateur
356
+                </div>
352
               </div>
357
               </div>
353
-            </div>
354
 
358
 
355
-            <div className='dashboard__webdav__information genericWebdav__info'>
356
-              <div className='dashboard__webdav__information__text genericWebdav__info__text'>
357
-                Lorem ipsum dolore dolore laborum exercitation et deserunt ad ullamco nostrud dolore magna in proident elit amet do eu ut officia anim magna dolore adipisicing aliqua qui reprehenderit laborum labore tempor consectetur ut pariatur deserunt nostrud.
358
-              </div>
359
+              <div className='dashboard__webdav__information genericWebdav__info'>
360
+                <div className='dashboard__webdav__information__text genericWebdav__info__text'>
361
+                  Lorem ipsum dolore dolore laborum exercitation et deserunt ad ullamco nostrud dolore magna in proident elit amet do eu ut officia anim magna dolore adipisicing aliqua qui reprehenderit laborum labore tempor consectetur ut pariatur deserunt nostrud.
362
+                </div>
359
 
363
 
360
-              <div className='dashboard__webdav__information__link genericWebdav__info__link'>
361
-                http://algoo.trac.im/webdav/
364
+                <div className='dashboard__webdav__information__link genericWebdav__info__link'>
365
+                  http://algoo.trac.im/webdav/
366
+                </div>
362
               </div>
367
               </div>
363
-            </div>
364
 
368
 
369
+            </div>
365
           </div>
370
           </div>
366
         </div>
371
         </div>
367
       </div>
372
       </div>

+ 45 - 9
src/container/Sidebar.jsx Просмотреть файл

4
 import { translate } from 'react-i18next'
4
 import { translate } from 'react-i18next'
5
 import WorkspaceListItem from '../component/Sidebar/WorkspaceListItem.jsx'
5
 import WorkspaceListItem from '../component/Sidebar/WorkspaceListItem.jsx'
6
 import { getWorkspaceList } from '../action-creator.async.js'
6
 import { getWorkspaceList } from '../action-creator.async.js'
7
-import { setWorkspaceListisOpenInSidebar } from '../action-creator.sync.js'
7
+import {
8
+  setWorkspaceListIsOpenInSidebar,
9
+  updateWorkspaceFilter
10
+} from '../action-creator.sync.js'
8
 import { PAGE_NAME } from '../helper.js'
11
 import { PAGE_NAME } from '../helper.js'
9
 
12
 
10
 class Sidebar extends React.Component {
13
 class Sidebar extends React.Component {
11
   constructor (props) {
14
   constructor (props) {
12
     super(props)
15
     super(props)
13
     this.state = {
16
     this.state = {
14
-      firstWsOpen: false
17
+      firstWsOpen: false,
18
+      workspaceIdInUrl: parseInt(props.match.params.idws)
15
     }
19
     }
16
   }
20
   }
17
 
21
 
18
   componentDidMount () {
22
   componentDidMount () {
23
+    const { workspaceIdInUrl } = this.state
19
     const { user, workspaceList, dispatch } = this.props
24
     const { user, workspaceList, dispatch } = this.props
20
-    user.id !== -1 && workspaceList.length === 0 && dispatch(getWorkspaceList(user.id))
25
+    user.id !== -1 && workspaceList.length === 0 && dispatch(getWorkspaceList(user.id, workspaceIdInUrl))
21
   }
26
   }
22
 
27
 
23
-  componentDidUpdate (prevProps) {
24
-    const { user, dispatch } = this.props
25
-    user.id !== -1 && prevProps.user.id !== user.id && dispatch(getWorkspaceList(user.id))
28
+  componentDidUpdate (prevProps, prevState) {
29
+    const { user, match, dispatch } = this.props
30
+
31
+    const newWorkspaceId = parseInt(match.params.idws)
32
+    prevState.workspaceIdInUrl !== newWorkspaceId && this.setState({workspaceIdInUrl: newWorkspaceId})
33
+
34
+    user.id !== -1 && prevProps.user.id !== user.id && dispatch(getWorkspaceList(user.id, newWorkspaceId))
26
   }
35
   }
27
 
36
 
28
-  handleClickWorkspace = (wsId, newisOpenInSidebar) => this.props.dispatch(setWorkspaceListisOpenInSidebar(wsId, newisOpenInSidebar))
37
+  handleClickWorkspace = (wsId, newIsOpenInSidebar) => this.props.dispatch(setWorkspaceListIsOpenInSidebar(wsId, newIsOpenInSidebar))
29
 
38
 
30
   handleClickAllContent = wsId => {
39
   handleClickAllContent = wsId => {
31
     this.props.history.push(`${PAGE_NAME.WS_CONTENT}/${wsId}`)
40
     this.props.history.push(`${PAGE_NAME.WS_CONTENT}/${wsId}`)
32
   }
41
   }
33
 
42
 
43
+  handleClickContentFilter = (wsId, filter) => {
44
+    const { workspaceIdInUrl } = this.state
45
+    const { workspace, history, dispatch } = this.props
46
+
47
+    const filterList = (() => {
48
+      if (wsId !== workspaceIdInUrl) return [filter] // load a different workspace => reset filters
49
+
50
+      if (workspace.filter.includes(filter)) return workspace.filter.filter(f => f !== filter) // remove the filter
51
+      else return [...workspace.filter, filter] // add the filter
52
+    })()
53
+
54
+    dispatch(updateWorkspaceFilter(filterList))
55
+
56
+    history.push(`${PAGE_NAME.WS_CONTENT}/${wsId}/${filterList.join(';')}`) // workspace.filter gets updated on react redraw from match.params
57
+  }
58
+
34
   render () {
59
   render () {
35
-    const { workspaceList, t } = this.props
60
+    const { workspaceIdInUrl } = this.state
61
+    const { activeLang, workspace, workspaceList, app, t } = this.props
36
 
62
 
37
     return (
63
     return (
38
       <div className='sidebar d-none d-lg-block'>
64
       <div className='sidebar d-none d-lg-block'>
43
                 number={++i}
69
                 number={++i}
44
                 wsId={ws.id}
70
                 wsId={ws.id}
45
                 name={ws.title}
71
                 name={ws.title}
72
+                app={app}
73
+                lang={activeLang}
74
+                activeFilterList={ws.id === workspaceIdInUrl ? workspace.filter : []}
46
                 isOpenInSidebar={ws.isOpenInSidebar}
75
                 isOpenInSidebar={ws.isOpenInSidebar}
47
                 onClickTitle={() => this.handleClickWorkspace(ws.id, !ws.isOpenInSidebar)}
76
                 onClickTitle={() => this.handleClickWorkspace(ws.id, !ws.isOpenInSidebar)}
48
                 onClickAllContent={this.handleClickAllContent}
77
                 onClickAllContent={this.handleClickAllContent}
78
+                onClickContentFilter={this.handleClickContentFilter}
49
                 key={ws.id}
79
                 key={ws.id}
50
               />
80
               />
51
             )}
81
             )}
62
   }
92
   }
63
 }
93
 }
64
 
94
 
65
-const mapStateToProps = ({ user, workspaceList }) => ({ user, workspaceList })
95
+const mapStateToProps = ({ lang, user, workspace, workspaceList, app }) => ({
96
+  activeLang: lang.find(l => l.active) || {id: 'en'},
97
+  user,
98
+  workspace,
99
+  workspaceList,
100
+  app
101
+})
66
 export default withRouter(connect(mapStateToProps)(translate()(Sidebar)))
102
 export default withRouter(connect(mapStateToProps)(translate()(Sidebar)))

+ 6 - 20
src/container/Tracim.jsx Просмотреть файл

2
 import { connect } from 'react-redux'
2
 import { connect } from 'react-redux'
3
 import Footer from '../component/Footer.jsx'
3
 import Footer from '../component/Footer.jsx'
4
 import Header from './Header.jsx'
4
 import Header from './Header.jsx'
5
-import Sidebar from './Sidebar.jsx'
6
 import Login from './Login.jsx'
5
 import Login from './Login.jsx'
7
 import Dashboard from './Dashboard.jsx'
6
 import Dashboard from './Dashboard.jsx'
8
 import Account from './Account.jsx'
7
 import Account from './Account.jsx'
20
 } from '../action-creator.async.js'
19
 } from '../action-creator.async.js'
21
 
20
 
22
 class Tracim extends React.Component {
21
 class Tracim extends React.Component {
23
-  componentDidMount = () => {
22
+  componentDidMount () {
24
     this.props.dispatch(getIsUserConnected())
23
     this.props.dispatch(getIsUserConnected())
25
     this.props.dispatch(getLangList())
24
     this.props.dispatch(getLangList())
26
   }
25
   }
27
 
26
 
28
   render () {
27
   render () {
29
-    const { user, location } = this.props
30
-
31
-    const SidebarWrapper = props => props.locationPath !== '/login'
32
-      ? (
33
-        <div className='sidebarpagecontainer'>
34
-          <Sidebar />
35
-          {props.children}
36
-        </div>
37
-      )
38
-      : props.children
28
+    const { user } = this.props
39
 
29
 
40
     return (
30
     return (
41
       <div className='tracim'>
31
       <div className='tracim'>
47
             <div className='tracim__content'>
37
             <div className='tracim__content'>
48
               <Route path={PAGE_NAME.LOGIN} component={Login} />
38
               <Route path={PAGE_NAME.LOGIN} component={Login} />
49
 
39
 
50
-              <SidebarWrapper locationPath={location.pathname}>
51
-
52
-                <PrivateRoute exact path={PAGE_NAME.HOME} component={WorkspaceContent} />
53
-                <PrivateRoute path={`${PAGE_NAME.WS_CONTENT}/:idws`} component={WorkspaceContent} />
54
-                <PrivateRoute exact path={PAGE_NAME.ACCOUNT} component={Account} />
55
-                <PrivateRoute exact path={PAGE_NAME.DASHBOARD} component={Dashboard} />
56
-
57
-              </SidebarWrapper>
40
+              <PrivateRoute exact path={PAGE_NAME.HOME} component={WorkspaceContent} />
41
+              <PrivateRoute path={`${PAGE_NAME.WS_CONTENT}/:idws/:filter?`} component={WorkspaceContent} />
42
+              <PrivateRoute exact path={PAGE_NAME.ACCOUNT} component={Account} />
43
+              <PrivateRoute exact path={PAGE_NAME.DASHBOARD} component={Dashboard} />
58
 
44
 
59
               <Footer />
45
               <Footer />
60
             </div>
46
             </div>

+ 62 - 48
src/container/WorkspaceContent.jsx Просмотреть файл

1
 import React from 'react'
1
 import React from 'react'
2
 import { connect } from 'react-redux'
2
 import { connect } from 'react-redux'
3
 import appFactory from '../appFactory.js'
3
 import appFactory from '../appFactory.js'
4
+import Sidebar from './Sidebar.jsx'
4
 import Folder from '../component/Workspace/Folder.jsx'
5
 import Folder from '../component/Workspace/Folder.jsx'
5
 import FileItem from '../component/Workspace/FileItem.jsx'
6
 import FileItem from '../component/Workspace/FileItem.jsx'
6
 import FileItemHeader from '../component/Workspace/FileItemHeader.jsx'
7
 import FileItemHeader from '../component/Workspace/FileItemHeader.jsx'
24
   componentDidMount () {
25
   componentDidMount () {
25
     const { workspaceList, app, match, dispatch } = this.props
26
     const { workspaceList, app, match, dispatch } = this.props
26
 
27
 
27
-    if (match.params.idws !== undefined) dispatch(getWorkspaceContent(match.params.idws))
28
-    else if (workspaceList.length > 0) dispatch(getWorkspaceContent(workspaceList[0].id)) // load first ws if none specified
28
+    if (match.params.idws !== undefined) dispatch(getWorkspaceContent(match.params.idws, match.params.filter))
29
+    else if (workspaceList.length > 0) dispatch(getWorkspaceContent(workspaceList[0].id, match.params.filter)) // load first ws if none specified
29
 
30
 
30
-    Object.keys(app).length === 0 && dispatch(getAppList())
31
+    if (Object.keys(app).length === 0) dispatch(getAppList())
31
   }
32
   }
32
 
33
 
33
   componentDidUpdate (prevProps) {
34
   componentDidUpdate (prevProps) {
34
     const { workspace, workspaceList, match, dispatch } = this.props
35
     const { workspace, workspaceList, match, dispatch } = this.props
36
+    console.log('workspaceContent update', prevProps, this.props)
35
 
37
 
36
     // if a workspace is already loaded and the idws in url hasn't changed, do nothing
38
     // if a workspace is already loaded and the idws in url hasn't changed, do nothing
37
     if (workspace.id !== -1 && prevProps.match.params.idws === match.params.idws) return
39
     if (workspace.id !== -1 && prevProps.match.params.idws === match.params.idws) return
38
 
40
 
39
     // if the idws in url has changed, load the new workspace
41
     // if the idws in url has changed, load the new workspace
40
-    if (match.params.idws !== undefined) dispatch(getWorkspaceContent(match.params.idws))
42
+    if (match.params.idws !== undefined) dispatch(getWorkspaceContent(match.params.idws, match.params.filter))
41
     // else bellow is for loading url PAGE_NAME.HOME (without an idws), when workspaceList is loaded, load the first workspace
43
     // else bellow is for loading url PAGE_NAME.HOME (without an idws), when workspaceList is loaded, load the first workspace
42
-    else if (match.params.idws === undefined && workspace.id === -1 && workspaceList.length > 0) dispatch(getWorkspaceContent(workspaceList[0].id))
44
+    else if (workspace.id === -1 && workspaceList.length > 0) dispatch(getWorkspaceContent(workspaceList[0].id))
43
   }
45
   }
44
 
46
 
45
   handleClickContentItem = content => {
47
   handleClickContentItem = content => {
48
     // dispatch(setActiveFileContentActive(content))
50
     // dispatch(setActiveFileContentActive(content))
49
   }
51
   }
50
 
52
 
53
+  filterWorkspaceContent = (contentList, filter) => filter.length === 0
54
+    ? contentList
55
+    : contentList.filter(c => c.type === 'folder' || filter.includes(c.type)) // keep unfiltered files and folders
56
+      .map(c => c.type !== 'folder' ? c : {...c, content: this.filterWorkspaceContent(c.content, filter)}) // recursively filter folder content
57
+      .filter(c => c.type !== 'folder' || c.content.length > 0) // remove empty folder
58
+
51
   render () {
59
   render () {
52
     const { workspace, app } = this.props
60
     const { workspace, app } = this.props
53
 
61
 
62
+    const filteredWorkspaceContent = this.filterWorkspaceContent(workspace.content, workspace.filter)
63
+
54
     return (
64
     return (
55
-      <PageWrapper customeClass='workspace'>
56
-        <PageTitle
57
-          parentClass='workspace__header'
58
-          customClass='justify-content-between'
59
-          title={workspace.title}
60
-        >
61
-          <DropdownCreateButton parentClass='workspace__header__btnaddworkspace' />
62
-        </PageTitle>
63
-
64
-        <PageContent parentClass='workspace__content'>
65
-          <div className='workspace__content__fileandfolder folder__content active'>
66
-            <FileItemHeader />
67
-
68
-            { workspace.content.map((c, i) => c.type === 'folder'
69
-              ? (
70
-                <Folder
71
-                  app={app}
72
-                  folderData={c}
73
-                  onClickItem={this.handleClickContentItem}
74
-                  isLast={i === workspace.content.length - 1}
75
-                  key={c.id}
76
-                />
77
-              )
78
-              : (
79
-                <FileItem
80
-                  name={c.title}
81
-                  type={c.type}
82
-                  icon={(app[c.type] || {icon: ''}).icon}
83
-                  status={c.status}
84
-                  onClickItem={() => this.handleClickContentItem(c)}
85
-                  isLast={i === workspace.content.length - 1}
86
-                  key={c.id}
87
-                />
88
-              )
89
-            )}
90
-          </div>
91
-
92
-          <DropdownCreateButton customClass='workspace__content__button mb-5' />
93
-
94
-          <div id='appContainer' />
95
-        </PageContent>
96
-
97
-      </PageWrapper>
65
+      <div className='sidebarpagecontainer'>
66
+        <Sidebar />
67
+
68
+        <PageWrapper customeClass='workspace'>
69
+          <PageTitle
70
+            parentClass='workspace__header'
71
+            customClass='justify-content-between'
72
+            title={workspace.title}
73
+          >
74
+            <DropdownCreateButton parentClass='workspace__header__btnaddworkspace' />
75
+          </PageTitle>
76
+
77
+          <PageContent parentClass='workspace__content'>
78
+            <div className='workspace__content__fileandfolder folder__content active'>
79
+              <FileItemHeader />
80
+
81
+              { filteredWorkspaceContent.map((c, i) => c.type === 'folder'
82
+                ? (
83
+                  <Folder
84
+                    app={app}
85
+                    folderData={c}
86
+                    onClickItem={this.handleClickContentItem}
87
+                    isLast={i === filteredWorkspaceContent.length - 1}
88
+                    key={c.id}
89
+                  />
90
+                )
91
+                : (
92
+                  <FileItem
93
+                    name={c.title}
94
+                    type={c.type}
95
+                    icon={(app[c.type] || {icon: ''}).icon}
96
+                    status={c.status}
97
+                    onClickItem={() => this.handleClickContentItem(c)}
98
+                    isLast={i === filteredWorkspaceContent.length - 1}
99
+                    key={c.id}
100
+                  />
101
+                )
102
+              )}
103
+            </div>
104
+
105
+            <DropdownCreateButton customClass='workspace__content__button mb-5' />
106
+
107
+            <div id='appContainer' />
108
+          </PageContent>
109
+
110
+        </PageWrapper>
111
+      </div>
98
     )
112
     )
99
   }
113
   }
100
 }
114
 }

+ 1 - 1
src/css/FileItem.styl Просмотреть файл

1
 .file
1
 .file
2
   display flex
2
   display flex
3
   border-bottom 0
3
   border-bottom 0
4
+  cursor pointer
4
   &:hover
5
   &:hover
5
     background-color files-hover
6
     background-color files-hover
6
   &__type
7
   &__type
10
     display flex
11
     display flex
11
     justify-content space-between
12
     justify-content space-between
12
     padding 15px 5px
13
     padding 15px 5px
13
-    cursor pointer
14
     &__text
14
     &__text
15
       font-size 17px
15
       font-size 17px
16
     &__icons
16
     &__icons

+ 4 - 1
src/css/Sidebar.styl Просмотреть файл

28
   flex-grow 0
28
   flex-grow 0
29
   height 100%
29
   height 100%
30
   font-size 18px
30
   font-size 18px
31
-  background-color rgba(253,253,253,0.3)
31
+  background-color rgba(253, 253, 253, 0.3)
32
 
32
 
33
 .sidebar
33
 .sidebar
34
   &__btnnewworkspace
34
   &__btnnewworkspace
96
               padding 10px 15px
96
               padding 10px 15px
97
               min-width 50px
97
               min-width 50px
98
               leftside()
98
               leftside()
99
+            &.activeFilter
100
+              .dropdown__icon
101
+                background-color rgba(253, 253, 253, 0.8)

+ 10 - 3
src/reducer/workspace.js Просмотреть файл

13
   id: -1,
13
   id: -1,
14
   title: '',
14
   title: '',
15
   ownerId: '',
15
   ownerId: '',
16
-  content: []
16
+  content: [],
17
+  filter: []
17
 }, action) {
18
 }, action) {
18
   switch (action.type) {
19
   switch (action.type) {
19
-    case `Update/${WORKSPACE}`:
20
-      return serializeWorkspace(action.workspace)
20
+    case `Set/${WORKSPACE}`:
21
+      return {
22
+        ...serializeWorkspace(action.workspace),
23
+        filter: action.filterStr ? action.filterStr.split(';') : []
24
+      }
25
+
26
+    case `Update/${WORKSPACE}/Filter`:
27
+      return {...state, filter: action.filterList}
21
 
28
 
22
     default:
29
     default:
23
       return state
30
       return state