Show students filter for educators viewing a classroom studio

This commit is contained in:
Paul Kaplan 2021-05-13 13:21:54 -04:00
parent 134cd927ec
commit e73312c0d2
3 changed files with 43 additions and 14 deletions

View file

@ -38,6 +38,7 @@
"studio.sharedFilter": "Shared", "studio.sharedFilter": "Shared",
"studio.favoritedFilter": "Favorited", "studio.favoritedFilter": "Favorited",
"studio.recentFilter": "Recent", "studio.recentFilter": "Recent",
"studio.studentsFilter": "Students",
"studio.activityAddProjectToStudio": "{profileLink} added the project {projectLink}", "studio.activityAddProjectToStudio": "{profileLink} added the project {projectLink}",
"studio.activityRemoveProjectStudio": "{profileLink} removed the project {projectLink}", "studio.activityRemoveProjectStudio": "{profileLink} removed the project {projectLink}",

View file

@ -1,6 +1,7 @@
import keyMirror from 'keymirror'; import keyMirror from 'keymirror';
import api from '../../../lib/api'; import api from '../../../lib/api';
import {selectUsername} from '../../../redux/session'; import {selectToken, selectUsername} from '../../../redux/session';
import {selectClassroomId} from '../../../redux/studio';
import {userProjects, projects} from './redux-modules'; import {userProjects, projects} from './redux-modules';
const Errors = keyMirror({ const Errors = keyMirror({
@ -12,13 +13,25 @@ const Errors = keyMirror({
const Filters = keyMirror({ const Filters = keyMirror({
SHARED: null, SHARED: null,
FAVORITED: null, FAVORITED: null,
RECENT: null RECENT: null,
STUDENTS: null
}); });
const Uris = { const Endpoints = {
[Filters.SHARED]: username => `/users/${username}/projects`, [Filters.SHARED]: state => ({
[Filters.FAVORITED]: username => `/users/${username}/favorites`, uri: `/users/${selectUsername(state)}/projects`
[Filters.RECENT]: username => `/users/${username}/recent` }),
[Filters.FAVORITED]: state => ({
uri: `/users/${selectUsername(state)}/favorites`
}),
[Filters.RECENT]: state => ({
uri: `/users/${selectUsername(state)}/projects/recentlyviewed`,
authentication: selectToken(state)
}),
[Filters.STUDENTS]: state => ({
uri: `/classrooms/${selectClassroomId(state)}/projects`,
authentication: selectToken(state)
})
}; };
const normalizeError = (err, body, res) => { const normalizeError = (err, body, res) => {
@ -30,14 +43,17 @@ const normalizeError = (err, body, res) => {
const loadUserProjects = type => ((dispatch, getState) => { const loadUserProjects = type => ((dispatch, getState) => {
const state = getState(); const state = getState();
const username = selectUsername(state);
const projectCount = userProjects.selector(state).items.length; const projectCount = userProjects.selector(state).items.length;
const projectsPerPage = 20; const projectsPerPage = 20;
const opts = {
...Endpoints[type](state),
params: {
limit: projectsPerPage,
offset: projectCount
}
};
dispatch(userProjects.actions.loading()); dispatch(userProjects.actions.loading());
api({ api(opts, (err, body, res) => {
uri: Uris[type](username),
params: {limit: projectsPerPage, offset: projectCount}
}, (err, body, res) => {
const error = normalizeError(err, body, res); const error = normalizeError(err, body, res);
if (error) return dispatch(userProjects.actions.error(error)); if (error) return dispatch(userProjects.actions.error(error));
const moreToLoad = body.length === projectsPerPage; const moreToLoad = body.length === projectsPerPage;

View file

@ -5,6 +5,7 @@ import {connect} from 'react-redux';
import classNames from 'classnames'; import classNames from 'classnames';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import {selectClassroomId} from '../../../redux/studio';
import {addProject, removeProject} from '../lib/studio-project-actions'; import {addProject, removeProject} from '../lib/studio-project-actions';
import {userProjects} from '../lib/redux-modules'; import {userProjects} from '../lib/redux-modules';
import {Filters, loadUserProjects, clearUserProjects} from '../lib/user-projects-actions'; import {Filters, loadUserProjects, clearUserProjects} from '../lib/user-projects-actions';
@ -16,10 +17,11 @@ import SubNavigation from '../../../components/subnavigation/subnavigation.jsx';
import UserProjectsTile from './user-projects-tile.jsx'; import UserProjectsTile from './user-projects-tile.jsx';
import './user-projects-modal.scss'; import './user-projects-modal.scss';
import {selectIsEducator} from '../../../redux/session';
const UserProjectsModal = ({ const UserProjectsModal = ({
items, error, loading, moreToLoad, onLoadMore, onClear, items, error, loading, moreToLoad, showStudentsFilter,
onAdd, onRemove, onRequestClose onLoadMore, onClear, onAdd, onRemove, onRequestClose
}) => { }) => {
const [filter, setFilter] = useState(Filters.SHARED); const [filter, setFilter] = useState(Filters.SHARED);
@ -60,6 +62,14 @@ const UserProjectsModal = ({
> >
<FormattedMessage id="studio.recentFilter" /> <FormattedMessage id="studio.recentFilter" />
</li> </li>
{showStudentsFilter &&
<li
className={classNames({active: filter === Filters.STUDENTS})}
onClick={() => setFilter(Filters.STUDENTS)}
>
<FormattedMessage id="studio.studentsFilter" />
</li>
}
</SubNavigation> </SubNavigation>
<ModalInnerContent className="user-projects-modal-content"> <ModalInnerContent className="user-projects-modal-content">
{error && <div>Error loading {filter}: {error}</div>} {error && <div>Error loading {filter}: {error}</div>}
@ -91,6 +101,7 @@ const UserProjectsModal = ({
}; };
UserProjectsModal.propTypes = { UserProjectsModal.propTypes = {
showStudentsFilter: PropTypes.bool,
items: PropTypes.arrayOf(PropTypes.shape({ items: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.id, id: PropTypes.id,
image: PropTypes.string, image: PropTypes.string,
@ -108,7 +119,8 @@ UserProjectsModal.propTypes = {
}; };
const mapStateToProps = state => ({ const mapStateToProps = state => ({
...userProjects.selector(state) ...userProjects.selector(state),
showStudentsFilter: selectIsEducator(state) && selectClassroomId(state)
}); });
const mapDispatchToProps = ({ const mapDispatchToProps = ({