Compare commits

..

6 Commits

Author SHA1 Message Date
Simon Chen
05c3468d93 Merge pull request #12 from edx/schen/fix_download_link
fix(functionality): Update the download report link URL
2018-11-14 14:18:39 -05:00
Simon Chen
1a88343be9 fix(functionality): Update the download report link URL so it goes to the right place 2018-11-14 13:55:12 -05:00
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
4 changed files with 61 additions and 35 deletions

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,
}),
],
});

19
package-lock.json generated
View File

@@ -2988,14 +2988,14 @@
}
},
"react": {
"version": "16.6.1",
"resolved": "https://registry.npmjs.org/react/-/react-16.6.1.tgz",
"integrity": "sha512-OtawJThYlvRgm9BXK+xTL7BIlDx8vv21j+fbQDjRRUyok6y7NyjlweGorielTahLZHYIdKUoK2Dp9ByVWuMqxw==",
"version": "16.6.3",
"resolved": "https://registry.npmjs.org/react/-/react-16.6.3.tgz",
"integrity": "sha512-zCvmH2vbEolgKxtqXL2wmGCUxUyNheYn/C+PD1YAjfxHC54+MhdruyhO7QieQrYsYeTxrn93PM2y0jRH1zEExw==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"scheduler": "^0.11.0"
"scheduler": "^0.11.2"
},
"dependencies": {
"prop-types": {
@@ -3055,6 +3055,15 @@
}
}
},
"scheduler": {
"version": "0.11.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.11.2.tgz",
"integrity": "sha512-+WCP3s3wOaW4S7C1tl3TEXp4l9lJn0ZK8G3W3WKRWmw77Z2cIFUW2MiNTMHn5sCjxN+t7N43HAOOgMjyAg5hlg==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
}
},
"warning": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.2.tgz",
@@ -3536,7 +3545,7 @@
},
"@types/object-assign": {
"version": "4.0.30",
"resolved": "https://registry.npmjs.org/@types/object-assign/-/object-assign-4.0.30.tgz",
"resolved": "http://registry.npmjs.org/@types/object-assign/-/object-assign-4.0.30.tgz",
"integrity": "sha1-iUk3HVqZ9Dge4PHfCpt6GH4H5lI="
},
"@types/tapable": {

View File

@@ -25,7 +25,7 @@
},
"dependencies": {
"@edx/edx-bootstrap": "^0.4.3",
"@edx/frontend-auth": "^1.1.0",
"@edx/frontend-auth": "1.1.0",
"@edx/paragon": "^3.7.0",
"babel-polyfill": "^6.26.0",
"classnames": "^2.2.5",

View File

@@ -1,9 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import emailPropType from 'email-prop-type';
import { Button, Modal, SearchField, Table, InputSelect } from '@edx/paragon';
import queryString from 'query-string';
import { configuration } from '../../config';
export default class Gradebook extends React.Component {
constructor(props) {
@@ -170,7 +168,7 @@ export default class Gradebook extends React.Component {
<input
style={{ width: '25px' }}
type="text"
onChange={(event) => this.setState({updateVal: event.target.value})}
onChange={event => this.setState({ updateVal: event.target.value })}
/> / {subsection.score_possible}
</span>
),
@@ -180,7 +178,7 @@ export default class Gradebook extends React.Component {
updateModuleId: subsection.module_id,
updateUserId: userEntry.user_id,
})
});
}
mapUserEntriesPercent = entries => entries.map((entry) => {
@@ -223,10 +221,10 @@ export default class Gradebook extends React.Component {
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,
user_id: this.state.updateUserId,
usage_id: this.state.updateModuleId,
grade: {
earned_graded_override: this.state.updateVal,
},
},
]);
@@ -238,27 +236,27 @@ export default class Gradebook extends React.Component {
};
mapCohortsEntries = (entries) => {
let mapped = entries.map(entry => ({
const mapped = entries.map(entry => ({
id: entry.id,
label: entry.name,
}));
mapped.unshift({id:0, label:'Cohorts'});
mapped.unshift({ id: 0, label: 'Cohorts' });
return mapped;
};
mapTracksEntries = (entries) => {
let mapped = entries.map(entry => ({
const mapped = entries.map(entry => ({
id: entry.slug,
label: entry.name,
}));
mapped.unshift({ label:'Tracks' });
mapped.unshift({ label: 'Tracks' });
return mapped;
};
updateTracks = (event) => {
const selectedTrackItem = this.props.tracks.find(x=>x.name===event);
const selectedTrackItem = this.props.tracks.find(x => x.name === event);
let selectedTrackSlug = null;
if(selectedTrackItem) {
if (selectedTrackItem) {
selectedTrackSlug = selectedTrackItem.slug;
}
this.props.getUserGrades(
@@ -266,14 +264,14 @@ export default class Gradebook extends React.Component {
this.props.selectedCohort,
selectedTrackSlug,
);
const updatedQueryStrings = this.updateQueryParams('track', selectedTrackSlug)
const updatedQueryStrings = this.updateQueryParams('track', selectedTrackSlug);
this.props.history.push(updatedQueryStrings);
};
updateCohorts = (event) => {
const selectedCohortItem = this.props.cohorts.find(x=>x.name===event);
const selectedCohortItem = this.props.cohorts.find(x => x.name === event);
let selectedCohortId = null;
if(selectedCohortItem) {
if (selectedCohortItem) {
selectedCohortId = selectedCohortItem.id;
}
this.props.getUserGrades(
@@ -281,7 +279,7 @@ export default class Gradebook extends React.Component {
selectedCohortId,
this.props.selectedTrack,
);
const updatedQueryStrings = this.updateQueryParams('cohort', selectedCohortId)
const updatedQueryStrings = this.updateQueryParams('cohort', selectedCohortId);
this.props.history.push(updatedQueryStrings);
};
@@ -301,6 +299,9 @@ export default class Gradebook extends React.Component {
return 'Tracks';
};
getDataDownloadUrl = courseId => `${configuration.LMS_BASE_URL}/courses/${courseId}/instructor#view-data_download`;
render() {
return (
<div className="d-flex justify-content-center">
@@ -384,7 +385,7 @@ export default class Gradebook extends React.Component {
</span>
{this.props.tracks.length > 0 &&
<InputSelect
name='Tracks'
name="Tracks"
value={this.mapSelectedTrackEntry(this.props.selectedTrack)}
options={this.mapTracksEntries(this.props.tracks)}
onChange={this.updateTracks}
@@ -392,7 +393,7 @@ export default class Gradebook extends React.Component {
}
{this.props.cohorts.length > 0 &&
<InputSelect
name='Cohorts'
name="Cohorts"
value={this.mapSelectedCohortEntry(this.props.selectedCohort)}
options={this.mapCohortsEntries(this.props.cohorts)}
onChange={this.updateCohorts}
@@ -403,7 +404,7 @@ export default class Gradebook extends React.Component {
</div>
<div>
<div style={{ marginLeft: '10px', marginBottom: '10px' }}>
<a href="https://www.google./com">Download Grade Report</a>
<a href={this.getDataDownloadUrl(this.props.match.params.courseId)}>Download Grade Report</a>
</div>
<SearchField
onSubmit={value => this.props.searchForUser(this.props.match.params.courseId, value, this.props.selectedCohort, this.props.selectedTrack)}
@@ -430,12 +431,12 @@ export default class Gradebook extends React.Component {
<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
defaultSortDirection="desc"
defaultSortedColumn="username"
/>
columns={[{ label: 'Username', key: 'username' }, { label: 'Current grade', key: 'currentGrade' }, { label: 'Adjusted grade', key: 'adjustedGrade' }]}
data={this.state.modalModel}
tableSortable
defaultSortDirection="desc"
defaultSortedColumn="username"
/>
</div>
)}
buttons={[
@@ -443,7 +444,7 @@ export default class Gradebook extends React.Component {
label="Edit Grade"
buttonType="primary"
onClick={this.handleAdjustedGradeClick}
/>
/>,
]}
onClose={() => this.setState({
modalOpen: false,