@@ -11,9 +11,9 @@ import Box from '../../components/widgets/Box';
1111import DateTime from '../../components/widgets/DateTime' ;
1212import Button , { TheButtonGroup } from '../../components/widgets/TheButton' ;
1313import Icon , { LoadingIcon , RefreshIcon , UserProfileIcon , WarningIcon } from '../../components/icons' ;
14- import { fetchUserIfNeeded } from '../../redux/modules/users.js' ;
14+ import { fetchUserIfNeeded , syncUser , syncUserReset } from '../../redux/modules/users.js' ;
1515import { fetchSisUser , fetchSisUserIfNeeded } from '../../redux/modules/sisUsers.js' ;
16- import { loggedInUserSelector } from '../../redux/selectors/users.js' ;
16+ import { loggedInUserSelector , isUserSyncing , isUserUpdated , isUserSyncFailed } from '../../redux/selectors/users.js' ;
1717import { loggedInSisUserSelector } from '../../redux/selectors/sisUsers.js' ;
1818import { isLoading , hasFailed , getJsData } from '../../redux/helpers/resourceManager' ;
1919
@@ -83,7 +83,16 @@ class User extends Component {
8383 Promise . all ( [ dispatch ( fetchUserIfNeeded ( userId ) ) , dispatch ( fetchSisUserIfNeeded ( userId , 30 ) ) ] ) ;
8484
8585 render ( ) {
86- const { loggedInUser, loggedInSisUser, fetchSisUser } = this . props ;
86+ const {
87+ loggedInUser,
88+ loggedInSisUser,
89+ fetchSisUser,
90+ syncUser,
91+ syncReset,
92+ isUserSyncing = false ,
93+ isUserUpdated = false ,
94+ isUserSyncFailed = false ,
95+ } = this . props ;
8796 const sisUserData = getJsData ( loggedInSisUser ) ?. sisUser ;
8897 const sisUserUpdated = Boolean ( getJsData ( loggedInSisUser ) ?. updated ) ;
8998 const sisUserUpdateFailed = Boolean ( getJsData ( loggedInSisUser ) ?. failed ) ;
@@ -111,6 +120,23 @@ class User extends Component {
111120 </ Callout >
112121 ) }
113122
123+ { isUserUpdated && (
124+ < Callout variant = "success" >
125+ < FormattedMessage
126+ id = "app.user.userUpdatedCallout"
127+ defaultMessage = "The ReCodEx user data were successfully updated by current SIS data."
128+ />
129+ </ Callout >
130+ ) }
131+ { isUserSyncFailed && (
132+ < Callout variant = "danger" >
133+ < FormattedMessage
134+ id = "app.user.userSyncFailedCallout"
135+ defaultMessage = "User sync operation failed. Reload the page and try again later."
136+ />
137+ </ Callout >
138+ ) }
139+
114140 < Table bordered >
115141 < thead >
116142 < tr >
@@ -189,16 +215,22 @@ class User extends Component {
189215
190216 < div className = "text-center" >
191217 < TheButtonGroup >
192- { Object . values ( diffIndex ) . some ( v => v ) && (
193- < Button variant = "success" >
194- < Icon icon = "left-long" gapRight />
218+ { ( isUserSyncing || Object . values ( diffIndex ) . some ( v => v ) ) && (
219+ < Button
220+ variant = { isUserSyncFailed ? 'danger' : 'success' }
221+ disabled = { isUserSyncing }
222+ onClick = { ( ) => syncUser ( user . id ) } >
223+ { isUserSyncing ? < LoadingIcon gapRight /> : < Icon icon = "left-long" gapRight /> }
195224 < FormattedMessage id = "app.user.syncButton" defaultMessage = "Overwrite ReCodEx with SIS Data" />
196225 </ Button >
197226 ) }
198227 < Button
199228 variant = { sisUserUpdateFailed ? 'danger' : 'primary' }
200229 disabled = { isLoading ( loggedInSisUser ) }
201- onClick = { ( ) => fetchSisUser ( user . id , 0 ) } >
230+ onClick = { ( ) => {
231+ syncReset ( user . id ) ;
232+ return fetchSisUser ( user . id , 0 ) ;
233+ } } >
202234 { isLoading ( loggedInSisUser ) ? < LoadingIcon gapRight /> : < RefreshIcon gapRight /> }
203235 < FormattedMessage id = "app.user.fetchSisButton" defaultMessage = "Refresh SIS Data" />
204236 </ Button >
@@ -215,19 +247,32 @@ class User extends Component {
215247User . propTypes = {
216248 loggedInUser : ImmutablePropTypes . map ,
217249 loggedInSisUser : ImmutablePropTypes . map ,
250+ isUserSyncing : PropTypes . bool ,
251+ isUserUpdated : PropTypes . bool ,
252+ isUserSyncFailed : PropTypes . bool ,
218253 loadAsync : PropTypes . func . isRequired ,
219254 fetchSisUser : PropTypes . func . isRequired ,
220255 fetchSisUserIfNeeded : PropTypes . func . isRequired ,
256+ syncUser : PropTypes . func . isRequired ,
257+ syncReset : PropTypes . func . isRequired ,
221258} ;
222259
223260export default connect (
224- state => ( {
225- loggedInUser : loggedInUserSelector ( state ) ,
226- loggedInSisUser : loggedInSisUserSelector ( state ) ,
227- } ) ,
261+ state => {
262+ const loggedInUser = loggedInUserSelector ( state ) ;
263+ return {
264+ loggedInUser,
265+ loggedInSisUser : loggedInSisUserSelector ( state ) ,
266+ isUserSyncing : isUserSyncing ( state , loggedInUser && loggedInUser . getIn ( [ 'data' , 'id' ] , '' ) ) ,
267+ isUserUpdated : isUserUpdated ( state , loggedInUser && loggedInUser . getIn ( [ 'data' , 'id' ] , '' ) ) ,
268+ isUserSyncFailed : isUserSyncFailed ( state , loggedInUser && loggedInUser . getIn ( [ 'data' , 'id' ] , '' ) ) ,
269+ } ;
270+ } ,
228271 dispatch => ( {
229272 loadAsync : userId => User . loadAsync ( { userId } , dispatch ) ,
230273 fetchSisUser : ( userId , expiration = null ) => dispatch ( fetchSisUser ( userId , expiration ) ) ,
231274 fetchSisUserIfNeeded : ( userId , expiration = null ) => dispatch ( fetchSisUserIfNeeded ( userId , expiration ) ) ,
275+ syncUser : userId => dispatch ( syncUser ( userId ) ) ,
276+ syncReset : userId => dispatch ( syncUserReset ( userId ) ) ,
232277 } )
233278) ( User ) ;
0 commit comments