|
@@ -10,25 +10,39 @@ import {
|
10
|
10
|
getWorkspaceDetail,
|
11
|
11
|
getWorkspaceMemberList,
|
12
|
12
|
getWorkspaceRecentActivityList,
|
13
|
|
- getWorkspaceReadStatusList
|
|
13
|
+ getWorkspaceReadStatusList,
|
|
14
|
+ getUserKnownMember,
|
|
15
|
+ postWorkspaceMember,
|
|
16
|
+ putUserWorkspaceRead
|
14
|
17
|
} from '../action-creator.async.js'
|
15
|
18
|
import {
|
16
|
19
|
newFlashMessage,
|
17
|
20
|
setWorkspaceDetail,
|
18
|
21
|
setWorkspaceMemberList,
|
19
|
22
|
setWorkspaceRecentActivityList,
|
|
23
|
+ setWorkspaceRecentActivityForUserList,
|
20
|
24
|
setWorkspaceReadStatusList
|
21
|
25
|
} from '../action-creator.sync.js'
|
22
|
|
-import { ROLE } from '../helper.js'
|
|
26
|
+import { ROLE, PAGE } from '../helper.js'
|
|
27
|
+import UserStatus from '../component/Dashboard/UserStatus.jsx'
|
23
|
28
|
import ContentTypeBtn from '../component/Dashboard/ContentTypeBtn.jsx'
|
24
|
29
|
import RecentActivity from '../component/Dashboard/RecentActivity.jsx'
|
25
|
30
|
import MemberList from '../component/Dashboard/MemberList.jsx'
|
|
31
|
+import MoreInfo from '../component/Dashboard/MoreInfo.jsx'
|
26
|
32
|
|
27
|
33
|
class Dashboard extends React.Component {
|
28
|
34
|
constructor (props) {
|
29
|
35
|
super(props)
|
30
|
36
|
this.state = {
|
31
|
37
|
workspaceIdInUrl: props.match.params.idws ? parseInt(props.match.params.idws) : null, // this is used to avoid handling the parseInt everytime
|
|
38
|
+ newMember: {
|
|
39
|
+ id: '',
|
|
40
|
+ avatarUrl: '',
|
|
41
|
+ nameOrEmail: '',
|
|
42
|
+ // createAccount: false, // @TODO ask DA about this checkbox if it is still usefull (since backend handles it all)
|
|
43
|
+ role: ''
|
|
44
|
+ },
|
|
45
|
+ searchedKnownMemberList: [],
|
32
|
46
|
displayNewMemberDashboard: false,
|
33
|
47
|
displayNotifBtn: false,
|
34
|
48
|
displayWebdavBtn: false,
|
|
@@ -41,52 +55,126 @@ class Dashboard extends React.Component {
|
41
|
55
|
|
42
|
56
|
const fetchWorkspaceDetail = await props.dispatch(getWorkspaceDetail(props.user, state.workspaceIdInUrl))
|
43
|
57
|
switch (fetchWorkspaceDetail.status) {
|
44
|
|
- case 200:
|
45
|
|
- props.dispatch(setWorkspaceDetail(fetchWorkspaceDetail.json)); break
|
46
|
|
- default:
|
47
|
|
- props.dispatch(newFlashMessage(props.t('An error has happened while fetching workspace detail'), 'warning')); break
|
|
58
|
+ case 200: props.dispatch(setWorkspaceDetail(fetchWorkspaceDetail.json)); break
|
|
59
|
+ default: props.dispatch(newFlashMessage(`${props.t('An error has happened while fetching')} ${props.t('workspace detail')}`, 'warning')); break
|
48
|
60
|
}
|
|
61
|
+ this.loadMemberList()
|
|
62
|
+ this.loadRecentActivity()
|
|
63
|
+ }
|
|
64
|
+
|
|
65
|
+ loadMemberList = async () => {
|
|
66
|
+ const { props, state } = this
|
49
|
67
|
|
50
|
68
|
const fetchWorkspaceMemberList = await props.dispatch(getWorkspaceMemberList(props.user, state.workspaceIdInUrl))
|
51
|
69
|
switch (fetchWorkspaceMemberList.status) {
|
52
|
|
- case 200:
|
53
|
|
- props.dispatch(setWorkspaceMemberList(fetchWorkspaceMemberList.json)); break
|
54
|
|
- default:
|
55
|
|
- props.dispatch(newFlashMessage(props.t('An error has happened while fetching member list'), 'warning')); break
|
|
70
|
+ case 200: props.dispatch(setWorkspaceMemberList(fetchWorkspaceMemberList.json)); break
|
|
71
|
+ default: props.dispatch(newFlashMessage(`${props.t('An error has happened while fetching')} ${props.t('member list')}`, 'warning')); break
|
56
|
72
|
}
|
|
73
|
+ }
|
|
74
|
+
|
|
75
|
+ loadRecentActivity = async () => {
|
|
76
|
+ const { props, state } = this
|
57
|
77
|
|
58
|
78
|
const fetchWorkspaceRecentActivityList = await props.dispatch(getWorkspaceRecentActivityList(props.user, state.workspaceIdInUrl))
|
|
79
|
+ const fetchWorkspaceReadStatusList = await props.dispatch(getWorkspaceReadStatusList(props.user, state.workspaceIdInUrl))
|
|
80
|
+
|
59
|
81
|
switch (fetchWorkspaceRecentActivityList.status) {
|
60
|
|
- case 200:
|
61
|
|
- props.dispatch(setWorkspaceRecentActivityList(fetchWorkspaceRecentActivityList.json)); break
|
62
|
|
- default:
|
63
|
|
- props.dispatch(newFlashMessage(props.t('An error has happened while fetching recent activity list'), 'warning')); break
|
|
82
|
+ case 200: props.dispatch(setWorkspaceRecentActivityList(fetchWorkspaceRecentActivityList.json)); break
|
|
83
|
+ default: props.dispatch(newFlashMessage(`${props.t('An error has happened while fetching')} ${props.t('recent activity list')}`, 'warning')); break
|
64
|
84
|
}
|
65
|
85
|
|
66
|
|
- const fetchWorkspaceReadStatusList = await props.dispatch(getWorkspaceReadStatusList(props.user, state.workspaceIdInUrl))
|
67
|
86
|
switch (fetchWorkspaceReadStatusList.status) {
|
|
87
|
+ case 200: props.dispatch(setWorkspaceReadStatusList(fetchWorkspaceReadStatusList.json)); break
|
|
88
|
+ default: props.dispatch(newFlashMessage(`${props.t('An error has happened while fetching')} ${props.t('read status list')}`, 'warning')); break
|
|
89
|
+ }
|
|
90
|
+
|
|
91
|
+ const readStatusForUserList = fetchWorkspaceReadStatusList.json.filter(c => c.read_by_user).map(c => c.content_id)
|
|
92
|
+ const recentActivityForUserList = fetchWorkspaceRecentActivityList.json.filter(content => !readStatusForUserList.includes(content.content_id))
|
|
93
|
+
|
|
94
|
+ props.dispatch(setWorkspaceRecentActivityForUserList(recentActivityForUserList))
|
|
95
|
+ }
|
|
96
|
+
|
|
97
|
+ handleToggleNewMemberDashboard = () => this.setState(prevState => ({displayNewMemberDashboard: !prevState.displayNewMemberDashboard}))
|
|
98
|
+
|
|
99
|
+ handleToggleNotifBtn = () => this.setState(prevState => ({displayNotifBtn: !prevState.displayNotifBtn}))
|
|
100
|
+
|
|
101
|
+ handleToggleWebdavBtn = () => this.setState(prevState => ({displayWebdavBtn: !prevState.displayWebdavBtn}))
|
|
102
|
+
|
|
103
|
+ handleToggleCalendarBtn = () => this.setState(prevState => ({displayCalendarBtn: !prevState.displayCalendarBtn}))
|
|
104
|
+
|
|
105
|
+ handleClickRecentContent = (idContent, typeContent) => this.props.history.push(PAGE.WORKSPACE.CONTENT(this.props.curWs.id, typeContent, idContent))
|
|
106
|
+
|
|
107
|
+ handleClickMarkRecentActivityAsRead = async () => {
|
|
108
|
+ const { props } = this
|
|
109
|
+ const fetchUserWorkspaceAllRead = await props.dispatch(putUserWorkspaceRead(props.user, props.curWs.id))
|
|
110
|
+ switch (fetchUserWorkspaceAllRead.status) {
|
|
111
|
+ case 204: this.loadRecentActivity(); break
|
|
112
|
+ default: props.dispatch(newFlashMessage(`${props.t('An error has happened while fetching "mark all as read"')}`, 'warning')); break
|
|
113
|
+ }
|
|
114
|
+ }
|
|
115
|
+
|
|
116
|
+ handleClickSeeMore = async () => {
|
|
117
|
+ console.log('nyi')
|
|
118
|
+ }
|
|
119
|
+
|
|
120
|
+ handleSearchUser = async userNameToSearch => {
|
|
121
|
+ const { props } = this
|
|
122
|
+ const fetchUserKnownMemberList = await props.dispatch(getUserKnownMember(props.user, userNameToSearch))
|
|
123
|
+ switch (fetchUserKnownMemberList.status) {
|
68
|
124
|
case 200:
|
69
|
|
- props.dispatch(setWorkspaceReadStatusList(fetchWorkspaceReadStatusList.json)); break
|
|
125
|
+ this.setState({searchedKnownMemberList: fetchUserKnownMemberList.json}); break
|
70
|
126
|
default:
|
71
|
|
- props.dispatch(newFlashMessage(props.t('An error has happened while fetching read status list'), 'warning')); break
|
|
127
|
+ props.dispatch(newFlashMessage(`${props.t('An error has happened while fetching')} ${props.t('known members list')}`, 'warning')); break
|
72
|
128
|
}
|
73
|
129
|
}
|
74
|
130
|
|
75
|
|
- handleToggleNewMemberDashboard = () => this.setState(prevState => ({
|
76
|
|
- displayNewMemberDashboard: !prevState.displayNewMemberDashboard
|
77
|
|
- }))
|
|
131
|
+ handleChangeNewMemberNameOrEmail = newNameOrEmail => {
|
|
132
|
+ if (newNameOrEmail.length >= 2) this.handleSearchUser(newNameOrEmail)
|
|
133
|
+ this.setState(prev => ({newMember: {...prev.newMember, nameOrEmail: newNameOrEmail}}))
|
|
134
|
+ }
|
|
135
|
+
|
|
136
|
+ handleClickKnownMember = knownMember => {
|
|
137
|
+ this.setState(prev => ({
|
|
138
|
+ newMember: {
|
|
139
|
+ ...prev.newMember,
|
|
140
|
+ id: knownMember.user_id,
|
|
141
|
+ nameOrEmail: knownMember.public_name,
|
|
142
|
+ avatarUrl: knownMember.avatar_url
|
|
143
|
+ },
|
|
144
|
+ searchedKnownMemberList: []
|
|
145
|
+ }))
|
|
146
|
+ }
|
|
147
|
+
|
|
148
|
+ // handleChangeNewMemberCreateAccount = newCreateAccount => this.setState(prev => ({newMember: {...prev.newMember, createAccount: newCreateAccount}}))
|
|
149
|
+
|
|
150
|
+ handleChangeNewMemberRole = newRole => this.setState(prev => ({newMember: {...prev.newMember, role: newRole}}))
|
|
151
|
+
|
|
152
|
+ handleClickValidateNewMember = async () => {
|
|
153
|
+ const { props, state } = this
|
|
154
|
+
|
|
155
|
+ if (state.newMember.nameOrEmail === '') {
|
|
156
|
+ props.dispatch(newFlashMessage(props.t('Please set a name or email'), 'warning'))
|
|
157
|
+ return
|
|
158
|
+ }
|
78
|
159
|
|
79
|
|
- handleToggleNotifBtn = () => this.setState(prevState => ({
|
80
|
|
- displayNotifBtn: !prevState.displayNotifBtn
|
81
|
|
- }))
|
|
160
|
+ if (state.newMember.role === '') {
|
|
161
|
+ props.dispatch(newFlashMessage(props.t('Please set a role'), 'warning'))
|
|
162
|
+ return
|
|
163
|
+ }
|
82
|
164
|
|
83
|
|
- handleToggleWebdavBtn = () => this.setState(prevState => ({
|
84
|
|
- displayWebdavBtn: !prevState.displayWebdavBtn
|
85
|
|
- }))
|
|
165
|
+ const fetchWorkspaceNewMember = await props.dispatch(postWorkspaceMember(props.user, props.curWs.id, {
|
|
166
|
+ id: state.newMember.id,
|
|
167
|
+ name: state.newMember.nameOrEmail,
|
|
168
|
+ role: state.newMember.role
|
|
169
|
+ }))
|
86
|
170
|
|
87
|
|
- handleToggleCalendarBtn = () => this.setState(prevState => ({
|
88
|
|
- displayCalendarBtn: !prevState.displayCalendarBtn
|
89
|
|
- }))
|
|
171
|
+ switch (fetchWorkspaceNewMember.status) {
|
|
172
|
+ case 200:
|
|
173
|
+ this.loadMemberList(); break
|
|
174
|
+ default:
|
|
175
|
+ props.dispatch(newFlashMessage(props.t('An error has happened while adding the member'), 'warning')); break
|
|
176
|
+ }
|
|
177
|
+ }
|
90
|
178
|
|
91
|
179
|
render () {
|
92
|
180
|
const { props, state } = this
|
|
@@ -118,72 +206,13 @@ class Dashboard extends React.Component {
|
118
|
206
|
</div>
|
119
|
207
|
</div>
|
120
|
208
|
|
121
|
|
- <div className='dashboard__userstatut'>
|
122
|
|
- <div className='dashboard__userstatut__role'>
|
123
|
|
- <div className='dashboard__userstatut__role__msg'>
|
124
|
|
- {props.t('Hi {{name}} ! Currently, you are ', {name: props.user.public_name})}
|
125
|
|
- </div>
|
126
|
|
-
|
127
|
|
- {(() => {
|
128
|
|
- const myself = props.curWs.memberList.find(m => m.id === props.user.user_id)
|
129
|
|
- if (myself === undefined) return
|
130
|
|
-
|
131
|
|
- const myRole = ROLE.find(r => r.slug === myself.role)
|
132
|
|
-
|
133
|
|
- return (
|
134
|
|
- <div className='dashboard__userstatut__role__definition'>
|
135
|
|
- <div className='dashboard__userstatut__role__definition__icon'>
|
136
|
|
- <i className={`fa fa-${myRole.faIcon}`} />
|
137
|
|
- </div>
|
138
|
|
-
|
139
|
|
- <div className='dashboard__userstatut__role__definition__text'>
|
140
|
|
- {myRole.label}
|
141
|
|
- </div>
|
142
|
|
- </div>
|
143
|
|
- )
|
144
|
|
- })()}
|
145
|
|
- </div>
|
146
|
|
-
|
147
|
|
- <div className='dashboard__userstatut__notification'>
|
148
|
|
- <div className='dashboard__userstatut__notification__text'>
|
149
|
|
- {props.t("You have subscribed to this workspace's notifications")} (nyi)
|
150
|
|
- </div>
|
151
|
|
-
|
152
|
|
- {state.displayNotifBtn
|
153
|
|
- ? (
|
154
|
|
- <div className='dashboard__userstatut__notification__subscribe dropdown'>
|
155
|
|
- <button
|
156
|
|
- className='dashboard__userstatut__notification__subscribe__btn btn btn-outline-primary dropdown-toggle'
|
157
|
|
- type='button'
|
158
|
|
- id='dropdownMenuButton'
|
159
|
|
- data-toggle='dropdown'
|
160
|
|
- aria-haspopup='true'
|
161
|
|
- aria-expanded='false'
|
162
|
|
- >
|
163
|
|
- {props.t('subscriber')}
|
164
|
|
- </button>
|
165
|
|
-
|
166
|
|
- <div className='dashboard__userstatut__notification__subscribe__submenu dropdown-menu'>
|
167
|
|
- <div className='dashboard__userstatut__notification__subscribe__submenu__item dropdown-item'>
|
168
|
|
- {props.t('subscriber')}
|
169
|
|
- </div>
|
170
|
|
- <div className='dashboard__userstatut__notification__subscribe__submenu__item dropdown-item dropdown-item'>
|
171
|
|
- {props.t('unsubscribed')}
|
172
|
|
- </div>
|
173
|
|
- </div>
|
174
|
|
- </div>
|
175
|
|
- )
|
176
|
|
- : (
|
177
|
|
- <div
|
178
|
|
- className='dashboard__userstatut__notification__btn btn btn-outline-primary'
|
179
|
|
- onClick={this.handleToggleNotifBtn}
|
180
|
|
- >
|
181
|
|
- {props.t('Change your status')}
|
182
|
|
- </div>
|
183
|
|
- )
|
184
|
|
- }
|
185
|
|
- </div>
|
186
|
|
- </div>
|
|
209
|
+ <UserStatus
|
|
210
|
+ user={props.user}
|
|
211
|
+ curWs={props.curWs}
|
|
212
|
+ displayNotifBtn={state.displayNotifBtn}
|
|
213
|
+ onClickToggleNotifBtn={this.handleToggleNotifBtn}
|
|
214
|
+ t={props.t}
|
|
215
|
+ />
|
187
|
216
|
</div>
|
188
|
217
|
|
189
|
218
|
<div className='dashboard__calltoaction justify-content-xl-center'>
|
|
@@ -202,9 +231,11 @@ class Dashboard extends React.Component {
|
202
|
231
|
<div className='dashboard__workspaceInfo'>
|
203
|
232
|
<RecentActivity
|
204
|
233
|
customClass='dashboard__activity'
|
205
|
|
- recentActivityFilteredForUser={props.curWs.recentActivityList.filter(content => !props.curWs.contentReadStatusList.includes(content.id))}
|
|
234
|
+ recentActivityFilteredForUser={props.curWs.recentActivityForUserList}
|
206
|
235
|
contentTypeList={props.contentType}
|
207
|
|
- onClickSeeMore={() => {}}
|
|
236
|
+ onClickRecentContent={this.handleClickRecentContent}
|
|
237
|
+ onClickEverythingAsRead={this.handleClickMarkRecentActivityAsRead}
|
|
238
|
+ onClickSeeMore={this.handleClickSeeMore}
|
208
|
239
|
t={props.t}
|
209
|
240
|
/>
|
210
|
241
|
|
|
@@ -212,70 +243,26 @@ class Dashboard extends React.Component {
|
212
|
243
|
customClass='dashboard__memberlist'
|
213
|
244
|
memberList={props.curWs.memberList}
|
214
|
245
|
roleList={ROLE}
|
|
246
|
+ searchedKnownMemberList={state.searchedKnownMemberList}
|
|
247
|
+ nameOrEmail={state.newMember.nameOrEmail}
|
|
248
|
+ onChangeNameOrEmail={this.handleChangeNewMemberNameOrEmail}
|
|
249
|
+ onClickKnownMember={this.handleClickKnownMember}
|
|
250
|
+ // createAccount={state.newMember.createAccount}
|
|
251
|
+ // onChangeCreateAccount={this.handleChangeNewMemberCreateAccount}
|
|
252
|
+ role={state.newMember.role}
|
|
253
|
+ onChangeRole={this.handleChangeNewMemberRole}
|
|
254
|
+ onClickValidateNewMember={this.handleClickValidateNewMember}
|
215
|
255
|
t={props.t}
|
216
|
256
|
/>
|
217
|
257
|
</div>
|
218
|
258
|
|
219
|
|
- <div className='dashboard__moreinfo'>
|
220
|
|
- <div className='dashboard__moreinfo__webdav genericBtnInfoDashboard'>
|
221
|
|
- <div
|
222
|
|
- className='dashboard__moreinfo__webdav__btn genericBtnInfoDashboard__btn'
|
223
|
|
- onClick={this.handleToggleWebdavBtn}
|
224
|
|
- >
|
225
|
|
- <div className='dashboard__moreinfo__webdav__btn__icon genericBtnInfoDashboard__btn__icon'>
|
226
|
|
- <i className='fa fa-windows' />
|
227
|
|
- </div>
|
228
|
|
-
|
229
|
|
- <div className='dashboard__moreinfo__webdav__btn__text genericBtnInfoDashboard__btn__text'>
|
230
|
|
- {this.props.t('Implement Tracim in your explorer')}
|
231
|
|
- </div>
|
232
|
|
- </div>
|
233
|
|
- {this.state.displayWebdavBtn === true &&
|
234
|
|
- <div>
|
235
|
|
- <div className='dashboard__moreinfo__webdav__information genericBtnInfoDashboard__info'>
|
236
|
|
- <div className='dashboard__moreinfo__webdav__information__text genericBtnInfoDashboard__info__text'>
|
237
|
|
- {this.props.t('Find all your documents deposited online directly on your computer via the workstation, without going through the software.')}'
|
238
|
|
- </div>
|
239
|
|
-
|
240
|
|
- <div className='dashboard__moreinfo__webdav__information__link genericBtnInfoDashboard__info__link'>
|
241
|
|
- http://algoo.trac.im/webdav/
|
242
|
|
- </div>
|
243
|
|
- </div>
|
244
|
|
- </div>
|
245
|
|
- }
|
246
|
|
- </div>
|
247
|
|
- <div className='dashboard__moreinfo__calendar genericBtnInfoDashboard'>
|
248
|
|
- <div className='dashboard__moreinfo__calendar__wrapperBtn'>
|
249
|
|
- <div
|
250
|
|
- className='dashboard__moreinfo__calendar__btn genericBtnInfoDashboard__btn'
|
251
|
|
- onClick={this.handleToggleCalendarBtn}
|
252
|
|
- >
|
253
|
|
- <div className='dashboard__moreinfo__calendar__btn__icon genericBtnInfoDashboard__btn__icon'>
|
254
|
|
- <i className='fa fa-calendar' />
|
255
|
|
- </div>
|
256
|
|
-
|
257
|
|
- <div className='dashboard__moreinfo__calendar__btn__text genericBtnInfoDashboard__btn__text'>
|
258
|
|
- {this.props.t('Workspace Calendar')}
|
259
|
|
- </div>
|
260
|
|
- </div>
|
261
|
|
- </div>
|
262
|
|
- <div className='dashboard__moreinfo__calendar__wrapperText'>
|
263
|
|
- {this.state.displayCalendarBtn === true &&
|
264
|
|
- <div>
|
265
|
|
- <div className='dashboard__moreinfo__calendar__information genericBtnInfoDashboard__info'>
|
266
|
|
- <div className='dashboard__moreinfo__calendar__information__text genericBtnInfoDashboard__info__text'>
|
267
|
|
- {this.props.t('Each workspace has its own calendar.')}
|
268
|
|
- </div>
|
269
|
|
-
|
270
|
|
- <div className='dashboard__moreinfo__calendar__information__link genericBtnInfoDashboard__info__link'>
|
271
|
|
- http://algoo.trac.im/calendar/
|
272
|
|
- </div>
|
273
|
|
- </div>
|
274
|
|
- </div>
|
275
|
|
- }
|
276
|
|
- </div>
|
277
|
|
- </div>
|
278
|
|
- </div>
|
|
259
|
+ <MoreInfo
|
|
260
|
+ onClickToggleWebdav={this.handleToggleWebdavBtn}
|
|
261
|
+ displayWebdavBtn={state.displayWebdavBtn}
|
|
262
|
+ onClickToggleCalendar={this.handleToggleCalendarBtn}
|
|
263
|
+ displayCalendarBtn={state.displayCalendarBtn}
|
|
264
|
+ t={props.t}
|
|
265
|
+ />
|
279
|
266
|
</PageContent>
|
280
|
267
|
</PageWrapper>
|
281
|
268
|
</div>
|