Skip to content

Commit

Permalink
Add Show Course Staff option and exclude all course roles by default (#…
Browse files Browse the repository at this point in the history
…168)

* Show Course Role Members

* add option to hide FilterBadge value for boolean filters

* chore: bump package to 1.4.20

Co-authored-by: Nathan Sprenkle <[email protected]>
  • Loading branch information
jansenk and nsprenkle authored Apr 16, 2021
1 parent 1c26aa1 commit 8bc1fc8
Show file tree
Hide file tree
Showing 12 changed files with 117 additions and 25 deletions.
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@edx/frontend-app-gradebook",
"version": "1.4.19",
"version": "1.4.20",
"description": "edx editable gradebook-ui to manipulate grade overrides on subsections",
"repository": {
"type": "git",
Expand Down
53 changes: 42 additions & 11 deletions src/components/FilterBadges/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import React from 'react';
import PropTypes from 'prop-types';
import initialFilters from '../../data/constants/filters';

function FilterBadge({ name, value, onClick }) {
function FilterBadge({
name, value, onClick, showValue,
}) {
return (
<div>
<span className="badge badge-info">
<span>{`${name}: ${value}`}</span>
<span>{name}{showValue && `: ${value}`}</span>
<button type="button" className="btn-info" aria-label="Close" onClick={onClick}>
<span aria-hidden="true">&times;</span>
</button>
Expand All @@ -18,6 +20,20 @@ function FilterBadge({ name, value, onClick }) {
);
}

FilterBadge.defaultProps = {
showValue: true,
};

FilterBadge.propTypes = {
name: PropTypes.string.isRequired,
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.bool,
]).isRequired,
onClick: PropTypes.func.isRequired,
showValue: PropTypes.bool,
};

function RangeFilterBadge({
displayName,
filterName1,
Expand Down Expand Up @@ -46,22 +62,32 @@ RangeFilterBadge.propTypes = {
};

function SingleValueFilterBadge({
displayName, filterName, filterValue, handleBadgeClose,
displayName, filterName, filterValue, handleBadgeClose, showValue,
}) {
return (filterValue !== initialFilters[filterName])
&& (
<FilterBadge
name={displayName}
value={filterValue}
onClick={handleBadgeClose}
showValue={showValue}
/>
);
}

SingleValueFilterBadge.defaultProps = {
showValue: true,
};

SingleValueFilterBadge.propTypes = {
displayName: PropTypes.string.isRequired,
filterName: PropTypes.string.isRequired,
filterValue: PropTypes.string.isRequired,
filterValue: PropTypes.oneOfType([
PropTypes.string,
PropTypes.bool,
]).isRequired,
handleBadgeClose: PropTypes.func.isRequired,
showValue: PropTypes.bool,
};

function FilterBadges({
Expand All @@ -73,6 +99,7 @@ function FilterBadges({
assignmentGradeMax,
courseGradeMin,
courseGradeMax,
includeCourseRoleMembers,
handleFilterBadgeClose,
}) {
return (
Expand Down Expand Up @@ -113,10 +140,17 @@ function FilterBadges({
/>
<SingleValueFilterBadge
displayName="Cohort"
filterName="track"
filterName="cohort"
filterValue={cohort}
handleBadgeClose={handleFilterBadgeClose(['cohort'])}
/>
<SingleValueFilterBadge
displayName="Including Course Team Members"
filterName="includeCourseRoleMembers"
filterValue={includeCourseRoleMembers}
showValue={false}
handleBadgeClose={handleFilterBadgeClose(['includeCourseRoleMembers'])}
/>
</div>
);
}
Expand All @@ -131,18 +165,13 @@ const mapStateToProps = state => (
assignmentGradeMax: state.filters.assignmentGradeMax,
courseGradeMin: state.filters.courseGradeMin,
courseGradeMax: state.filters.courseGradeMax,
includeCourseRoleMembers: state.filters.includeCourseRoleMembers,
}
);

const ConnectedFilterBadges = connect(mapStateToProps)(FilterBadges);
export default ConnectedFilterBadges;

FilterBadge.propTypes = {
name: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired,
};

FilterBadges.defaultProps = {
assignment: initialFilters.assignmentType,
assignmentType: initialFilters.assignmentType,
Expand All @@ -152,6 +181,7 @@ FilterBadges.defaultProps = {
assignmentGradeMax: initialFilters.assignmentGradeMax,
courseGradeMin: initialFilters.courseGradeMin,
courseGradeMax: initialFilters.courseGradeMax,
includeCourseRoleMembers: initialFilters.includeCourseRoleMembers,
};

FilterBadges.propTypes = {
Expand All @@ -163,5 +193,6 @@ FilterBadges.propTypes = {
assignmentGradeMax: PropTypes.string,
courseGradeMin: PropTypes.string,
courseGradeMax: PropTypes.string,
includeCourseRoleMembers: PropTypes.bool,
handleFilterBadgeClose: PropTypes.func.isRequired,
};
13 changes: 13 additions & 0 deletions src/components/Gradebook/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Button,
Collapsible,
Icon,
CheckBox,
InputSelect,
InputText,
SearchField,
Expand Down Expand Up @@ -466,6 +467,15 @@ export default class Gradebook extends React.Component {
onChange={this.updateCohorts}
/>
</Collapsible>
<Collapsible title="Include Course Team Members" className="filter-group mb-3">
<CheckBox
name="include-course-team-members"
aria-label="Include Course Team Members"
label="Include Course Team Members"
checked={this.props.includeCourseRoleMembers}
onChange={this.props.updateIncludeCourseRoleMembers}
/>
</Collapsible>
</Drawer>
);
}
Expand All @@ -487,6 +497,7 @@ Gradebook.defaultProps = {
showSpinner: false,
totalUsersCount: null,
tracks: [],
includeCourseRoleMembers: false,
};

Gradebook.propTypes = {
Expand Down Expand Up @@ -524,4 +535,6 @@ Gradebook.propTypes = {
name: PropTypes.string,
})),
updateCourseGradeFilter: PropTypes.func.isRequired,
includeCourseRoleMembers: PropTypes.bool,
updateIncludeCourseRoleMembers: PropTypes.func.isRequired,
};
10 changes: 9 additions & 1 deletion src/containers/GradebookPage/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ import {
import { fetchCohorts } from '../../data/actions/cohorts';
import { fetchTracks } from '../../data/actions/tracks';
import {
initializeFilters, resetFilters, updateAssignmentFilter, updateAssignmentLimits, updateCourseGradeFilter,
initializeFilters,
resetFilters,
updateAssignmentFilter,
updateAssignmentLimits,
updateCourseGradeFilter,
updateIncludeCourseRoleMembers,
} from '../../data/actions/filters';
import stateHasMastersTrack from '../../data/selectors/tracks';
import {
Expand Down Expand Up @@ -73,6 +78,7 @@ const mapStateToProps = (state, ownProps) => (
),
courseGradeMin: formatMinCourseGrade(state.filters.courseGradeMin),
courseGradeMax: formatMaxCourseGrade(state.filters.courseGradeMax),
excludedCourseRoles: state.filters.includeCourseRoleMembers ? '' : 'all',
}),
grades: state.grades.results,
headings: getHeadings(state),
Expand Down Expand Up @@ -108,6 +114,7 @@ const mapStateToProps = (state, ownProps) => (
tracks: state.tracks.results,
uploadSuccess: !!(state.grades.bulkManagement
&& state.grades.bulkManagement.uploadSuccess),
includeCourseRoleMembers: state.filters.includeCourseRoleMembers,
}
);

Expand All @@ -131,6 +138,7 @@ const mapDispatchToProps = {
updateAssignmentFilter,
updateAssignmentLimits,
updateCourseGradeFilter,
updateIncludeCourseRoleMembers,
};

const GradebookPage = connect(
Expand Down
27 changes: 25 additions & 2 deletions src/data/actions/filters.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import initialFilters from '../constants/filters';
import {
INITIALIZE_FILTERS, RESET_FILTERS, UPDATE_ASSIGNMENT_FILTER, UPDATE_ASSIGNMENT_LIMITS, UPDATE_COURSE_GRADE_LIMITS,
INITIALIZE_FILTERS,
RESET_FILTERS,
UPDATE_ASSIGNMENT_FILTER,
UPDATE_ASSIGNMENT_LIMITS,
UPDATE_COURSE_GRADE_LIMITS,
UPDATE_INCLUDE_COURSE_ROLE_MEMBERS,
} from '../constants/actionTypes/filters';
import { getFilters } from '../selectors/filters';
import { fetchGrades } from './grades';

const initializeFilters = ({
assignment = initialFilters.assignment,
Expand All @@ -12,6 +19,7 @@ const initializeFilters = ({
assignmentGradeMax = initialFilters.assignmentGradeMax,
courseGradeMin = initialFilters.courseGradeMin,
courseGradeMax = initialFilters.assignmentGradeMax,
includeCourseRoleMembers = initialFilters.includeCourseRoleMembers,
}) => ({
type: INITIALIZE_FILTERS,
data: {
Expand All @@ -23,6 +31,7 @@ const initializeFilters = ({
assignmentGradeMax,
courseGradeMin,
courseGradeMax,
includeCourseRoleMembers,
},
});

Expand Down Expand Up @@ -50,7 +59,21 @@ const updateCourseGradeFilter = (courseGradeMin, courseGradeMax, courseId) => ({
},
});

const updateIncludeCourseRoleMembersFilter = (includeCourseRoleMembers) => ({
type: UPDATE_INCLUDE_COURSE_ROLE_MEMBERS,
data: {
includeCourseRoleMembers,
},
});

const updateIncludeCourseRoleMembers = includeCourseRoleMembers => (dispatch, getState) => {
dispatch(updateIncludeCourseRoleMembersFilter(includeCourseRoleMembers));
const state = getState();
const { cohort, track, assignmentType } = getFilters(state);
dispatch(fetchGrades(state.grades.courseId, cohort, track, assignmentType));
};

export {
initializeFilters, resetFilters, updateAssignmentFilter,
updateAssignmentLimits, updateCourseGradeFilter,
updateAssignmentLimits, updateCourseGradeFilter, updateIncludeCourseRoleMembers,
};
2 changes: 2 additions & 0 deletions src/data/actions/grades.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ const fetchGrades = (
assignmentGradeMin: assignmentMin,
courseGradeMin,
courseGradeMax,
includeCourseRoleMembers,
} = getFilters(getState());
const { id: assignmentId } = assignment || {};
const assignmentGradeMax = formatMaxAssignmentGrade(assignmentMax, { assignmentId });
Expand All @@ -158,6 +159,7 @@ const fetchGrades = (
assignmentGradeMin,
courseGradeMin: courseGradeMinFormatted,
courseGradeMax: courseGradeMaxFormatted,
includeCourseRoleMembers,
},

)
Expand Down
2 changes: 1 addition & 1 deletion src/data/actions/grades.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('actions', () => {
const expectedCohort = 1;
const expectedTrack = 'verified';
const expectedAssignmentType = 'Exam';
const fetchGradesURL = `${configuration.LMS_BASE_URL}/api/grades/v1/gradebook/${courseId}/?page_size=25&cohort_id=${expectedCohort}&enrollment_mode=${expectedTrack}`;
const fetchGradesURL = `${configuration.LMS_BASE_URL}/api/grades/v1/gradebook/${courseId}/?page_size=25&cohort_id=${expectedCohort}&enrollment_mode=${expectedTrack}&excluded_course_roles=all`;
const responseData = {
next: `${fetchGradesURL}&cursor=2344fda`,
previous: null,
Expand Down
3 changes: 2 additions & 1 deletion src/data/constants/actionTypes/filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ const RESET_FILTERS = 'RESET_FILTERS';
const UPDATE_ASSIGNMENT_FILTER = 'UPDATE_ASSIGNMENT_FILTER';
const UPDATE_ASSIGNMENT_LIMITS = 'UPDATE_ASSIGNMENT_LIMITS';
const UPDATE_COURSE_GRADE_LIMITS = 'UPDATE_COURSE_GRADE_LIMITS';
const UPDATE_INCLUDE_COURSE_ROLE_MEMBERS = 'UPDATE_INCLUDE_COURSE_ROLE_MEMBERS';
export {
INITIALIZE_FILTERS, RESET_FILTERS, UPDATE_ASSIGNMENT_FILTER,
UPDATE_ASSIGNMENT_LIMITS, UPDATE_COURSE_GRADE_LIMITS,
UPDATE_ASSIGNMENT_LIMITS, UPDATE_COURSE_GRADE_LIMITS, UPDATE_INCLUDE_COURSE_ROLE_MEMBERS,
};
1 change: 1 addition & 0 deletions src/data/constants/filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const initialFilters = {
assignmentGradeMax: '100',
courseGradeMin: '0',
courseGradeMax: '100',
includeCourseRoleMembers: false,
};

export default initialFilters;
12 changes: 11 additions & 1 deletion src/data/reducers/filters.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { GOT_GRADES, FILTER_BY_ASSIGNMENT_TYPE } from '../constants/actionTypes/grades';

import {
INITIALIZE_FILTERS, UPDATE_ASSIGNMENT_FILTER, UPDATE_ASSIGNMENT_LIMITS, UPDATE_COURSE_GRADE_LIMITS, RESET_FILTERS,
INITIALIZE_FILTERS,
UPDATE_ASSIGNMENT_FILTER,
UPDATE_ASSIGNMENT_LIMITS,
UPDATE_COURSE_GRADE_LIMITS,
RESET_FILTERS,
UPDATE_INCLUDE_COURSE_ROLE_MEMBERS,
} from '../constants/actionTypes/filters';

import initialFilters from '../constants/filters';
Expand Down Expand Up @@ -70,6 +75,11 @@ const reducer = (state = initialState, action) => {
courseGradeMin: action.data.courseGradeMin,
courseGradeMax: action.data.courseGradeMax,
};
case UPDATE_INCLUDE_COURSE_ROLE_MEMBERS:
return {
...state,
includeCourseRoleMembers: action.data.includeCourseRoleMembers,
};
default:
return state;
}
Expand Down
Loading

0 comments on commit 8bc1fc8

Please sign in to comment.