Skip to content

Commit

Permalink
Merge pull request #176 from ReCodEx/sis-courses
Browse files Browse the repository at this point in the history
Fixing bug and improving SIS course containers (so that teaching students can see both containers).
  • Loading branch information
Martin Kruliš committed Feb 12, 2018
2 parents 85120fd + c2380f9 commit 40049d8
Show file tree
Hide file tree
Showing 5 changed files with 463 additions and 328 deletions.
276 changes: 152 additions & 124 deletions src/containers/SisIntegrationContainer/SisIntegrationContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,24 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { FormattedMessage, injectIntl } from 'react-intl';
import Box from '../../components/widgets/Box';
import { Table } from 'react-bootstrap';
import Button from '../../components/widgets/FlatButton';
import { LinkContainer } from 'react-router-bootstrap';
import Icon from 'react-fontawesome';
import { Table } from 'react-bootstrap';
import Box from '../../components/widgets/Box';
import Button from '../../components/widgets/FlatButton';

import UsersNameContainer from '../UsersNameContainer';
import { fetchGroupsIfNeeded } from '../../redux/modules/groups';
import { fetchSisStatusIfNeeded } from '../../redux/modules/sisStatus';
import { fetchSisSubscribedGroups } from '../../redux/modules/sisSubscribedGroups';
import { sisStateSelector } from '../../redux/selectors/sisStatus';
import { sisSubscribedGroupsSelector } from '../../redux/selectors/sisSubscribedGroups';
import { loggedInUserIdSelector } from '../../redux/selectors/auth';
import ResourceRenderer from '../../components/helpers/ResourceRenderer';
import { groupDataAccessorSelector } from '../../redux/selectors/groups';

import UsersNameContainer from '../UsersNameContainer';
import LeaveJoinGroupButtonContainer from '../LeaveJoinGroupButtonContainer';
import { getLocalizedName } from '../../helpers/getLocalizedData';
import { getGroupCanonicalLocalizedName } from '../../helpers/getLocalizedData';
import ResourceRenderer from '../../components/helpers/ResourceRenderer';

import withLinks from '../../hoc/withLinks';

Expand All @@ -25,151 +28,174 @@ class SisIntegrationContainer extends Component {
this.props.loadData(this.props.currentUserId);
}

static loadData = (dispatch, loggedInUserId) => {
static loadData = (dispatch, loggedInUserId) =>
dispatch(fetchSisStatusIfNeeded())
.then(res => res.value)
.then(
({ accessible, terms }) =>
accessible &&
terms.map(({ year, term }) =>
dispatch(fetchSisSubscribedGroups(loggedInUserId, year, term))
.then(res => res.value)
.then(groups =>
groups
.filter(
group =>
group.parentGroupsIds && group.parentGroupsIds.length > 0
)
.map(group =>
dispatch(fetchGroupsIfNeeded(...group.parentGroupsIds))
)
)
)
);
};

