Compare commits

...

11 Commits

Author SHA1 Message Date
Alex Dusenbery
6f752f3a18 fix(auth): Pin frontend-auth to 1.1.0 for now. 2018-11-14 13:35:09 -05:00
Alex Dusenbery
7bbc9a84dc fix(auth): use frontend-auth 1.2.0 (allows us to POST without CSRF violation). 2018-11-14 12:12:13 -05:00
Simon Chen
85cf3e35e4 Merge pull request #9 from edx/aed/prod-env
fix(packaging): Add default environment key/value pairs to prod webpack config
2018-11-14 10:35:40 -05:00
Alex Dusenbery
85fa6bca72 fix(packaging): Add default environment key/value pairs to prod webpack config. 2018-11-14 10:23:38 -05:00
Simon Chen
231685e78d Merge pull request #7 from edx/schen/cohorts
Create the cohorts and track dropdown for filtering students
2018-11-13 21:49:21 -05:00
Simon Chen
a4dc135129 feat(filter): Create the cohorts and track dropdown for filtering students
This is to provide the feature to filter students on the gradebook by
cohorts or enrollment tracks
2018-11-13 21:33:11 -05:00
Alex Dusenbery
2c890e53f8 Get the basic grade update working. 2018-11-13 13:03:50 -05:00
Richard I Reilly
33556fd749 Merge pull request #4 from edx/rir/hookup-redux
Hook up redux to get data for component
2018-11-09 15:58:35 -05:00
Rick Reilly
8a62e8b710 Hook search up to the backend 2018-11-09 15:54:05 -05:00
Alex Dusenbery
45272dd8b7 feat(auth): Use the frontend-auth client
- Also add some config
2018-11-09 14:42:08 -05:00
Rick Reilly
f94a0bd7f7 Hook up redux to get data for component 2018-11-09 14:42:08 -05:00
22 changed files with 7413 additions and 6278 deletions

6
.gitignore vendored
View File

@@ -6,4 +6,8 @@ coverage
dist/
.python-version
### pyenv ###
.python-version
### Emacs ###
*~

View File

@@ -73,6 +73,21 @@ module.exports = Merge.smart(commonConfig, {
inject: true, // Appends script tags linking to the webpack bundles at the end of the body
template: path.resolve(__dirname, '../public/index.html'),
}),
new webpack.EnvironmentPlugin({
NODE_ENV: 'development',
BASE_URL: 'localhost:1991',
LMS_BASE_URL: 'http://localhost:18000',
LOGIN_URL: 'http://localhost:18000/login',
LOGOUT_URL: 'http://localhost:18000/login',
REFRESH_ACCESS_TOKEN_ENDPOINT: 'http://localhost:18000/login',
DATA_API_BASE_URL: 'http://localhost:8000',
// LMS_CLIENT_ID should match the lms DOT client application id your LMS container
LMS_CLIENT_ID: 'login-service-client-id',
SEGMENT_KEY: null,
FEATURE_FLAGS: {},
ACCESS_TOKEN_COOKIE_NAME: 'edx-jwt-cookie-header-payload',
CSRF_COOKIE_NAME: 'csrftoken',
}),
// when the --hot option is not passed in as part of the command
// the HotModuleReplacementPlugin has to be specified in the Webpack configuration
// https://webpack.js.org/configuration/dev-server/#devserver-hot

View File

@@ -3,6 +3,7 @@
const Merge = require('webpack-merge');
const commonConfig = require('./webpack.common.config.js');
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
@@ -91,5 +92,20 @@ module.exports = Merge.smart(commonConfig, {
inject: true, // Appends script tags linking to the webpack bundles at the end of the body
template: path.resolve(__dirname, '../public/index.html'),
}),
new webpack.EnvironmentPlugin({
NODE_ENV: 'production',
BASE_URL: null,
LMS_BASE_URL: null,
LOGIN_URL: null,
LOGOUT_URL: null,
REFRESH_ACCESS_TOKEN_ENDPOINT: null,
DATA_API_BASE_URL: null,
SEGMENT_KEY: null,
FEATURE_FLAGS: {},
ACCESS_TOKEN_COOKIE_NAME: null,
CSRF_COOKIE_NAME: 'csrftoken',
NEW_RELIC_APP_ID: null,
NEW_RELIC_LICENSE_KEY: null,
}),
],
});

