Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ const CoursesGroupsList = ({
<BindIcon gapRight />
<FormattedMessage
id="app.coursesGroupsList.bind"
defaultMessage="Bind Existing Group"
defaultMessage="Bind with Existing Group"
/>
</Button>
)}
Expand Down
6 changes: 4 additions & 2 deletions src/locales/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"app.box.highlighterExplanation": "Tento panel je zvýrazněný. Klikněte pro vrácení do normálního stavu.",
"app.confirm.no": "Ne",
"app.confirm.yes": "Ano",
"app.coursesGroupsList.bind": "Svázat existující skupinu",
"app.coursesGroupsList.bind": "Svázat s existující skupinou",
"app.coursesGroupsList.create": "Vytvořit novou skupinu",
"app.coursesGroupsList.firstWeekEven": "sudé týdny",
"app.coursesGroupsList.firstWeekOdd": "liché týdny",
Expand Down Expand Up @@ -122,6 +122,7 @@
"app.groupsTeacher.createParentGroupLabelExplanation": "Zobrazují se pouze skupiny, které jsou umístěny zároveň pod skupinou předmětu `{course}` a skupinou semestru `{term}`.",
"app.groupsTeacher.lastRefreshInfo": "Seznam předmětů, které vyučujete, byl naposledy stažen ze SISu",
"app.groupsTeacher.noActiveTerms": "V tuto chvíli nejsou učitelům dostupné žádné semestry.",
"app.groupsTeacher.noGroupsForSelection": "Nejsou dostupné žádné vhodné skupiny pro výběr...",
"app.groupsTeacher.notTeacher": "Tato stránka je dostupná pouze učitelům.",
"app.groupsTeacher.scheduledAt": "Rozvrženo na",
"app.groupsTeacher.selectGroupForBinding": "Vyberte skupinu pro svázání",
Expand All @@ -142,13 +143,14 @@
"app.homepage.groupsStudentPage": "Připojte se ke skupinám, které odpovídají vašim zapsaným předmětům v SISu.",
"app.homepage.groupsSuperadminPage": "Správa skupin a jejich atributů na nejvyšší úrovni (dostupné pouze hlavním administrátorům).",
"app.homepage.groupsTeacherPage": "Vytvořte nebo přiřaďte skupiny pro vaše předměty ze SISu.",
"app.homepage.loginFailed": "Ověření uživatele selhalo",
"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...",
"app.homepage.termsPage": "Správa semestrů a jejich souvisejících dat (kdy jsou aktivní pro studenty a učitele).",
"app.homepage.title": "Rozšíření SIS-CodEx",
"app.homepage.userPage": "Stránka s osobními údaji umožnujě synchronizovat uživatelský profil (jméno, tituly, email) s daty ze SISu.",
"app.homepage.userSessionExpired": "Vaše uživatelská relace vypršela",
"app.homepage.userSessionExpired": "Vaše uživatelská relace vypršela nebo jste se odhlásili",
"app.homepage.userSessionExpiredInfo": "Musíte inicializovat novou relaci opětovným vstupem do této aplikace z ReCodExu.",
"app.localizedTexts.validation.noLocalizedText": "Prosíme povolte alespoň jednu záložku s lokalizovanými texty.",
"app.notifications.hideAll": "Pouze nové notifikace",
Expand Down
8 changes: 5 additions & 3 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"app.box.highlighterExplanation": "This box is highlighted. Click to restore.",
"app.confirm.no": "No",
"app.confirm.yes": "Yes",
"app.coursesGroupsList.bind": "Bind Existing Group",
"app.coursesGroupsList.bind": "Bind with Existing Group",
"app.coursesGroupsList.create": "Create New Group",
"app.coursesGroupsList.firstWeekEven": "even weeks",
"app.coursesGroupsList.firstWeekOdd": "odd weeks",
Expand Down Expand Up @@ -122,6 +122,7 @@
"app.groupsTeacher.createParentGroupLabelExplanation": "Only groups that are located in the hierarchy under both `{course}` course group and `{term}` term group are listed.",
"app.groupsTeacher.lastRefreshInfo": "The list of courses taught by you was last downloaded from SIS",
"app.groupsTeacher.noActiveTerms": "There are currently no terms available for teachers.",
"app.groupsTeacher.noGroupsForSelection": "There are no suitable groups to select from...",
"app.groupsTeacher.notTeacher": "This page is available only to teachers.",
"app.groupsTeacher.scheduledAt": "Scheduled at",
"app.groupsTeacher.selectGroupForBinding": "Select Group for Binding",
Expand All @@ -142,13 +143,14 @@
"app.homepage.groupsStudentPage": "Join groups that correspond to your enrolled courses in SIS.",
"app.homepage.groupsSuperadminPage": "Management of groups and their attributes at highest level (available to superadmins only).",
"app.homepage.groupsTeacherPage": "Create or bind groups for your courses in SIS.",
"app.homepage.loginFailed": "Authentication process failed",
"app.homepage.processingToken": "Processing authentication token...",
"app.homepage.processingTokenFailed": "Authentication process failed.",
"app.homepage.returnToReCodEx": "Return to ReCodEx...",
"app.homepage.termsPage": "Management of terms and their related dates (when they are active for students and teachers).",
"app.homepage.title": "SiS-CodEx Extension",
"app.homepage.userPage": "The personal data integration page allows updating ReCodEx user profile (name, titles, email) using data from SIS.",
"app.homepage.userSessionExpired": "Your user session has expired",
"app.homepage.userSessionExpired": "Your user session has expired or you have logged out",
"app.homepage.userSessionExpiredInfo": "You need to initialize a new session by re-entering this application from ReCodEx.",
"app.localizedTexts.validation.noLocalizedText": "Please enable at least one tab of localized texts.",
"app.notifications.hideAll": "Only new notifications",
Expand Down Expand Up @@ -267,4 +269,4 @@
"generic.operationFailed": "The operation has failed",
"generic.reset": "Reset",
"generic.save": "Save"
}
}
57 changes: 38 additions & 19 deletions src/pages/GroupsTeacher/GroupsTeacher.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,15 @@ class GroupsTeacher extends Component {
selectedGroupId: '',
};

