Skip to content

Commit

Permalink
Adjusting labels and captions, adding user-sync-cancel callout, addin…
Browse files Browse the repository at this point in the history
…g logout link to home page.
  • Loading branch information
krulis-martin committed Feb 18, 2025
1 parent a0f522c commit e5f597c
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/components/layout/Sidebar/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const Sidebar = ({ pendingFetchOperations, loggedInUser, currentUrl, links: { HO
</>
) : (
<MenuItem
title={<FormattedMessage id="app.sidebar.menu.return" defaultMessage="Back to ReCodEx" />}
title={<FormattedMessage id="app.backToReCodEx" defaultMessage="Back to ReCodEx" />}
icon="person-walking-arrow-loop-left"
link={getReturnUrl()}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/Sidebar/UserPanel/UserPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class UserPanel extends Component {
}}>
<ReturnIcon className="text-danger sidebar-up-collapse-gaps" gapRight />
<span className="sidebar-up-hide-collapsed">
<FormattedMessage id="app.logout" defaultMessage="Logout" />
<FormattedMessage id="app.backToReCodEx" defaultMessage="Back to ReCodEx" />
</span>
</a>
</OverlayTrigger>
Expand Down
13 changes: 7 additions & 6 deletions src/locales/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"app.apiErrorCodes.500-000": "Neočekávaná vnitřní chyba.",
"app.apiErrorCodes.501": "Funkce nebyla implementována",
"app.apiErrorCodes.unknown": "Neznámá chyba API.",
"app.backToReCodEx": "Zpět do ReCodExu",
"app.badge.failedLoading": "Nepodařilo se načíst data",
"app.badge.failedLoadingInfo": "Prosim zkontrolujte si své připojení k Internetu.",
"app.badge.sessionExpiration": "Expirace sezení:",
Expand Down Expand Up @@ -53,7 +54,8 @@
"app.groups.removeFromGroup": "Odebrat ze skupiny",
"app.header.languageSwitching.translationTitle": "Jazyková verze",
"app.headerNotification.copiedToClippboard": "Zkopírováno do schránky.",
"app.homepage.about": "Toto rozšíření ReCodExu mí nastarost datovou integraci mezi ReCodExem a Studijním informačním systémem (SIS) Karlovy Univerzity. Prosíme vyberte si jednu ze stránek níže.",
"app.homepage.about": "Toto rozšíření ReCodExu má na starost datovou integraci mezi ReCodExem a Studijním Informačním Systémem (SIS) Karlovy Univerzity. Prosíme vyberte si jednu ze stránek níže.",
"app.homepage.backToReCodExDescription": "A odlásit z relace SIS-CodExu.",
"app.homepage.processingToken": "Probíhá zpracování přihlašovacího tokenu...",
"app.homepage.processingTokenFailed": "Autentizační proces selhal.",
"app.homepage.returnToReCodEx": "Návrat do ReCodExu...",
Expand All @@ -66,7 +68,6 @@
"app.localizedTexts.noText": "Pro danou lokalizaci není vyplněn ani text ani externí odkaz na zadaní. Tato úloha ještě není řádně dospecifikována.",
"app.localizedTexts.studentHintHeading": "Nápověda",
"app.localizedTexts.validation.noLocalizedText": "Prosíme povolte alespoň jednu záložku s lokalizovanými texty.",
"app.logout": "Odhlásit",
"app.navigation.dashboard": "Přehled",
"app.navigation.edit": "Editovat",
"app.navigation.exercise": "Úloha",
Expand Down Expand Up @@ -103,7 +104,6 @@
"app.roles.supervisorStudents": "Vedoucí-studenti",
"app.roles.supervisors": "Vedoucí",
"app.roles.supervisorsEmpowered": "Zplnomocnění vedoucí",
"app.sidebar.menu.return": "Zpět do ReCodExu",
"app.sidebar.menu.user": "Osobní údaje",
"app.submissionStatus.accepted": "Toto řešení bylo označeno jako akceptované vedoucím skupiny.",
"app.user.diffBox.email": "Email",
Expand All @@ -115,12 +115,13 @@
"app.user.diffBox.title": "Uživatelský profil",
"app.user.diffBox.titlesAfterName": "Tituly před jménem",
"app.user.diffBox.titlesBeforeName": "Tituly za jménem",
"app.user.fetchSisButton": "Občerstvit data ze SISu",
"app.user.fetchSisButton": "Znovu načíst data ze SISu",
"app.user.sisUserFailedCallout": "Načítání dat ze SISu selhalo.",
"app.user.sisUserLoadedCallout": "Data ze SISu byla úspěšně načtena.",
"app.user.syncButton": "Přepsat ReCodEx daty ze SISu",
"app.user.syncButton": "Aktualizovat profil v ReCodExu daty ze SISu",
"app.user.title": "Osobní údaje",
"app.user.userSyncFailedCallout": "Synchronizace uživatele selhala. Prosím, znovu načťete stránku a opakujte akci později.",
"app.user.userSyncCanceledCallout": "Synchronizace uživatelských dat byla přerušena, protože profil z ReCodExu byl zastaralý a bylo nutné jej znovu načíst. Prosíme, zahajte aktualizaci dat znovu, pokud je to stále žádoucí.",
"app.user.userSyncFailedCallout": "Synchronizace uživatele selhala. Prosíme, znovu načťete stránku a opakujte akci později.",
"app.user.userUpdatedCallout": "Uživatelská data v ReCodExu byla úspěšně aktualizována daty ze SISu.",
"app.userName.externalIds": "Externí identifikátory",
"app.userName.externalIdsClickInfo": "klikutím zkopírujete ID do schránky",
Expand Down
9 changes: 5 additions & 4 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"app.apiErrorCodes.500-000": "Unexpected internal error.",
"app.apiErrorCodes.501": "Feature not implemented",
"app.apiErrorCodes.unknown": "Unknown API error.",
"app.backToReCodEx": "Back to ReCodEx",
"app.badge.failedLoading": "Failed to load the data",
"app.badge.failedLoadingInfo": "Please check your Internet connection.",
"app.badge.sessionExpiration": "Session expiration:",
Expand Down Expand Up @@ -54,6 +55,7 @@
"app.header.languageSwitching.translationTitle": "Translation",
"app.headerNotification.copiedToClippboard": "Copied to clippboard.",
"app.homepage.about": "This ReCodEx extension handles data integration and exchange between ReCodEx and Charles University Student Information System (SIS). Please choose one of the pages below.",
"app.homepage.backToReCodExDescription": "And logout from SIS-CodEx session.",
"app.homepage.processingToken": "Processing authentication token...",
"app.homepage.processingTokenFailed": "Authentication process failed.",
"app.homepage.returnToReCodEx": "Return to ReCodEx...",
Expand All @@ -66,7 +68,6 @@
"app.localizedTexts.noText": "There is no text nor link for given localization. The exercise is not fully specified yet.",
"app.localizedTexts.studentHintHeading": "Hint",
"app.localizedTexts.validation.noLocalizedText": "Please enable at least one tab of localized texts.",
"app.logout": "Logout",
"app.navigation.dashboard": "Dashboard",
"app.navigation.edit": "Edit",
"app.navigation.exercise": "Exercise",
Expand Down Expand Up @@ -103,7 +104,6 @@
"app.roles.supervisorStudents": "Supervisor-students",
"app.roles.supervisors": "Supervisors",
"app.roles.supervisorsEmpowered": "Empowered Supervisors",
"app.sidebar.menu.return": "Back to ReCodEx",
"app.sidebar.menu.user": "Personal Data",
"app.submissionStatus.accepted": "This solution was marked by one of the supervisors as accepted.",
"app.user.diffBox.email": "Email",
Expand All @@ -115,11 +115,12 @@
"app.user.diffBox.title": "User's profile",
"app.user.diffBox.titlesAfterName": "Titles after",
"app.user.diffBox.titlesBeforeName": "Titles before",
"app.user.fetchSisButton": "Refresh SIS Data",
"app.user.fetchSisButton": "Reload SIS data",
"app.user.sisUserFailedCallout": "SIS data (re)loading failed.",
"app.user.sisUserLoadedCallout": "The SIS user data were successfully (re)loaded.",
"app.user.syncButton": "Overwrite ReCodEx with SIS Data",
"app.user.syncButton": "Update ReCodEx profile with data from SIS",
"app.user.title": "Personal Data",
"app.user.userSyncCanceledCallout": "User sync operation was canceled, because the ReCodEx profile data were outdated and needed to be reloaded. Please, re-start the operation if it is still desired.",
"app.user.userSyncFailedCallout": "User sync operation failed. Reload the page and try again later.",
"app.user.userUpdatedCallout": "The ReCodEx user data were successfully updated by current SIS data.",
"app.userName.externalIds": "External identifiers",
Expand Down
4 changes: 3 additions & 1 deletion src/locales/whitelist_cs.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[
"app.roles.student"
"app.roles.student",
"app.user.diffBox.email",
"app.user.diffBox.login"
]
47 changes: 46 additions & 1 deletion src/pages/Home/Home.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Icon, {
import Callout from '../../components/widgets/Callout';

import { setLang } from '../../redux/modules/app.js';
import { login } from '../../redux/modules/auth.js';
import { login, logout } from '../../redux/modules/auth.js';

import { getReturnUrl, setReturnUrl } from '../../helpers/localStorage.js';
import { knownLocalesNames } from '../../helpers/localizedData.js';
Expand Down Expand Up @@ -146,6 +146,50 @@ class Home extends Component {
</p>
</Col>
</Row>

<hr className="my-4" />

<Row>
<Col xs={false} sm="auto">
<h3>
<Icon
icon="person-walking-arrow-loop-left"
gapLeft={2}
gapRight={2}
fixedWidth
className="text-body-secondary"
/>
</h3>
</Col>
<Col xs={12} sm>
<h3>
<Link
to={USER_URI}
className="link-body-emphasis"
onClick={e => {
e.preventDefault();
logout();

// let's go back to ReCodEx after the logout...
const url = getReturnUrl();
if (url && window) {
setReturnUrl(null);
window.location.assign(url);
}
}}>
<FormattedMessage id="app.backToReCodEx" defaultMessage="Back to ReCodEx" />
<LinkIcon gapLeft={3} />
</Link>
</h3>

<p>
<FormattedMessage
id="app.homepage.backToReCodExDescription"
defaultMessage="And logout from SIS-CodEx session."
/>
</p>
</Col>
</Row>
</>
)}
</div>
Expand All @@ -171,5 +215,6 @@ export default connect(
dispatch => ({
setLang: lang => dispatch(setLang(lang)),
login: token => dispatch(login(token)),
logout: () => dispatch(logout()),
})
)(injectIntl(withLinks(Home)));
28 changes: 25 additions & 3 deletions src/pages/User/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ import Button, { TheButtonGroup } from '../../components/widgets/TheButton';
import Icon, { LoadingIcon, RefreshIcon, UserProfileIcon, WarningIcon } from '../../components/icons';
import { fetchUserIfNeeded, syncUser, syncUserReset } from '../../redux/modules/users.js';
import { fetchSisUser, fetchSisUserIfNeeded } from '../../redux/modules/sisUsers.js';
import { loggedInUserSelector, isUserSyncing, isUserUpdated, isUserSyncFailed } from '../../redux/selectors/users.js';
import {
loggedInUserSelector,
isUserSyncing,
isUserUpdated,
isUserSyncFailed,
isUserSyncCanceled,
} from '../../redux/selectors/users.js';
import { loggedInSisUserSelector } from '../../redux/selectors/sisUsers.js';
import { isLoading, hasFailed, getJsData } from '../../redux/helpers/resourceManager';

Expand Down Expand Up @@ -91,6 +97,7 @@ class User extends Component {
syncReset,
isUserSyncing = false,
isUserUpdated = false,
isUserSyncCanceled = false,
isUserSyncFailed = false,
} = this.props;
const sisUserData = getJsData(loggedInSisUser)?.sisUser;
Expand Down Expand Up @@ -128,6 +135,16 @@ class User extends Component {
/>
</Callout>
)}

{isUserSyncCanceled && (
<Callout variant="warning">
<FormattedMessage
id="app.user.userSyncCanceledCallout"
defaultMessage="User sync operation was canceled, because the ReCodEx profile data were outdated and needed to be reloaded. Please, re-start the operation if it is still desired."
/>
</Callout>
)}

{isUserSyncFailed && (
<Callout variant="danger">
<FormattedMessage
Expand Down Expand Up @@ -221,7 +238,10 @@ class User extends Component {
disabled={isUserSyncing}
onClick={() => syncUser(user.id)}>
{isUserSyncing ? <LoadingIcon gapRight /> : <Icon icon="left-long" gapRight />}
<FormattedMessage id="app.user.syncButton" defaultMessage="Overwrite ReCodEx with SIS Data" />
<FormattedMessage
id="app.user.syncButton"
defaultMessage="Update ReCodEx profile with data from SIS"
/>
</Button>
)}
<Button
Expand All @@ -232,7 +252,7 @@ class User extends Component {
return fetchSisUser(user.id, 0);
}}>
{isLoading(loggedInSisUser) ? <LoadingIcon gapRight /> : <RefreshIcon gapRight />}
<FormattedMessage id="app.user.fetchSisButton" defaultMessage="Refresh SIS Data" />
<FormattedMessage id="app.user.fetchSisButton" defaultMessage="Reload SIS data" />
</Button>
</TheButtonGroup>
</div>
Expand All @@ -249,6 +269,7 @@ User.propTypes = {
loggedInSisUser: ImmutablePropTypes.map,
isUserSyncing: PropTypes.bool,
isUserUpdated: PropTypes.bool,
isUserSyncCanceled: PropTypes.bool,
isUserSyncFailed: PropTypes.bool,
loadAsync: PropTypes.func.isRequired,
fetchSisUser: PropTypes.func.isRequired,
Expand All @@ -265,6 +286,7 @@ export default connect(
loggedInSisUser: loggedInSisUserSelector(state),
isUserSyncing: isUserSyncing(state, loggedInUser && loggedInUser.getIn(['data', 'id'], '')),
isUserUpdated: isUserUpdated(state, loggedInUser && loggedInUser.getIn(['data', 'id'], '')),
isUserSyncCanceled: isUserSyncCanceled(state, loggedInUser && loggedInUser.getIn(['data', 'id'], '')),
isUserSyncFailed: isUserSyncFailed(state, loggedInUser && loggedInUser.getIn(['data', 'id'], '')),
};
},
Expand Down
9 changes: 7 additions & 2 deletions src/redux/modules/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,18 @@ const reducer = handleActions(
state
.setIn(['resources', id, 'syncing'], true)
.removeIn(['resources', id, 'updated'])
.removeIn(['resources', id, 'syncCanceled'])
.removeIn(['resources', id, 'syncFailed']),

[additionalActionTypes.SYNC_FULFILLED]: (state, { payload: { user, updated }, meta: { id } }) =>
[additionalActionTypes.SYNC_FULFILLED]: (
state,
{ payload: { user, updated = false, canceled = false }, meta: { id } }
) =>
state
.setIn(['resources', id], createRecord({ state: resourceStatus.FULFILLED, data: user }))
.setIn(['resources', id, 'syncing'], false)
.setIn(['resources', id, 'updated'], updated),
.setIn(['resources', id, 'updated'], updated)
.setIn(['resources', id, 'syncCanceled'], canceled),

[additionalActionTypes.SYNC_REJECTED]: (state, { meta: { id } }) =>
state.setIn(['resources', id, 'syncing'], false).setIn(['resources', id, 'syncFailed'], true),
Expand Down
5 changes: 4 additions & 1 deletion src/redux/selectors/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ export const isUserSyncing = createSelector([usersSelector, getParam], (users, i
export const isUserUpdated = createSelector([usersSelector, getParam], (users, id) =>
users.getIn([id, 'updated'], false)
);
export const isUserSyncCanceled = createSelector([usersSelector, getParam], (users, id) =>
users.getIn([id, 'syncCanceled'], false)
);
export const isUserSyncFailed = createSelector([usersSelector, getParam], (users, id) =>
users.getIn([id, 'syncFailed', false])
users.getIn([id, 'syncFailed'], false)
);

0 comments on commit e5f597c

Please sign in to comment.