10702
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -25,14 +25,15 @@
},
"dependencies": {
"@edx/edx-bootstrap": "^0.4.3",
"@edx/frontend-auth": "^1.0.3",
"@edx/paragon": "^3.5.2",
"@edx/frontend-auth": "1.1.0",
"@edx/paragon": "^3.7.0",
"babel-polyfill": "^6.26.0",
"classnames": "^2.2.5",
"email-prop-type": "^1.1.5",
"font-awesome": "^4.7.0",
"history": "^4.7.2",
"prop-types": "^15.5.10",
"query-string": "^6.2.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-redux": "^5.0.7",

View File

@@ -1,3 +1,12 @@
.student-filters{
display: flex;
.label{
padding-top: 30px;
}
.form-group{
margin-left: 10px;
}
}
.gbook {
overflow-x: scroll;
@@ -21,6 +30,7 @@
background-color: #fff;
}
.table tr td:not(:first-child) {
//not real sylz. plz kill before prod
min-width: 250px;
}
.table tr td:nth-child(2) {

View File

@@ -1,24 +1,37 @@
import React from 'react';
import PropTypes from 'prop-types';
import emailPropType from 'email-prop-type';
import { SearchField, Table, Modal } from '@edx/paragon';
import { Button, Modal, SearchField, Table, InputSelect } from '@edx/paragon';
import queryString from 'query-string';
export default class Gradebook extends React.Component {
constructor(props) {
super(props);
this.state = {
grades: this.mapUserEnteriesPercent(this.props.results).sort(this.sortAlphaDesc),
headings: this.mapHeadings(this.props.results[0]),
grades: [], // this.mapUserEntriesPercent(this.props.grades).sort(this.sortAlphaDesc),
headings: [], // this.mapHeadings(this.props.grades[0]),
filterValue: '',
modalContent: (<h1>Hello, World!</h1>),
modalOpen: false,
modalModel: [{}],
updateVal: 0,
updateModuleId: null,
updateUserId: null,
};
}
componentDidMount() {
const urlQuery = queryString.parse(this.props.location.search);
this.props.getUserGrades(
this.props.match.params.courseId,
urlQuery.cohort,
urlQuery.track,
);
this.props.getTracks(this.props.match.params.courseId);
this.props.getCohorts(this.props.match.params.courseId);
}
sortAlphaDesc = (gradeRowA, gradeRowB) => {
const a = gradeRowA.username.toUpperCase();
const b = gradeRowB.username.toUpperCase();
@@ -53,7 +66,7 @@ export default class Gradebook extends React.Component {
}
return 0;
}
function sortNumDesc(gradeRowA, gradeRowB) {
if (gradeRowA[colKey] < gradeRowB[colKey]) {
return 1;
@@ -62,261 +75,383 @@ export default class Gradebook extends React.Component {
return -1;
}
return 0;
};
}
this.setState({grades: [...this.state.grades].sort(direction === 'desc' ? sortNumDesc : sortNumAsc)});
this.setState({ grades: [...this.state.grades].sort(direction === 'desc' ? sortNumDesc : sortNumAsc) });
}
mapHeadings = entry => {
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 => {
onSort: (direction) => {
this.setState({
grades: [...this.state.grades].sort(direction === 'desc' ? this.sortAlphaDesc : this.sortAlphaAsc)
})
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);
};
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' )
.filter(section => section.is_graded && section.label && section.category == 'Homework')
.map(s => ({
label: s.label,
label: s.label,
key: s.label,
columnSortable: true,
onSort: direction => {this.sortNumerically(s.label, direction)},
onSort: (direction) => { this.sortNumerically(s.label, direction); },
}));
return results.concat(assignmentHeadings);
};
mapHeadingsExam = entry => {
mapHeadingsExam = (entry) => {
const results = [{
label: 'Username',
key: 'username',
columnSortable: true,
onSort: direction => {
onSort: (direction) => {
this.setState({
grades: [...this.state.grades].sort(direction === 'desc' ? this.sortAlphaDesc : this.sortAlphaAsc)
})
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' )
.filter(section => section.is_graded && section.label && section.category == 'Exam')
.map(s => ({
label: s.label,
label: s.label,
key: s.label,
columnSortable: true,
onSort: direction => {this.sortNumerically(s.label, direction)},
onSort: (direction) => { this.sortNumerically(s.label, direction); },
}));
return results.concat(assignmentHeadings);
};
mapUserEnteriesPercent = (entries) => entries.map(entry => {
const results = {username: entry.username};
setNewModalState = (userEntry, subsection) => {
this.setState({
modalModel: [{
username: userEntry.username,
currentGrade: `${subsection.score_earned}/${subsection.score_possible}`,
adjustedGrade: (
<span>
<input
style={{ width: '25px' }}
type="text"
onChange={(event) => this.setState({updateVal: event.target.value})}
/> / {subsection.score_possible}
</span>
),
assignmentName: `${subsection.subsection_name}`,
}],
modalOpen: true,
updateModuleId: subsection.module_id,
updateUserId: userEntry.user_id,
})
}
mapUserEntriesPercent = entries => entries.map((entry) => {
const results = { username: entry.username };
const assignments = entry.section_breakdown
.filter(section => section.is_graded)
.reduce((acc,s) => {
acc[s.label]= (
<button
.reduce((acc, subsection) => {
acc[subsection.label] = (
<button
className="btn btn-header link-style"
onClick={()=> this.setState({
modalModel: [{
username: entry.username,
autoGrade: `${s.score_earned}/${s.score_possible}`,
adjustedGrade: (<span><input style={{width: '25px'}} type='text' value={this.updateVal}></input> / {s.score_possible}</span>),
assignmentName: `${s.subsection_name}`,
}],
modalOpen: true,
})}
onClick={() => this.setNewModalState(entry, subsection)}
>
{s.percent}
{subsection.percent}
</button>);
return acc;
}, {});
const totals = {total: entry.percent * 100}
return acc;
}, {});
const totals = { total: entry.percent * 100 };
return Object.assign(results, assignments, totals);
});
mapUserEnteriesAbsolute = (entries) => entries.map(entry => {
const results = {username: entry.username};
mapUserEntriesAbsolute = entries => entries.map((entry) => {
const results = { username: entry.username };
const assignments = entry.section_breakdown
.filter(section => section.is_graded)
.reduce((acc,s) => {
acc[s.label]= (
<button
.reduce((acc, subsection) => {
acc[subsection.label] = (
<button
className="btn btn-header link-style"
onClick={()=> this.setState({
modalModel: [{
username: entry.username,
autoGrade: `${s.score_earned}/${s.score_possible}`,
adjustedGrade: (<span><input style={{width: '25px'}} type='text' value={this.updateVal}></input> / {s.score_possible}</span>),
assignmentName: `${s.subsection_name}`,
}],
modalOpen: true,
})}
onClick={() => this.setNewModalState(entry, subsection)}
>
{s.score_earned}/{s.score_possible}
{subsection.score_earned}/{subsection.score_possible}
</button>);
//TODO: This is a really hacky thing I'm doing just to get sorting to work. Should be able to clean this up drastically when I introduce the reducers
acc[`${s.label}Percent`] = s.percent
return acc;
}, {});
return acc;
}, {});
const totals = {total: entry.percent * 100}
const totals = { total: entry.percent * 100 };
return Object.assign(results, assignments, totals);
});
handleAdjustedGradeClick = () => {
this.props.updateGrades(this.props.match.params.courseId, [
{
'user_id': this.state.updateUserId,
'usage_id': this.state.updateModuleId,
'grade': {
'earned_graded_override': this.state.updateVal,
},
},
]);
}
updateQueryParams = (queryKey, queryValue) => {
const parsed = queryString.parse(this.props.location.search);
parsed[queryKey] = queryValue;
return `?${queryString.stringify(parsed)}`;
};
mapCohortsEntries = (entries) => {
let mapped = entries.map(entry => ({
id: entry.id,
label: entry.name,
}));
mapped.unshift({id:0, label:'Cohorts'});
return mapped;
};
mapTracksEntries = (entries) => {
let mapped = entries.map(entry => ({
id: entry.slug,
label: entry.name,
}));
mapped.unshift({ label:'Tracks' });
return mapped;
};
updateTracks = (event) => {
const selectedTrackItem = this.props.tracks.find(x=>x.name===event);
let selectedTrackSlug = null;
if(selectedTrackItem) {
selectedTrackSlug = selectedTrackItem.slug;
}
this.props.getUserGrades(
this.props.match.params.courseId,
this.props.selectedCohort,
selectedTrackSlug,
);
const updatedQueryStrings = this.updateQueryParams('track', selectedTrackSlug)
this.props.history.push(updatedQueryStrings);
};
updateCohorts = (event) => {
const selectedCohortItem = this.props.cohorts.find(x=>x.name===event);
let selectedCohortId = null;
if(selectedCohortItem) {
selectedCohortId = selectedCohortItem.id;
}
this.props.getUserGrades(
this.props.match.params.courseId,
selectedCohortId,
this.props.selectedTrack,
);
const updatedQueryStrings = this.updateQueryParams('cohort', selectedCohortId)
this.props.history.push(updatedQueryStrings);
};
mapSelectedCohortEntry = (entry) => {
const selectedCohortEntry = this.props.cohorts.find(x => x.id === parseInt(entry, 10));
if (selectedCohortEntry) {
return selectedCohortEntry.name;
}
return 'Cohorts';
};
mapSelectedTrackEntry = (entry) => {
const selectedTrackEntry = this.props.tracks.find(x => x.slug === entry);
if (selectedTrackEntry) {
return selectedTrackEntry.name;
}
return 'Tracks';
};
render() {
return (
<div className="d-flex justify-content-center">
<div className="card" style={{width: '50rem'}}>
<div className="card" style={{ width: '50rem' }}>
<div className="card-body">
<h1>Gradebook</h1>
<hr/>
<hr />
<div className="d-flex justify-content-between" >
<div>
<div>
Score View:
Score View:
<span>
<input
id='score-view-percent'
className='ml-2'
type='radio'
name='score-view'
value='percent'
onClick={()=> {this.setState({
grades: this.mapUserEnteriesPercent(this.props.results).sort(this.sortAlphaDesc),
})}}
<input
id="score-view-percent"
className="ml-2"
type="radio"
name="score-view"
value="percent"
onClick={() => this.setState({ grades: this.mapUserEntriesPercent(this.props.results).sort(this.sortAlphaDesc) })}
/>
<label className='ml-2 mr-2' htmlFor='score-view-percent'>Percent</label>
<label className="ml-2 mr-2" htmlFor="score-view-percent">Percent</label>
</span>
<span>
<input
id='score-view-absolute'
type='radio'
name='score-view'
value='absolute'
onClick={()=> {this.setState({
grades: this.mapUserEnteriesAbsolute(this.props.results).sort(this.sortAlphaDesc),
})}}
<input
id="score-view-absolute"
type="radio"
name="score-view"
value="absolute"
onClick={() => this.setState({ grades: this.mapUserEntriesAbsolute(this.props.results).sort(this.sortAlphaDesc) })}
/>
<label className='ml-2 mr-2' htmlFor='score-view-absolute'>Absolute</label>
<label className="ml-2 mr-2" htmlFor="score-view-absolute">Absolute</label>
</span>
</div>
<div>
Category:
Category:
<span>
<input
id='category-all'
className='ml-2'
type='radio'
name='category'
value='all'
onClick={()=> {this.setState({
headings: this.mapHeadings(this.props.results[0]),
})}}
/>
<label className='ml-2 mr-2' htmlFor='category-all'>All</label>
<label className="ml-2 mr-2" htmlFor="category-all">
<input
id="category-all"
className="ml-2"
type="radio"
name="category"
value="all"
onClick={() =>
this.setState({ headings: this.mapHeadings(this.props.results[0]) })}
/>
All
</label>
</span>
<span>
<input
id='category-homework'
className='ml-2'
type='radio'
name='category'
value='homework'
onClick={()=> {this.setState({
<input
id="category-homework"
className="ml-2"
type="radio"
name="category"
value="homework"
onClick={() =>
this.setState({
headings: this.mapHeadingsHw(this.props.results[0]),
})}}
})}
/>
<label className='ml-2 mr-2' htmlFor='category-homework'>Homework</label>
<label className="ml-2 mr-2" htmlFor="category-homework">Homework</label>
</span>
<span>
<input
id='category-exam'
type='radio'
name='category'
value='exam'
onClick={()=> {this.setState({
headings: this.mapHeadingsExam(this.props.results[0]),
})}}
/>
<label className='ml-2 mr-2' htmlFor='Exam'>Exam</label>
<label className="ml-2 mr-2" htmlFor="Exam">
<input
id="category-exam"
type="radio"
name="category"
value="exam"
onClick={() => this.setState({ headings: this.mapHeadingsExam(this.props.results[0]) })}
/>
Exam
</label>
</span>
</div>
{(this.props.tracks.length > 0 || this.props.cohorts.length > 0) &&
<div className="student-filters">
<span className="label">
Student Groups:
</span>
{this.props.tracks.length > 0 &&
<InputSelect
name='Tracks'
value={this.mapSelectedTrackEntry(this.props.selectedTrack)}
options={this.mapTracksEntries(this.props.tracks)}
onChange={this.updateTracks}
/>
}
{this.props.cohorts.length > 0 &&
<InputSelect
name='Cohorts'
value={this.mapSelectedCohortEntry(this.props.selectedCohort)}
options={this.mapCohortsEntries(this.props.cohorts)}
onChange={this.updateCohorts}
/>
}
</div>
}
</div>
<div>
<div style={{marginLeft: "10px" ,marginBottom: "10px"}}>
<div style={{ marginLeft: '10px', marginBottom: '10px' }}>
<a href="https://www.google./com">Download Grade Report</a>
</div>
<SearchField
onSubmit={() => {this.setState({
grades: this.mapUserEnteriesPercent(this.props.results).filter(entry => entry.username == '' || entry.username.includes(this.state.filterValue))
})}}
onChange={filterValue => this.setState({filterValue})}
onClear={() => {this.setState({grades: this.mapUserEnteriesPercent(this.props.results).sort(this.sortAlphaDesc)})}}
<SearchField
onSubmit={value => this.props.searchForUser(this.props.match.params.courseId, value, this.props.selectedCohort, this.props.selectedTrack)}
onChange={filterValue => this.setState({ filterValue })}
onClear={() => this.props.getUserGrades(this.props.match.params.courseId, this.props.selectedCohort, this.props.selectedTrack)}
value={this.state.filterValue}
/>
</div>
</div>
<br/>
<br />
<div className="gbook">
<Table
columns={this.state.headings}
data={this.state.grades}
tableSortable={true}
defaultSortDirection='desc'
defaultSortedColumn='username'
columns={this.mapHeadings(this.props.grades[0])}
data={this.mapUserEntriesPercent(this.props.grades)}
tableSortable
defaultSortDirection="desc"
defaultSortedColumn="username"
/>
</div>
<Modal
open={this.state.modalOpen}
title="Edit Grades"
body={(
<div>
<h3>{this.state.modalModel[0].assignmentName}</h3>
<Table
columns={[{label: 'Username', key: 'username',},{label: 'Auto grade',key: 'autoGrade',},{label: 'Adjusted grade',key: 'adjustedGrade',}]}
open={this.state.modalOpen}
title="Edit Grades"
body={(
<div>
<h3>{this.state.modalModel[0].assignmentName}</h3>
<Table
columns={[{ label: 'Username', key: 'username' }, { label: 'Current grade', key: 'currentGrade' }, { label: 'Adjusted grade', key: 'adjustedGrade' }]}
data={this.state.modalModel}
tableSortable={true}
defaultSortDirection='desc'
defaultSortedColumn='username'
tableSortable
defaultSortDirection="desc"
defaultSortedColumn="username"
/>
</div>
)}
onClose={()=> this.setState({modalOpen: false,})}
</div>
)}
buttons={[
<Button
label="Edit Grade"
buttonType="primary"
onClick={this.handleAdjustedGradeClick}
/>
]}
onClose={() => this.setState({
modalOpen: false,
modalModel: [{}],
updateVal: 0,
updateModuleId: null,
updateUserId: null,
})}
/>
</div>
</div>
@@ -325,1019 +460,3 @@ export default class Gradebook extends React.Component {
}
}
Gradebook.defaultProps = {
"results": [
{
"course_id": "course-v1:edX+DemoX+Demo_Course",
"email": "honor@example.com",
"user_id": 6,
"username": "honor",
"full_name": "",
"passed": false,
"percent": 0,
"letter_grade": null,
"progress_page_url": "/courses/course-v1:edX+DemoX+Demo_Course/progress/6/",
"section_breakdown": [
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Introduction",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b",
"subsection_name": "Demo Course Overview"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 1: Getting Started",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/3.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5",
"percent": 0,
"score_earned": 0,
"score_possible": 3,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
"subsection_name": "Lesson 1 - Getting Started"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": "Homework",
"chapter_name": "Example Week 1: Getting Started",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": true,
"grade_description": "(0.00/11.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": "Ex 01",
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions",
"percent": 0,
"score_earned": 0,
"score_possible": 11,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
"subsection_name": "Homework - Question Styles"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 2: Get Interactive",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@simulations",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
"subsection_name": "Lesson 2 - Let's Get Interactive!"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": "Homework",
"chapter_name": "Example Week 2: Get Interactive",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": true,
"grade_description": "(0.00/5.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": "Ex 02",
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@graded_simulations",
"percent": 0,
"score_earned": 0,
"score_possible": 5,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
"subsection_name": "Homework - Labs and Demos"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 2: Get Interactive",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/19.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@175e76c4951144a29d46211361266e0e",
"percent": 0,
"score_earned": 0,
"score_possible": 19,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
"subsection_name": "Homework - Essays"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 3: Be Social",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@48ecb924d7fe4b66a230137626bfa93e",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
"subsection_name": "Lesson 3 - Be Social"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 3: Be Social",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@dbe8fc027bcb4fe9afb744d2e8415855",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
"subsection_name": "Homework - Find Your Study Buddy"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 3: Be Social",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@6ab9c442501d472c8ed200e367b4edfa",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
"subsection_name": "More Ways to Connect"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": "Exam",
"chapter_name": "About Exams and Certificates",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": true,
"grade_description": "(0.00/6.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow",
"percent": 0,
"score_earned": 0,
"score_possible": 6,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@1414ffd5143b4b508f739b563ab468b7",
"subsection_name": "edX Exams"
}
],
"aggregates": {
"Exam": {
"score_possible": 6,
"score_earned": 0
},
"Homework": {
"score_possible": 16,
"score_earned": 0
}
}
},
{
"course_id": "course-v1:edX+DemoX+Demo_Course",
"email": "audit@example.com",
"user_id": 7,
"username": "audit",
"full_name": "",
"passed": false,
"percent": 0.17,
"letter_grade": null,
"progress_page_url": "/courses/course-v1:edX+DemoX+Demo_Course/progress/7/",
"section_breakdown": [
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Introduction",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b",
"subsection_name": "Demo Course Overview"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 1: Getting Started",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/3.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5",
"percent": 0,
"score_earned": 0,
"score_possible": 3,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
"subsection_name": "Lesson 1 - Getting Started"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": "Homework",
"chapter_name": "Example Week 1: Getting Started",
"comment": "",
"detail": "",
"displayed_value": "0.45",
"is_graded": true,
"grade_description": "(5.00/11.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": "Ex 01",
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions",
"percent": 0.45,
"score_earned": 5,
"score_possible": 11,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
"subsection_name": "Homework - Question Styles"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 2: Get Interactive",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@simulations",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
"subsection_name": "Lesson 2 - Let's Get Interactive!"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": "Homework",
"chapter_name": "Example Week 2: Get Interactive",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": true,
"grade_description": "(0.00/5.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": "Ex 02",
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@graded_simulations",
"percent": 0,
"score_earned": 0,
"score_possible": 5,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
"subsection_name": "Homework - Labs and Demos"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 2: Get Interactive",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/19.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@175e76c4951144a29d46211361266e0e",
"percent": 0,
"score_earned": 0,
"score_possible": 19,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
"subsection_name": "Homework - Essays"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 3: Be Social",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@48ecb924d7fe4b66a230137626bfa93e",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
"subsection_name": "Lesson 3 - Be Social"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 3: Be Social",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@dbe8fc027bcb4fe9afb744d2e8415855",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
"subsection_name": "Homework - Find Your Study Buddy"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 3: Be Social",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@6ab9c442501d472c8ed200e367b4edfa",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
"subsection_name": "More Ways to Connect"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": "Exam",
"chapter_name": "About Exams and Certificates",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": true,
"grade_description": "(0.00/6.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow",
"percent": 0,
"score_earned": 0,
"score_possible": 6,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@1414ffd5143b4b508f739b563ab468b7",
"subsection_name": "edX Exams"
}
],
"aggregates": {
"Exam": {
"score_possible": 6,
"score_earned": 0
},
"Homework": {
"score_possible": 16,
"score_earned": 5
}
}
},
{
"course_id": "course-v1:edX+DemoX+Demo_Course",
"email": "verified@example.com",
"user_id": 8,
"username": "verified",
"full_name": "",
"passed": false,
"percent": 0,
"letter_grade": null,
"progress_page_url": "/courses/course-v1:edX+DemoX+Demo_Course/progress/8/",
"section_breakdown": [
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Introduction",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b",
"subsection_name": "Demo Course Overview"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 1: Getting Started",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/3.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5",
"percent": 0,
"score_earned": 0,
"score_possible": 3,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
"subsection_name": "Lesson 1 - Getting Started"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": "Homework",
"chapter_name": "Example Week 1: Getting Started",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": true,
"grade_description": "(0.00/11.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": "Ex 01",
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions",
"percent": 0,
"score_earned": 0,
"score_possible": 11,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
"subsection_name": "Homework - Question Styles"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 2: Get Interactive",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@simulations",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
"subsection_name": "Lesson 2 - Let's Get Interactive!"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": "Homework",
"chapter_name": "Example Week 2: Get Interactive",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": true,
"grade_description": "(0.00/5.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": "Ex 02",
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@graded_simulations",
"percent": 0,
"score_earned": 0,
"score_possible": 5,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
"subsection_name": "Homework - Labs and Demos"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 2: Get Interactive",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/19.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@175e76c4951144a29d46211361266e0e",
"percent": 0,
"score_earned": 0,
"score_possible": 19,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
"subsection_name": "Homework - Essays"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 3: Be Social",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@48ecb924d7fe4b66a230137626bfa93e",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
"subsection_name": "Lesson 3 - Be Social"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 3: Be Social",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@dbe8fc027bcb4fe9afb744d2e8415855",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
"subsection_name": "Homework - Find Your Study Buddy"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 3: Be Social",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@6ab9c442501d472c8ed200e367b4edfa",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
"subsection_name": "More Ways to Connect"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": "Exam",
"chapter_name": "About Exams and Certificates",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": true,
"grade_description": "(0.00/6.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow",
"percent": 0,
"score_earned": 0,
"score_possible": 6,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@1414ffd5143b4b508f739b563ab468b7",
"subsection_name": "edX Exams"
}
],
"aggregates": {
"Exam": {
"score_possible": 6,
"score_earned": 0
},
"Homework": {
"score_possible": 16,
"score_earned": 0
}
}
},
{
"course_id": "course-v1:edX+DemoX+Demo_Course",
"email": "staff@example.com",
"user_id": 9,
"username": "staff",
"full_name": "",
"passed": false,
"percent": 0,
"letter_grade": null,
"progress_page_url": "/courses/course-v1:edX+DemoX+Demo_Course/progress/9/",
"section_breakdown": [
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Introduction",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b",
"subsection_name": "Demo Course Overview"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 1: Getting Started",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/3.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5",
"percent": 0,
"score_earned": 0,
"score_possible": 3,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
"subsection_name": "Lesson 1 - Getting Started"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": "Homework",
"chapter_name": "Example Week 1: Getting Started",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": true,
"grade_description": "(0.00/11.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": "Ex 01",
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions",
"percent": 0,
"score_earned": 0,
"score_possible": 11,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
"subsection_name": "Homework - Question Styles"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 2: Get Interactive",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@simulations",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
"subsection_name": "Lesson 2 - Let's Get Interactive!"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": "Homework",
"chapter_name": "Example Week 2: Get Interactive",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": true,
"grade_description": "(0.00/5.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": "Ex 02",
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@graded_simulations",
"percent": 0,
"score_earned": 0,
"score_possible": 5,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
"subsection_name": "Homework - Labs and Demos"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 2: Get Interactive",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/19.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@175e76c4951144a29d46211361266e0e",
"percent": 0,
"score_earned": 0,
"score_possible": 19,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
"subsection_name": "Homework - Essays"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 3: Be Social",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@48ecb924d7fe4b66a230137626bfa93e",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
"subsection_name": "Lesson 3 - Be Social"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 3: Be Social",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@dbe8fc027bcb4fe9afb744d2e8415855",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
"subsection_name": "Homework - Find Your Study Buddy"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "Example Week 3: Be Social",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@6ab9c442501d472c8ed200e367b4edfa",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
"subsection_name": "More Ways to Connect"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": "Exam",
"chapter_name": "About Exams and Certificates",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": true,
"grade_description": "(0.00/6.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow",
"percent": 0,
"score_earned": 0,
"score_possible": 6,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@1414ffd5143b4b508f739b563ab468b7",
"subsection_name": "edX Exams"
},
{
"are_grades_published": true,
"auto_grade": false,
"category": null,
"chapter_name": "holding section",
"comment": "",
"detail": "",
"displayed_value": "0.00",
"is_graded": false,
"grade_description": "(0.00/0.00)",
"is_ag": false,
"is_average": false,
"is_manually_graded": false,
"label": null,
"letter_grade": null,
"module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@07bc32474380492cb34f76e5f9d9a135",
"percent": 0,
"score_earned": 0,
"score_possible": 0,
"section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@9fca584977d04885bc911ea76a9ef29e",
"subsection_name": "New Subsection"
}
],
"aggregates": {
"Exam": {
"score_possible": 6,
"score_earned": 0
},
"Homework": {
"score_possible": 16,
"score_earned": 0
}
}
}
]
};
// CommentDetails.defaultProps = {
// id: null,
// postId: null,
// name: '',
// email: 'example@example.com',
// body: '',
// };
// CommentDetails.propTypes = {
// id: PropTypes.number,
// postId: PropTypes.number,
// name: PropTypes.string,
// email: emailPropType,
// body: PropTypes.string,
// };

16
src/config/index.js Normal file
View File

@@ -0,0 +1,16 @@
const configuration = {
BASE_URL: process.env.BASE_URL,
LMS_BASE_URL: process.env.LMS_BASE_URL,
LOGIN_URL: process.env.LOGIN_URL,
LOGOUT_URL: process.env.LOGOUT_URL,
REFRESH_ACCESS_TOKEN_ENDPOINT: process.env.REFRESH_ACCESS_TOKEN_ENDPOINT,
DATA_API_BASE_URL: process.env.DATA_API_BASE_URL,
SECURE_COOKIES: process.env.NODE_ENV !== 'development',
SEGMENT_KEY: process.env.SEGMENT_KEY,
ACCESS_TOKEN_COOKIE_NAME: process.env.ACCESS_TOKEN_COOKIE_NAME,
CSRF_COOKIE_NAME: process.env.CSRF_COOKIE_NAME,
};
const features = {};
export { configuration, features };

View File

@@ -1,15 +1,37 @@
import { connect } from 'react-redux';
import Gradebook from '../../components/Gradebook';
import { fetchComment } from '../../data/actions/comment';
import { fetchGrades, fetchMatchingUserGrades, updateGrades } from '../../data/actions/grades';
import { fetchCohorts } from '../../data/actions/cohorts';
import { fetchTracks } from '../../data/actions/tracks';
const mapStateToProps = state => (
{
grades: state.grades.results,
tracks: state.tracks.results,
cohorts: state.cohorts.results,
selectedTrack: state.grades.selectedTrack,
selectedCohort: state.grades.selectedCohort,
}
);
const mapDispatchToProps = dispatch => (
{
getUserGrades: (courseId, cohort, track) => {
dispatch(fetchGrades(courseId, cohort, track));
},
searchForUser: (courseId, searchText, cohort, track) => {
dispatch(fetchMatchingUserGrades(courseId, searchText, cohort, track));
},
getCohorts: (courseId) => {
dispatch(fetchCohorts(courseId));
},
getTracks: (courseId) => {
dispatch(fetchTracks(courseId));
},
updateGrades: (courseId, updateData) => {
dispatch(updateGrades(courseId, updateData));
},
}
);

View File

@@ -0,0 +1,31 @@
import {
STARTED_FETCHING_COHORTS,
GOT_COHORTS,
ERROR_FETCHING_COHORTS,
} from '../constants/actionTypes/cohorts';
import LmsApiService from '../services/LmsApiService';
const startedFetchingCohorts = () => ({ type: STARTED_FETCHING_COHORTS });
const errorFetchingCohorts = () => ({ type: ERROR_FETCHING_COHORTS });
const gotCohorts = cohorts => ({ type: GOT_COHORTS, cohorts });
const fetchCohorts = courseId => (
(dispatch) => {
dispatch(startedFetchingCohorts());
return LmsApiService.fetchCohorts(courseId)
.then(response => response.data)
.then((data) => {
dispatch(gotCohorts(data.cohorts));
})
.catch((error) => {
dispatch(errorFetchingCohorts());
});
}
);
export {
fetchCohorts,
startedFetchingCohorts,
gotCohorts,
errorFetchingCohorts,
};

View File

@@ -0,0 +1,87 @@
import {
STARTED_FETCHING_GRADES,
FINISHED_FETCHING_GRADES,
ERROR_FETCHING_GRADES,
GOT_GRADES,
GRADE_UPDATE_REQUEST,
GRADE_UPDATE_SUCCESS,
GRADE_UPDATE_FAILURE,
} from '../constants/actionTypes/grades';
import LmsApiService from '../services/LmsApiService';
const startedFetchingGrades = () => ({ type: STARTED_FETCHING_GRADES });
const finishedFetchingGrades = () => ({ type: FINISHED_FETCHING_GRADES });
const errorFetchingGrades = () => ({ type: ERROR_FETCHING_GRADES });
const gotGrades = (grades, cohort, track) => ({
type: GOT_GRADES,
grades,
cohort,
track,
});
const gradeUpdateRequest = () => ({ type: GRADE_UPDATE_REQUEST });
const gradeUpdateSuccess = responseData => ({
type: GRADE_UPDATE_SUCCESS,
payload: { responseData },
})
const gradeUpdateFailure = error => ({
type: GRADE_UPDATE_FAILURE,
payload: { error },
});
const fetchGrades = (courseId, cohort, track) => (
(dispatch) => {
dispatch(startedFetchingGrades());
return LmsApiService.fetchGradebookData(courseId, null, cohort, track)
.then(response => response.data)
.then((data) => {
dispatch(gotGrades(data.results, cohort, track));
dispatch(finishedFetchingGrades());
})
.catch((error) => {
dispatch(errorFetchingGrades());
});
}
);
const fetchMatchingUserGrades = (courseId, searchText, cohort, track) => (
(dispatch) => {
dispatch(startedFetchingGrades());
return LmsApiService.fetchGradebookData(courseId, searchText, cohort, track)
.then(response => response.data)
.then((data) => {
dispatch(gotGrades(data.results, cohort, track));
dispatch(finishedFetchingGrades());
})
.catch((error) => {
dispatch(errorFetchingGrades());
});
}
);
const updateGrades = (courseId, updateData) => (
(dispatch) => {
dispatch(gradeUpdateRequest());
return LmsApiService.updateGradebookData(courseId, updateData)
.then(response => response.data)
.then((data) => {
dispatch(gradeUpdateSuccess(data))
})
.catch((error) => {
dispatch(gradeUpdateFailure(error));
});
}
);
export {
startedFetchingGrades,
finishedFetchingGrades,
errorFetchingGrades,
gotGrades,
fetchGrades,
fetchMatchingUserGrades,
gradeUpdateRequest,
gradeUpdateSuccess,
gradeUpdateFailure,
updateGrades,
};

View File

@@ -0,0 +1,31 @@
import {
STARTED_FETCHING_TRACKS,
GOT_TRACKS,
ERROR_FETCHING_TRACKS,
} from '../constants/actionTypes/tracks';
import LmsApiService from '../services/LmsApiService';
const startedFetchingTracks = () => ({ type: STARTED_FETCHING_TRACKS });
const errorFetchingTracks = () => ({ type: ERROR_FETCHING_TRACKS });
const gotTracks = tracks => ({ type: GOT_TRACKS, tracks });
const fetchTracks = courseId => (
(dispatch) => {
dispatch(startedFetchingTracks());
return LmsApiService.fetchTracks(courseId)
.then(response => response.data)
.then((data) => {
dispatch(gotTracks(data.course_modes));
})
.catch((error) => {
dispatch(errorFetchingTracks());
});
}
);
export {
fetchTracks,
startedFetchingTracks,
gotTracks,
errorFetchingTracks,
};

13
src/data/apiClient.js Normal file
View File

@@ -0,0 +1,13 @@
import { configuration } from '../config';
import { getAuthenticatedAPIClient } from '@edx/frontend-auth';
const apiClient = getAuthenticatedAPIClient({
appBaseUrl: configuration.BASE_URL,
loginUrl: configuration.LOGIN_URL,
logoutUrl: configuration.LOGOUT_URL,
refreshAccessTokenEndpoint: configuration.REFRESH_ACCESS_TOKEN_ENDPOINT,
accessTokenCookieName: configuration.ACCESS_TOKEN_COOKIE_NAME,
csrfCookieName: configuration.CSRF_COOKIE_NAME,
});
export default apiClient;

View File

@@ -0,0 +1,9 @@
const STARTED_FETCHING_COHORTS = 'STARTED_FETCHING_COHORTS';
const GOT_COHORTS = 'GOT_COHORTS';
const ERROR_FETCHING_COHORTS = 'ERROR_FETCHING_COHORTS';
export {
STARTED_FETCHING_COHORTS,
GOT_COHORTS,
ERROR_FETCHING_COHORTS,
};

View File

@@ -0,0 +1,18 @@
const STARTED_FETCHING_GRADES = 'STARTED_FETCHING_GRADES';
const FINISHED_FETCHING_GRADES = 'FINISHED_FETCHING_GRADES';
const ERROR_FETCHING_GRADES = 'ERROR_FETCHING_GRADES';
const GOT_GRADES = 'GOT_GRADES';
const GRADE_UPDATE_REQUEST = 'GRADE_UPDATE_REQUEST';
const GRADE_UPDATE_SUCCESS = 'GRADE_UPDATE_SUCCESS';
const GRADE_UPDATE_FAILURE = 'GRADE_UPDATE_FAILURE';
export {
STARTED_FETCHING_GRADES,
FINISHED_FETCHING_GRADES,
ERROR_FETCHING_GRADES,
GOT_GRADES,
GRADE_UPDATE_REQUEST,
GRADE_UPDATE_SUCCESS,
GRADE_UPDATE_FAILURE,
};

View File

@@ -0,0 +1,9 @@
const STARTED_FETCHING_TRACKS = 'STARTED_FETCHING_TRACKS';
const GOT_TRACKS = 'GOT_TRACKS';
const ERROR_FETCHING_TRACKS = 'ERROR_FETCHING_TRACKS';
export {
STARTED_FETCHING_TRACKS,
GOT_TRACKS,
ERROR_FETCHING_TRACKS,
};

View File

@@ -0,0 +1,39 @@
import {
STARTED_FETCHING_COHORTS,
ERROR_FETCHING_COHORTS,
GOT_COHORTS,
} from '../constants/actionTypes/cohorts';
const initialState = {
results: [],
startedFetching: false,
errorFetching: false,
};
const cohorts = (state = initialState, action) => {
switch (action.type) {
case GOT_COHORTS:
return {
...state,
results: action.cohorts,
errorFetching: false,
};
case STARTED_FETCHING_COHORTS:
return {
...state,
startedFetching: true,
};
case ERROR_FETCHING_COHORTS:
return {
...state,
finishedFetching: true,
errorFetching: true,
};
default:
return state;
}
};
export default cohorts;

1042
src/data/reducers/grades.js Normal file
View File

@@ -0,0 +1,1042 @@
import {
STARTED_FETCHING_GRADES,
ERROR_FETCHING_GRADES,
GOT_GRADES,
} from '../constants/actionTypes/grades';
const initialState = {
results: [],
startedFetching: false,
finishedFetching: false,
errorFetching: false,
};
const grades = (state = initialState, action) => {
switch (action.type) {
case GOT_GRADES:
return {
...state,
results: action.grades,
finishedFetching: true,
errorFetching: false,
selectedTrack: action.track,
selectedCohort: action.cohort,
};
case STARTED_FETCHING_GRADES:
return {
...state,
startedFetching: true,
finishedFetching: false,
};
case ERROR_FETCHING_GRADES:
return {
...state,
finishedFetching: true,
errorFetching: true,
};
default:
return state;
}
};
export default grades;
// Gradebook.defaultProps = {
// "results": [
// {
// "course_id": "course-v1:edX+DemoX+Demo_Course",
// "email": "honor@example.com",
// "user_id": 6,
// "username": "honor",
// "full_name": "",
// "passed": false,
// "percent": 0,
// "letter_grade": null,
// "progress_page_url": "/courses/course-v1:edX+DemoX+Demo_Course/progress/6/",
// "section_breakdown": [
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Introduction",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b",
// "subsection_name": "Demo Course Overview"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/3.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 3,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Lesson 1 - Getting Started"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/11.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 01",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 11,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Homework - Question Styles"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Lesson 2 - Let's Get Interactive!"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/5.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 02",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@graded_simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 5,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Labs and Demos"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/19.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@175e76c4951144a29d46211361266e0e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 19,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Essays"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@48ecb924d7fe4b66a230137626bfa93e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Lesson 3 - Be Social"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@dbe8fc027bcb4fe9afb744d2e8415855",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Homework - Find Your Study Buddy"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@6ab9c442501d472c8ed200e367b4edfa",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "More Ways to Connect"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Exam",
// "chapter_name": "About Exams and Certificates",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/6.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 6,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@1414ffd5143b4b508f739b563ab468b7",
// "subsection_name": "edX Exams"
// }
// ],
// "aggregates": {
// "Exam": {
// "score_possible": 6,
// "score_earned": 0
// },
// "Homework": {
// "score_possible": 16,
// "score_earned": 0
// }
// }
// },
// {
// "course_id": "course-v1:edX+DemoX+Demo_Course",
// "email": "audit@example.com",
// "user_id": 7,
// "username": "audit",
// "full_name": "",
// "passed": false,
// "percent": 0.17,
// "letter_grade": null,
// "progress_page_url": "/courses/course-v1:edX+DemoX+Demo_Course/progress/7/",
// "section_breakdown": [
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Introduction",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b",
// "subsection_name": "Demo Course Overview"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/3.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 3,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Lesson 1 - Getting Started"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.45",
// "is_graded": true,
// "grade_description": "(5.00/11.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 01",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions",
// "percent": 0.45,
// "score_earned": 5,
// "score_possible": 11,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Homework - Question Styles"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Lesson 2 - Let's Get Interactive!"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/5.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 02",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@graded_simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 5,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Labs and Demos"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/19.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@175e76c4951144a29d46211361266e0e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 19,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Essays"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@48ecb924d7fe4b66a230137626bfa93e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Lesson 3 - Be Social"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@dbe8fc027bcb4fe9afb744d2e8415855",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Homework - Find Your Study Buddy"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@6ab9c442501d472c8ed200e367b4edfa",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "More Ways to Connect"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Exam",
// "chapter_name": "About Exams and Certificates",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/6.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 6,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@1414ffd5143b4b508f739b563ab468b7",
// "subsection_name": "edX Exams"
// }
// ],
// "aggregates": {
// "Exam": {
// "score_possible": 6,
// "score_earned": 0
// },
// "Homework": {
// "score_possible": 16,
// "score_earned": 5
// }
// }
// },
// {
// "course_id": "course-v1:edX+DemoX+Demo_Course",
// "email": "verified@example.com",
// "user_id": 8,
// "username": "verified",
// "full_name": "",
// "passed": false,
// "percent": 0,
// "letter_grade": null,
// "progress_page_url": "/courses/course-v1:edX+DemoX+Demo_Course/progress/8/",
// "section_breakdown": [
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Introduction",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b",
// "subsection_name": "Demo Course Overview"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/3.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 3,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Lesson 1 - Getting Started"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/11.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 01",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 11,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Homework - Question Styles"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Lesson 2 - Let's Get Interactive!"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/5.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 02",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@graded_simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 5,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Labs and Demos"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/19.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@175e76c4951144a29d46211361266e0e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 19,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Essays"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@48ecb924d7fe4b66a230137626bfa93e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Lesson 3 - Be Social"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@dbe8fc027bcb4fe9afb744d2e8415855",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Homework - Find Your Study Buddy"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@6ab9c442501d472c8ed200e367b4edfa",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "More Ways to Connect"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Exam",
// "chapter_name": "About Exams and Certificates",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/6.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 6,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@1414ffd5143b4b508f739b563ab468b7",
// "subsection_name": "edX Exams"
// }
// ],
// "aggregates": {
// "Exam": {
// "score_possible": 6,
// "score_earned": 0
// },
// "Homework": {
// "score_possible": 16,
// "score_earned": 0
// }
// }
// },
// {
// "course_id": "course-v1:edX+DemoX+Demo_Course",
// "email": "staff@example.com",
// "user_id": 9,
// "username": "staff",
// "full_name": "",
// "passed": false,
// "percent": 0,
// "letter_grade": null,
// "progress_page_url": "/courses/course-v1:edX+DemoX+Demo_Course/progress/9/",
// "section_breakdown": [
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Introduction",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@d8a6192ade314473a78242dfeedfbf5b",
// "subsection_name": "Demo Course Overview"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/3.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 3,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Lesson 1 - Getting Started"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 1: Getting Started",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/11.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 01",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 11,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations",
// "subsection_name": "Homework - Question Styles"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Lesson 2 - Let's Get Interactive!"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Homework",
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/5.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": "Ex 02",
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@graded_simulations",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 5,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Labs and Demos"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 2: Get Interactive",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/19.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@175e76c4951144a29d46211361266e0e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 19,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@graded_interactions",
// "subsection_name": "Homework - Essays"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@48ecb924d7fe4b66a230137626bfa93e",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Lesson 3 - Be Social"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@dbe8fc027bcb4fe9afb744d2e8415855",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "Homework - Find Your Study Buddy"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "Example Week 3: Be Social",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@6ab9c442501d472c8ed200e367b4edfa",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@social_integration",
// "subsection_name": "More Ways to Connect"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": "Exam",
// "chapter_name": "About Exams and Certificates",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": true,
// "grade_description": "(0.00/6.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@workflow",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 6,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@1414ffd5143b4b508f739b563ab468b7",
// "subsection_name": "edX Exams"
// },
// {
// "are_grades_published": true,
// "auto_grade": false,
// "category": null,
// "chapter_name": "holding section",
// "comment": "",
// "detail": "",
// "displayed_value": "0.00",
// "is_graded": false,
// "grade_description": "(0.00/0.00)",
// "is_ag": false,
// "is_average": false,
// "is_manually_graded": false,
// "label": null,
// "letter_grade": null,
// "module_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@07bc32474380492cb34f76e5f9d9a135",
// "percent": 0,
// "score_earned": 0,
// "score_possible": 0,
// "section_block_id": "block-v1:edX+DemoX+Demo_Course+type@chapter+block@9fca584977d04885bc911ea76a9ef29e",
// "subsection_name": "New Subsection"
// }
// ],
// "aggregates": {
// "Exam": {
// "score_possible": 6,
// "score_earned": 0
// },
// "Homework": {
// "score_possible": 16,
// "score_earned": 0
// }
// }
// }
// ]
// };

View File

@@ -1,11 +1,13 @@
import { combineReducers } from 'redux';
import posts from './posts';
import comment from './comment';
import cohorts from './cohorts';
import grades from './grades';
import tracks from './tracks';
const rootReducer = combineReducers({
posts,
comment,
grades,
cohorts,
tracks,
});
export default rootReducer;

View File

@@ -0,0 +1,39 @@
import {
STARTED_FETCHING_TRACKS,
ERROR_FETCHING_TRACKS,
GOT_TRACKS,
} from '../constants/actionTypes/tracks';
const initialState = {
results: [],
startedFetching: false,
errorFetching: false,
};
const tracks = (state = initialState, action) => {
switch (action.type) {
case GOT_TRACKS:
return {
...state,
results: action.tracks,
errorFetching: false,
};
case STARTED_FETCHING_TRACKS:
return {
...state,
startedFetching: true,
};
case ERROR_FETCHING_TRACKS:
return {
...state,
finishedFetching: true,
errorFetching: true,
};
default:
return state;
}
};
export default tracks;

View File

@@ -0,0 +1,59 @@
import apiClient from '../apiClient';
import { configuration } from '../../config';
class LmsApiService {
static baseUrl = configuration.LMS_BASE_URL;
static fetchGradebookData(courseId, searchText, cohort, track) {
let gradebookUrl = `${LmsApiService.baseUrl}/api/grades/v1/gradebook/${courseId}/`;
if (searchText || track || cohort) {
gradebookUrl += '?';
}
if (searchText) {
gradebookUrl += `username_contains=${searchText}&`;
}
if (cohort) {
gradebookUrl += `cohort_id=${cohort}&`;
}
if (track) {
gradebookUrl += `enrollment_mode=${track}`;
}
return apiClient.get(gradebookUrl);
}
static updateGradebookData(courseId, updateData) {
/*
updateData is expected to be a list of objects with the keys 'user_id' (an integer),
'usage_id' (a string) and 'grade', which is an object with the keys:
'earned_all_override', 'possible_all_override', 'earned_graded_override', and 'possible_graded_override',
each of which should be an integer.
Example:
[
{
"user_id": 9,
"usage_id": "block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions",
"grade": {
"earned_all_override": 11,
"possible_all_override": 11,
"earned_graded_override": 11,
"possible_graded_override": 11
}
}
]
*/
const gradebookUrl = `${LmsApiService.baseUrl}/api/grades/v1/gradebook/${courseId}/bulk-update`;
return apiClient.post(gradebookUrl, updateData);
}
static fetchTracks(courseId) {
const trackUrl = `${LmsApiService.baseUrl}/api/enrollment/v1/course/${courseId}`;
return apiClient.get(trackUrl);
}
static fetchCohorts(courseId) {
const cohortsUrl = `${LmsApiService.baseUrl}/courses/${courseId}/cohorts/`;
return apiClient.get(cohortsUrl);
}
}
export default LmsApiService;

View File

@@ -1,7 +1,7 @@
import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { Provider } from 'react-redux';
import GradebookPage from './containers/GradebookPage';
@@ -11,20 +11,11 @@ import './App.scss';
const App = () => (
<Provider store={store}>
<Router>
<div>
<header>
<nav>
<ul className="nav">
<li className="nav-item"><Link className="nav-link" to="/">Home</Link></li>
</ul>
</nav>
</header>
<main>
<Switch>
<Route exact path="/" component={GradebookPage} />
</Switch>
</main>
</div>
<main>
<Switch>
<Route exact path="/:courseId" component={GradebookPage} />
</Switch>
</main>
</Router>
</Provider>
);