mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-23 23:57:55 -05:00
Show students filter for educators viewing a classroom studio
This commit is contained in:
parent
134cd927ec
commit
e73312c0d2
3 changed files with 43 additions and 14 deletions
|
@ -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}",
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 = ({
|
||||||
|
|
Loading…
Reference in a new issue