Fix the category filter
This commit is contained in:
@@ -52,134 +52,6 @@ export default class Gradebook extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
sortAlphaDesc = (gradeRowA, gradeRowB) => {
|
||||
const a = gradeRowA.username.toUpperCase();
|
||||
const b = gradeRowB.username.toUpperCase();
|
||||
if (a < b) {
|
||||
return -1;
|
||||
}
|
||||
if (a > b) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
sortAlphaAsc = (gradeRowA, gradeRowB) => {
|
||||
const a = gradeRowA.username.toUpperCase();
|
||||
const b = gradeRowB.username.toUpperCase();
|
||||
if (a < b) {
|
||||
return 1;
|
||||
}
|
||||
if (a > b) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
sortNumerically = (colKey, direction) => {
|
||||
function sortNumAsc(gradeRowA, gradeRowB) {
|
||||
if (gradeRowA[colKey] < gradeRowB[colKey]) {
|
||||
return -1;
|
||||
}
|
||||
if (gradeRowA[colKey] > gradeRowB[colKey]) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function sortNumDesc(gradeRowA, gradeRowB) {
|
||||
if (gradeRowA[colKey] < gradeRowB[colKey]) {
|
||||
return 1;
|
||||
}
|
||||
if (gradeRowA[colKey] > gradeRowB[colKey]) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
this.setState({ grades: [...this.state.grades].sort(direction === 'desc' ? sortNumDesc : sortNumAsc) });
|
||||
}
|
||||
|
||||
mapHeadings = (entry) => {
|
||||
if (entry) {
|
||||
const results = [{
|
||||
label: 'Username',
|
||||
key: 'username',
|
||||
columnSortable: true,
|
||||
onSort: (direction) => {
|
||||
this.setState({
|
||||
grades: [...this.state.grades].sort(direction === 'desc' ? this.sortAlphaDesc : this.sortAlphaAsc),
|
||||
});
|
||||
},
|
||||
}];
|
||||
|
||||
const assignmentHeadings = entry.section_breakdown
|
||||
.filter(section => section.is_graded && section.label)
|
||||
.map(s => ({
|
||||
label: s.label,
|
||||
key: s.label,
|
||||
columnSortable: true,
|
||||
onSort: (direction) => { this.sortNumerically(s.label, direction); },
|
||||
}));
|
||||
|
||||
const totals = [{
|
||||
label: 'Total',
|
||||
key: 'total',
|
||||
columnSortable: true,
|
||||
onSort: (direction) => { this.sortNumerically('total', direction); },
|
||||
}];
|
||||
|
||||
return results.concat(assignmentHeadings).concat(totals);
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
mapHeadingsHw = (entry) => {
|
||||
const results = [{
|
||||
label: 'Username',
|
||||
key: 'username',
|
||||
columnSortable: true,
|
||||
onSort: (direction) => {
|
||||
this.setState({
|
||||
grades: [...this.state.grades].sort(direction === 'desc' ? this.sortAlphaDesc : this.sortAlphaAsc),
|
||||
});
|
||||
},
|
||||
}];
|
||||
const assignmentHeadings = entry.section_breakdown
|
||||
.filter(section => section.is_graded && section.label && section.category == 'Homework')
|
||||
.map(s => ({
|
||||
label: s.label,
|
||||
key: s.label,
|
||||
columnSortable: true,
|
||||
onSort: (direction) => { this.sortNumerically(s.label, direction); },
|
||||
}));
|
||||
|
||||
return results.concat(assignmentHeadings);
|
||||
};
|
||||
|
||||
mapHeadingsExam = (entry) => {
|
||||
const results = [{
|
||||
label: 'Username',
|
||||
key: 'username',
|
||||
columnSortable: true,
|
||||
onSort: (direction) => {
|
||||
this.setState({
|
||||
grades: [...this.state.grades].sort(direction === 'desc' ? this.sortAlphaDesc : this.sortAlphaAsc),
|
||||
});
|
||||
},
|
||||
}];
|
||||
const assignmentHeadings = entry.section_breakdown
|
||||
.filter(section => section.is_graded && section.label && section.category == 'Exam')
|
||||
.map(s => ({
|
||||
label: s.label,
|
||||
key: s.label,
|
||||
columnSortable: true,
|
||||
onSort: (direction) => { this.sortNumerically(s.label, direction); },
|
||||
}));
|
||||
|
||||
return results.concat(assignmentHeadings);
|
||||
};
|
||||
|
||||
handleAdjustedGradeClick = () => {
|
||||
this.props.updateGrades(this.props.match.params.courseId, [
|
||||
{
|
||||
@@ -345,8 +217,7 @@ export default class Gradebook extends React.Component {
|
||||
type="radio"
|
||||
name="category"
|
||||
value="all"
|
||||
onClick={() =>
|
||||
this.setState({ headings: this.mapHeadings(this.props.results[0]) })}
|
||||
onClick={() => this.props.filterColumns('all', this.props.grades[0])}
|
||||
/>
|
||||
All
|
||||
</label>
|
||||
@@ -358,10 +229,7 @@ export default class Gradebook extends React.Component {
|
||||
type="radio"
|
||||
name="category"
|
||||
value="homework"
|
||||
onClick={() =>
|
||||
this.setState({
|
||||
headings: this.mapHeadingsHw(this.props.results[0]),
|
||||
})}
|
||||
onClick={() => this.props.filterColumns('hw', this.props.grades[0])}
|
||||
/>
|
||||
<label className="ml-2 mr-2" htmlFor="category-homework">Homework</label>
|
||||
</span>
|
||||
@@ -372,7 +240,7 @@ export default class Gradebook extends React.Component {
|
||||
type="radio"
|
||||
name="category"
|
||||
value="exam"
|
||||
onClick={() => this.setState({ headings: this.mapHeadingsExam(this.props.results[0]) })}
|
||||
onClick={() => this.props.filterColumns('exam', this.props.grades[0])}
|
||||
/>
|
||||
Exam
|
||||
</label>
|
||||
@@ -417,9 +285,8 @@ export default class Gradebook extends React.Component {
|
||||
<br />
|
||||
<div className="gbook">
|
||||
<Table
|
||||
columns={this.mapHeadings(this.props.grades[0])}
|
||||
columns={this.props.headings}
|
||||
data={this.formatter[this.props.format](this.props.grades)}
|
||||
tableSortable
|
||||
defaultSortDirection="desc"
|
||||
defaultSortedColumn="username"
|
||||
/>
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
fetchMatchingUserGrades,
|
||||
updateGrades,
|
||||
toggleGradeFormat,
|
||||
filterColumns,
|
||||
} from '../../data/actions/grades';
|
||||
import { fetchCohorts } from '../../data/actions/cohorts';
|
||||
import { fetchTracks } from '../../data/actions/tracks';
|
||||
@@ -13,6 +14,7 @@ import { fetchTracks } from '../../data/actions/tracks';
|
||||
const mapStateToProps = state => (
|
||||
{
|
||||
grades: state.grades.results,
|
||||
headings: state.grades.headings,
|
||||
tracks: state.tracks.results,
|
||||
cohorts: state.cohorts.results,
|
||||
selectedTrack: state.grades.selectedTrack,
|
||||
@@ -41,6 +43,9 @@ const mapDispatchToProps = dispatch => (
|
||||
toggleFormat: (formatType) => {
|
||||
dispatch(toggleGradeFormat(formatType));
|
||||
},
|
||||
filterColumns: (filterType, exampleUser) => {
|
||||
dispatch(filterColumns(filterType, exampleUser));
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -7,17 +7,21 @@ import {
|
||||
GRADE_UPDATE_SUCCESS,
|
||||
GRADE_UPDATE_FAILURE,
|
||||
TOGGLE_GRADE_FORMAT,
|
||||
SORT_GRADES,
|
||||
FILTER_COLUMNS,
|
||||
} from '../constants/actionTypes/grades';
|
||||
import LmsApiService from '../services/LmsApiService';
|
||||
import { headingMapper } from './utils';
|
||||
|
||||
const startedFetchingGrades = () => ({ type: STARTED_FETCHING_GRADES });
|
||||
const finishedFetchingGrades = () => ({ type: FINISHED_FETCHING_GRADES });
|
||||
const errorFetchingGrades = () => ({ type: ERROR_FETCHING_GRADES });
|
||||
const gotGrades = (grades, cohort, track) => ({
|
||||
const gotGrades = (grades, cohort, track, headings) => ({
|
||||
type: GOT_GRADES,
|
||||
grades,
|
||||
cohort,
|
||||
track,
|
||||
headings,
|
||||
});
|
||||
|
||||
const gradeUpdateRequest = () => ({ type: GRADE_UPDATE_REQUEST });
|
||||
@@ -32,7 +36,12 @@ const gradeUpdateFailure = error => ({
|
||||
|
||||
|
||||
const toggleGradeFormat = formatType => ({ type: TOGGLE_GRADE_FORMAT, formatType });
|
||||
const sortGrades = (columnName, direction) => ({ type: SORT_GRADES, columnName, direction });
|
||||
|
||||
const filterColumns = (filterType, exampleUser) => ({
|
||||
type: FILTER_COLUMNS,
|
||||
headings: headingMapper[filterType](exampleUser)
|
||||
});
|
||||
|
||||
const fetchGrades = (courseId, cohort, track) => (
|
||||
(dispatch) => {
|
||||
@@ -40,7 +49,7 @@ const fetchGrades = (courseId, cohort, track) => (
|
||||
return LmsApiService.fetchGradebookData(courseId, null, cohort, track)
|
||||
.then(response => response.data)
|
||||
.then((data) => {
|
||||
dispatch(gotGrades(data.results, cohort, track));
|
||||
dispatch(gotGrades(data.results, cohort, track, headingMapper.all(data.results[0])));
|
||||
dispatch(finishedFetchingGrades());
|
||||
})
|
||||
.catch(() => {
|
||||
@@ -70,7 +79,7 @@ const updateGrades = (courseId, updateData) => (
|
||||
return LmsApiService.updateGradebookData(courseId, updateData)
|
||||
.then(response => response.data)
|
||||
.then((data) => {
|
||||
dispatch(gradeUpdateSuccess(data))
|
||||
dispatch(gradeUpdateSuccess(data));
|
||||
})
|
||||
.catch((error) => {
|
||||
dispatch(gradeUpdateFailure(error));
|
||||
@@ -90,4 +99,6 @@ export {
|
||||
gradeUpdateFailure,
|
||||
updateGrades,
|
||||
toggleGradeFormat,
|
||||
sortGrades,
|
||||
filterColumns,
|
||||
};
|
||||
|
||||
131
src/data/actions/utils.js
Normal file
131
src/data/actions/utils.js
Normal file
@@ -0,0 +1,131 @@
|
||||
|
||||
const sortAlphaDesc = (gradeRowA, gradeRowB) => {
|
||||
const a = gradeRowA.username.toUpperCase();
|
||||
const b = gradeRowB.username.toUpperCase();
|
||||
if (a < b) {
|
||||
return -1;
|
||||
}
|
||||
if (a > b) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
const sortAlphaAsc = (gradeRowA, gradeRowB) => {
|
||||
const a = gradeRowA.username.toUpperCase();
|
||||
const b = gradeRowB.username.toUpperCase();
|
||||
if (a < b) {
|
||||
return 1;
|
||||
}
|
||||
if (a > b) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
const sortNumerically = (colKey, direction) => {
|
||||
function sortNumAsc(gradeRowA, gradeRowB) {
|
||||
if (gradeRowA[colKey] < gradeRowB[colKey]) {
|
||||
return -1;
|
||||
}
|
||||
if (gradeRowA[colKey] > gradeRowB[colKey]) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function sortNumDesc(gradeRowA, gradeRowB) {
|
||||
if (gradeRowA[colKey] < gradeRowB[colKey]) {
|
||||
return 1;
|
||||
}
|
||||
if (gradeRowA[colKey] > gradeRowB[colKey]) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
this.setState({ grades: [...this.state.grades].sort(direction === 'desc' ? sortNumDesc : sortNumAsc) });
|
||||
};
|
||||
const headingMapper = {
|
||||
all: (entry) => {
|
||||
if (entry) {
|
||||
const results = [{
|
||||
label: 'Username',
|
||||
key: 'username',
|
||||
columnSortable: true,
|
||||
onSort: (direction) => {
|
||||
this.setState({
|
||||
grades: [...this.state.grades].sort(direction === 'desc' ? this.sortAlphaDesc : this.sortAlphaAsc),
|
||||
});
|
||||
},
|
||||
}];
|
||||
|
||||
const assignmentHeadings = entry.section_breakdown
|
||||
.filter(section => section.is_graded && section.label)
|
||||
.map(s => ({
|
||||
label: s.label,
|
||||
key: s.label,
|
||||
columnSortable: true,
|
||||
onSort: (direction) => { this.sortNumerically(s.label, direction); },
|
||||
}));
|
||||
|
||||
const totals = [{
|
||||
label: 'Total',
|
||||
key: 'total',
|
||||
columnSortable: true,
|
||||
onSort: (direction) => { this.sortNumerically('total', direction); },
|
||||
}];
|
||||
|
||||
return results.concat(assignmentHeadings).concat(totals);
|
||||
}
|
||||
return [];
|
||||
},
|
||||
hw: (entry) => {
|
||||
const results = [{
|
||||
label: 'Username',
|
||||
key: 'username',
|
||||
columnSortable: true,
|
||||
onSort: (direction) => {
|
||||
this.setState({
|
||||
grades: [...this.state.grades].sort(direction === 'desc' ? this.sortAlphaDesc : this.sortAlphaAsc),
|
||||
});
|
||||
},
|
||||
}];
|
||||
|
||||
const assignmentHeadings = entry.section_breakdown
|
||||
.filter(section => section.is_graded && section.label && section.category == 'Homework')
|
||||
.map(s => ({
|
||||
label: s.label,
|
||||
key: s.label,
|
||||
columnSortable: false,
|
||||
onSort: (direction) => { this.sortNumerically(s.label, direction); },
|
||||
}));
|
||||
|
||||
return results.concat(assignmentHeadings);
|
||||
},
|
||||
exam: (entry) => {
|
||||
const results = [{
|
||||
label: 'Username',
|
||||
key: 'username',
|
||||
columnSortable: false,
|
||||
onSort: (direction) => {
|
||||
this.setState({
|
||||
grades: [...this.state.grades].sort(direction === 'desc' ? this.sortAlphaDesc : this.sortAlphaAsc),
|
||||
});
|
||||
},
|
||||
}];
|
||||
|
||||
const assignmentHeadings = entry.section_breakdown
|
||||
.filter(section => section.is_graded && section.label && section.category == 'Exam')
|
||||
.map(s => ({
|
||||
label: s.label,
|
||||
key: s.label,
|
||||
columnSortable: false,
|
||||
onSort: (direction) => { this.sortNumerically(s.label, direction); },
|
||||
}));
|
||||
|
||||
return results.concat(assignmentHeadings);
|
||||
},
|
||||
};
|
||||
|
||||
export { headingMapper };
|
||||
@@ -8,6 +8,8 @@ const GRADE_UPDATE_SUCCESS = 'GRADE_UPDATE_SUCCESS';
|
||||
const GRADE_UPDATE_FAILURE = 'GRADE_UPDATE_FAILURE';
|
||||
|
||||
const TOGGLE_GRADE_FORMAT = 'TOGGLE_GRADE_FORMAT';
|
||||
const SORT_GRADES = 'SORT_GRADES';
|
||||
const FILTER_COLUMNS = 'FILTER_COLUMNS';
|
||||
|
||||
export {
|
||||
STARTED_FETCHING_GRADES,
|
||||
@@ -18,4 +20,6 @@ export {
|
||||
GRADE_UPDATE_SUCCESS,
|
||||
GRADE_UPDATE_FAILURE,
|
||||
TOGGLE_GRADE_FORMAT,
|
||||
SORT_GRADES,
|
||||
FILTER_COLUMNS,
|
||||
};
|
||||
|
||||
@@ -3,10 +3,12 @@ import {
|
||||
ERROR_FETCHING_GRADES,
|
||||
GOT_GRADES,
|
||||
TOGGLE_GRADE_FORMAT,
|
||||
FILTER_COLUMNS,
|
||||
} from '../constants/actionTypes/grades';
|
||||
|
||||
const initialState = {
|
||||
results: [],
|
||||
headings: [],
|
||||
startedFetching: false,
|
||||
finishedFetching: false,
|
||||
errorFetching: false,
|
||||
@@ -19,6 +21,7 @@ const grades = (state = initialState, action) => {
|
||||
return {
|
||||
...state,
|
||||
results: action.grades,
|
||||
headings: action.headings,
|
||||
finishedFetching: true,
|
||||
errorFetching: false,
|
||||
selectedTrack: action.track,
|
||||
@@ -41,6 +44,11 @@ const grades = (state = initialState, action) => {
|
||||
...state,
|
||||
gradeFormat: action.formatType,
|
||||
};
|
||||
case FILTER_COLUMNS:
|
||||
return {
|
||||
...state,
|
||||
headings: action.headings,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user