render() {
const {
sisStatus,
currentUserId,
sisGroups,
groupsAccessor,
links: { GROUP_URI_FACTORY },
intl: { locale }
} = this.props;
return (
<Box
title={
<FormattedMessage
id="app.dashboard.sisGroups"
defaultMessage="SIS groups with ReCodEx mapping"
id="app.dashboard.sisGroupsStudent"
defaultMessage="SIS Courses - Student"
/>
}
collapsable
noPadding
isOpen
unlimitedHeight
isOpen={false}
>
<ResourceRenderer resource={sisStatus}>
{sisStatus =>
<div>
{!sisStatus.accessible &&
<p className="text-center">
<FormattedMessage
id="app.sisIntegration.noAccessible"
defaultMessage="Your account does not support SIS integration. Please, log in using CAS-UK."
/>
</p>}
{sisStatus.accessible &&
sisStatus.terms.map((term, i) =>
<div key={i}>
<h4 style={{ paddingLeft: '10px' }}>
<FormattedMessage
id="app.sisIntegration.yearTerm"
defaultMessage="Year and term:"
/>{' '}
{`${term.year}-${term.term}`}
</h4>
<ResourceRenderer
resource={sisGroups(term.year, term.term)}
>
{groups =>
<div>
{groups && groups.length > 0
? <Table hover>
<thead>
<tr>
<th>
<FormattedMessage
id="app.sisIntegration.groupName"
defaultMessage="Name"
/>
</th>
<th>
<FormattedMessage
id="app.sisIntegration.courseId"
defaultMessage="Course ID"
/>
</th>
<th>
<div>
<p className="text-muted">
<FormattedMessage
id="app.dashboard.sisGroupsStudentExplain"
defaultMessage="SIS courses you are enrolled to in particular semesters and which have correspondig groups in ReCodEx."
/>
</p>
<ResourceRenderer resource={sisStatus}>
{sisStatus =>
<div>
{!sisStatus.accessible &&
<p className="text-center">
<FormattedMessage
id="app.sisIntegration.noAccessible"
defaultMessage="Your account does not support SIS integration. Please, log in using CAS-UK."
/>
</p>}
{sisStatus.accessible &&
sisStatus.terms.map((term, i) =>
<div key={i}>
<h4>
<FormattedMessage
id="app.sisIntegration.yearTerm"
defaultMessage="Year and term:"
/>{' '}
{`${term.year}-${term.term}`}
</h4>
<ResourceRenderer
resource={sisGroups(term.year, term.term)}
>
{groups =>
<div>
{groups && groups.length > 0
? <Table hover>
<thead>
<tr>
<th>
<FormattedMessage
id="app.sisIntegration.groupName"
defaultMessage="Name"
/>
</th>
<th>
<FormattedMessage
id="app.sisIntegration.courseId"
defaultMessage="Course ID"
/>
</th>
<th>
<FormattedMessage
id="app.sisIntegration.groupAdmins"
defaultMessage="Group Administrators"
/>
</th>
<th />
</tr>
</thead>
<tbody>
{groups &&
groups.map((group, i) =>
<tr key={i}>
<td>
{getGroupCanonicalLocalizedName(
group,
groupsAccessor,
locale
)}
</td>
<td>
<code>
{group.sisCode}
</code>
</td>
<td>
{group.primaryAdminsIds.map(id =>
<UsersNameContainer
key={id}
userId={id}
/>
)}
</td>
<td className="text-right">
<span>
<LinkContainer
to={GROUP_URI_FACTORY(group.id)}
>
<Button
bsStyle="primary"
bsSize="xs"
className="btn-flat"
>
<Icon name="group" />{' '}
<FormattedMessage
id="app.sisIntegration.groupDetail"
defaultMessage="See group's page"
/>
</Button>
</LinkContainer>
<LeaveJoinGroupButtonContainer
userId={currentUserId}
groupId={group.id}
/>
</span>
</td>
</tr>
)}
</tbody>
</Table>
: <div className="text-center">
<p>
<b>
<FormattedMessage
id="app.sisIntegration.groupAdmins"
defaultMessage="Group Administrators"
id="app.sisIntegration.noSisGroups"
defaultMessage="Currently there are no ReCodEx groups matching your SIS subjects for this time period."
/>
</th>
<th />
</tr>
</thead>
<tbody>
{groups &&
groups.map((group, i) =>
<tr key={i}>
<td>
{getLocalizedName(group, locale)}
</td>
<td>
<code>
{group.sisCode}
</code>
</td>
<td>
{group.primaryAdminsIds.map(id =>
<UsersNameContainer
key={id}
userId={id}
/>
)}
</td>
<td className="text-right">
<span>
<LinkContainer
to={GROUP_URI_FACTORY(group.id)}
>
<Button
bsStyle="primary"
bsSize="xs"
className="btn-flat"
>
<Icon name="group" />{' '}
<FormattedMessage
id="app.sisIntegration.groupDetail"
defaultMessage="See group's page"
/>
</Button>
</LinkContainer>
<LeaveJoinGroupButtonContainer
userId={currentUserId}
groupId={group.id}
/>
</span>
</td>
</tr>
)}
</tbody>
</Table>
: <div className="text-center">
<p>
<b>
<FormattedMessage
id="app.sisIntegration.noSisGroups"
defaultMessage="Currently there are no ReCodEx groups matching your SIS subjects for this time period."
/>
</b>
</p>
</div>}
</div>}
</ResourceRenderer>
</div>
)}
</div>}
</ResourceRenderer>
</b>
</p>
</div>}
</div>}
</ResourceRenderer>
</div>
)}
</div>}
</ResourceRenderer>
</div>
</Box>
);
}
Expand All @@ -180,6 +206,7 @@ SisIntegrationContainer.propTypes = {
currentUserId: PropTypes.string,
loadData: PropTypes.func.isRequired,
sisGroups: PropTypes.func.isRequired,
groupsAccessor: PropTypes.func.isRequired,
links: PropTypes.object,
intl: PropTypes.shape({ locale: PropTypes.string.isRequired }).isRequired
};
Expand All @@ -192,7 +219,8 @@ export default withLinks(
sisStatus: sisStateSelector(state),
currentUserId,
sisGroups: (year, term) =>
sisSubscribedGroupsSelector(currentUserId, year, term)(state)
sisSubscribedGroupsSelector(currentUserId, year, term)(state),
groupsAccessor: groupDataAccessorSelector(state)
};
},
dispatch => ({
Expand Down
Loading

0 comments on commit 40049d8

Please sign in to comment.