startBind = (bindEvent, selectGroups) => this.setState({ bindEvent, selectGroups });
startBind = (bindEvent, selectGroups) => {
const selectedGroupId = selectGroups[0]?.id || '';
this.setState({ bindEvent, selectGroups, selectedGroupId });
};

startCreate = (createEvent, selectGroups) => this.setState({ createEvent, selectGroups });
startCreate = (createEvent, selectGroups) => {
const selectedGroupId = selectGroups[0]?.id || '';
this.setState({ createEvent, selectGroups, selectedGroupId });
};

closeModal = () =>
this.setState({
Expand All @@ -102,25 +108,29 @@ class GroupsTeacher extends Component {

handleGroupChange = ev => this.setState({ selectedGroupId: ev.target.value });

completeModalOperation = () => {
completeModalOperation = async () => {
const { loggedInUserId, bind, create, loadAsync } = this.props;

this.setState({ modalPending: true });
if (this.state.bindEvent !== null) {
bind(this.state.selectedGroupId, this.state.bindEvent).then(
() => loadAsync(loggedInUserId).then(this.closeModal),
error => this.setState({ modalPending: false, modalError: error?.message || 'unknown error' })
);
} else if (this.state.createEvent !== null) {
create(this.state.selectedGroupId, this.state.createEvent)
.then(
() => loadAsync(loggedInUserId),
error => this.setState({ modalPending: false, modalError: error?.message || 'unknown error' })
)
.then(this.closeModal);
} else {
if (!this.state.bindEvent && !this.state.createEvent) {
this.closeModal();
return;
}

this.setState({ modalPending: true });

try {
if (this.state.bindEvent !== null) {
await bind(this.state.selectedGroupId, this.state.bindEvent);
} else if (this.state.createEvent !== null) {
await create(this.state.selectedGroupId, this.state.createEvent);
}
} catch (error) {
this.setState({ modalPending: false, modalError: error?.message || 'unknown error' });
return;
}

await loadAsync(loggedInUserId);
this.closeModal();
};

unbindAndReload = (groupId, eventId) => {
Expand Down Expand Up @@ -376,10 +386,10 @@ class GroupsTeacher extends Component {
</FormLabel>
<InputGroup>
<FormSelect
className="form-control"
className={'form-control' + (!this.state.selectGroups?.length ? ' text-danger' : '')}
value={this.state.selectedGroupId}
disabled={!this.state.selectGroups?.length}
onChange={this.handleGroupChange}>
<option value="">...</option>
{this.state.selectGroups?.map(group => (
<option key={group.id} value={group.id}>
{group.fullName}&nbsp;&nbsp;
Expand All @@ -393,6 +403,15 @@ class GroupsTeacher extends Component {
)}
</option>
))}

{!this.state.selectGroups?.length && (
<option value="">
<FormattedMessage
id="app.groupsTeacher.noGroupsForSelection"
defaultMessage="There are no suitable groups to select from..."
/>
</option>
)}
</FormSelect>
</InputGroup>
</FormGroup>
Expand Down
18 changes: 14 additions & 4 deletions src/pages/Home/Home.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ import Icon, {
import Callout from '../../components/widgets/Callout';

import { setLang } from '../../redux/modules/app.js';
import { login, logout } from '../../redux/modules/auth.js';
import { login, logout, statusTypes as authStatusTypes } from '../../redux/modules/auth.js';
import { fetchUserIfNeeded } from '../../redux/modules/users.js';
import { loggedInUserSelector } from '../../redux/selectors/users.js';
import { loggedInUserIdSelector } from '../../redux/selectors/auth.js';
import { loggedInUserIdSelector, loginStatusSelector } from '../../redux/selectors/auth.js';

import { getReturnUrl, setReturnUrl } from '../../helpers/localStorage.js';
import { knownLocalesNames } from '../../helpers/localizedData.js';
Expand Down Expand Up @@ -85,19 +85,27 @@ class Home extends Component {
render() {
const {
loggedInUser,
loginStatus,
params: { token = null },
links: { USER_URI, TERMS_URI, GROUPS_STUDENT_URI, GROUPS_TEACHER_URI, GROUPS_SUPERADMIN_URI },
} = this.props;

if (!loggedInUser && !token) {
if (!loggedInUser && (!token || loginStatus === authStatusTypes.LOGIN_FAILED)) {
return (
<PageContent
icon={<HomeIcon />}
title={<FormattedMessage id="app.homepage.title" defaultMessage="SiS-CodEx Extension" />}
windowTitle={<FormattedMessage id="app.homepage.title" defaultMessage="SiS-CodEx Extension" />}>
<Callout variant="warning" className="my-3">
<h4>
<FormattedMessage id="app.homepage.userSessionExpired" defaultMessage="Your user session has expired" />
{!token ? (
<FormattedMessage
id="app.homepage.userSessionExpired"
defaultMessage="Your user session has expired or you have logged out"
/>
) : (
<FormattedMessage id="app.homepage.loginFailed" defaultMessage="Authentication process failed" />
)}
</h4>
<p>
<FormattedMessage
Expand Down Expand Up @@ -342,6 +350,7 @@ Home.propTypes = {
}),
loggedInUserId: PropTypes.string,
loggedInUser: ImmutablePropTypes.map,
loginStatus: PropTypes.string,
loadAsync: PropTypes.func.isRequired,
setLang: PropTypes.func.isRequired,
login: PropTypes.func.isRequired,
Expand All @@ -353,6 +362,7 @@ export default connect(
state => ({
loggedInUserId: loggedInUserIdSelector(state),
loggedInUser: loggedInUserSelector(state),
loginStatus: loginStatusSelector(state),
}),
dispatch => ({
loadAsync: userId => Home.loadAsync({ userId }, dispatch),
Expand Down
2 changes: 1 addition & 1 deletion src/redux/selectors/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const accessTokenExpiration = createSelector(accessTokenSelector, token =
);
export const loggedInUserIdSelector = createSelector(getAuth, getLoggedInUserId);

export const loginStatusSelector = createSelector(getAuth, auth => auth.getIn(['status']));
export const loginStatusSelector = createSelector(getAuth, auth => auth.getIn(['status', 'recodex']));

export const loginErrorSelector = createSelector(getAuth, auth => auth.getIn(['errors', 'recodex'])?.toJS() || null);

Expand Down