diff --git a/common/static/common/js/components/BlockBrowser/data/reducers/index.js b/common/static/common/js/components/BlockBrowser/data/reducers/index.js
index 365e9153edd5..98e68e872cc2 100644
--- a/common/static/common/js/components/BlockBrowser/data/reducers/index.js
+++ b/common/static/common/js/components/BlockBrowser/data/reducers/index.js
@@ -27,7 +27,7 @@ export const blocks = (state = {}, action) => {
}
};
-export const selectedBlock = (state = null, action) => {
+export const selectedBlock = (state = '', action) => {
switch (action.type) {
case courseBlocksActions.SELECT_BLOCK:
return action.blockId;
diff --git a/lms/djangoapps/instructor/static/instructor/ProblemBrowser/components/Main/Main.jsx b/lms/djangoapps/instructor/static/instructor/ProblemBrowser/components/Main/Main.jsx
index a9c9c5c61dd9..500e956c8bba 100644
--- a/lms/djangoapps/instructor/static/instructor/ProblemBrowser/components/Main/Main.jsx
+++ b/lms/djangoapps/instructor/static/instructor/ProblemBrowser/components/Main/Main.jsx
@@ -28,6 +28,7 @@ export default class Main extends React.Component {
this.props.createProblemResponsesReportTask(
this.props.problemResponsesEndpoint,
this.props.taskStatusEndpoint,
+ this.props.reportDownloadEndpoint,
this.props.selectedBlock,
);
}
@@ -71,6 +72,7 @@ Main.propTypes = {
onSelectBlock: PropTypes.func.isRequired,
selectedBlock: PropTypes.string,
taskStatusEndpoint: PropTypes.string.isRequired,
+ reportDownloadEndpoint: PropTypes.string.isRequired,
};
Main.defaultProps = {
diff --git a/lms/djangoapps/instructor/static/instructor/ProblemBrowser/components/Main/MainContainer.jsx b/lms/djangoapps/instructor/static/instructor/ProblemBrowser/components/Main/MainContainer.jsx
index 55c40facf299..6282dd61f9e5 100644
--- a/lms/djangoapps/instructor/static/instructor/ProblemBrowser/components/Main/MainContainer.jsx
+++ b/lms/djangoapps/instructor/static/instructor/ProblemBrowser/components/Main/MainContainer.jsx
@@ -14,10 +14,10 @@ const mapDispatchToProps = dispatch => ({
(courseId, excludeBlockTypes) =>
dispatch(fetchCourseBlocks(courseId, excludeBlockTypes)),
createProblemResponsesReportTask:
- (problemResponsesEndpoint, taskStatusEndpoint, problemLocation) =>
+ (problemResponsesEndpoint, taskStatusEndpoint, reportDownloadEndpoint, problemLocation) =>
dispatch(
createProblemResponsesReportTask(
- problemResponsesEndpoint, taskStatusEndpoint, problemLocation,
+ problemResponsesEndpoint, taskStatusEndpoint, reportDownloadEndpoint, problemLocation,
),
),
});
diff --git a/lms/djangoapps/instructor/static/instructor/ProblemBrowser/components/ReportStatus/ReportStatus.jsx b/lms/djangoapps/instructor/static/instructor/ProblemBrowser/components/ReportStatus/ReportStatus.jsx
index 9715493aa914..3919963f7ad9 100644
--- a/lms/djangoapps/instructor/static/instructor/ProblemBrowser/components/ReportStatus/ReportStatus.jsx
+++ b/lms/djangoapps/instructor/static/instructor/ProblemBrowser/components/ReportStatus/ReportStatus.jsx
@@ -15,10 +15,11 @@ const ReportStatus = ({ error, succeeded, inProgress, reportPath }) => {
const successMessage = (
);
diff --git a/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/actions/constants.js b/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/actions/constants.js
index e643833285be..74a66ef2a37d 100644
--- a/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/actions/constants.js
+++ b/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/actions/constants.js
@@ -2,3 +2,6 @@ export const REPORT_GENERATION_REQUEST = 'REPORT_GENERATION_REQUEST';
export const REPORT_GENERATION_SUCCESS = 'REPORT_GENERATION_SUCCESS';
export const REPORT_GENERATION_ERROR = 'REPORT_GENERATION_ERROR';
export const REPORT_GENERATION_REFRESH_STATUS = 'REPORT_GENERATION_REFRESH_STATUS';
+export const REPORT_DOWNLOADS_LIST_REQUEST = 'REPORT_DOWNLOADS_LIST_REQUEST';
+export const REPORT_DOWNLOADS_LIST_SUCCESS = 'REPORT_DOWNLOADS_LIST_SUCCESS';
+export const REPORT_DOWNLOADS_LIST_ERROR = 'REPORT_DOWNLOADS_LIST_ERROR';
diff --git a/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/actions/problemResponses.js b/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/actions/problemResponses.js
index a129340767dd..a62c4cb2ea0a 100644
--- a/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/actions/problemResponses.js
+++ b/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/actions/problemResponses.js
@@ -1,5 +1,5 @@
/* global gettext */
-import { fetchTaskStatus, initiateProblemResponsesRequest } from '../api/client';
+import { fetchDownloadsList, fetchTaskStatus, initiateProblemResponsesRequest } from '../api/client';
import {
REPORT_GENERATION_ERROR,
REPORT_GENERATION_REQUEST,
@@ -7,12 +7,12 @@ import {
REPORT_GENERATION_REFRESH_STATUS,
} from './constants';
-const taskStatusSuccess = (succeeded, inProgress, reportPath, reportName) => ({
+const taskStatusSuccess = (succeeded, inProgress, reportName, downloadsData) => ({
type: REPORT_GENERATION_SUCCESS,
succeeded,
inProgress,
- reportPath,
reportName,
+ downloadsData,
});
const problemResponsesRequest = blockId => ({
@@ -30,8 +30,8 @@ const problemResponsesRefreshStatus = timeout => ({
timeout,
});
-const getTaskStatus = (endpoint, taskId) => dispatch =>
- fetchTaskStatus(endpoint, taskId)
+const getTaskStatus = (taskStatusEndpoint, reportDownloadEndpoint, taskId) => dispatch =>
+ fetchTaskStatus(taskStatusEndpoint, taskId)
.then((response) => {
if (response.ok) {
return response.json();
@@ -41,20 +41,27 @@ const getTaskStatus = (endpoint, taskId) => dispatch =>
.then(
(statusData) => {
if (statusData.in_progress) {
- const timeout = setTimeout(() => dispatch(getTaskStatus(endpoint, taskId)), 2000);
+ const timeout = setTimeout(
+ () => dispatch(getTaskStatus(taskStatusEndpoint, reportDownloadEndpoint, taskId)),
+ 2000,
+ );
return dispatch(problemResponsesRefreshStatus(timeout));
}
if (statusData.task_state === 'SUCCESS') {
const taskProgress = statusData.task_progress;
- const reportPath = taskProgress && taskProgress.report_path;
const reportName = taskProgress && taskProgress.report_name;
- return dispatch(
- taskStatusSuccess(
- true,
- statusData.in_progress,
- reportPath,
- reportName,
- ),
+ return fetchDownloadsList(reportDownloadEndpoint, reportName)
+ .then(response => response.json())
+ .then(
+ data => dispatch(
+ taskStatusSuccess(
+ true,
+ statusData.in_progress,
+ reportName,
+ data.downloads,
+ ),
+ ),
+ () => dispatch(problemResponsesFailure(gettext('There was an error generating the report link.'))),
);
}
return dispatch(problemResponsesFailure(gettext('There was an error generating your report.')));
@@ -67,6 +74,7 @@ const getTaskStatus = (endpoint, taskId) => dispatch =>
const createProblemResponsesReportTask = (
problemResponsesEndpoint,
taskStatusEndpoint,
+ reportDownloadEndpoint,
blockId,
) => (dispatch) => {
dispatch(problemResponsesRequest(blockId));
@@ -78,7 +86,7 @@ const createProblemResponsesReportTask = (
throw new Error(response);
})
.then(
- json => dispatch(getTaskStatus(taskStatusEndpoint, json.task_id)),
+ json => dispatch(getTaskStatus(taskStatusEndpoint, reportDownloadEndpoint, json.task_id)),
() => dispatch(problemResponsesFailure(gettext('Unable to submit request to generate report.'))),
);
};
diff --git a/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/api/client.js b/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/api/client.js
index 532af508a5b9..843d754b7cda 100644
--- a/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/api/client.js
+++ b/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/api/client.js
@@ -25,9 +25,25 @@ const fetchTaskStatus = (endpoint, taskId) => fetch(
credentials: 'same-origin',
method: 'get',
headers: HEADERS,
- });
+ },
+ );
+
+const fetchDownloadsList = (endpoint, reportName) => {
+ const formData = new FormData();
+ formData.set('report_name', reportName);
+
+ return fetch(
+ endpoint, {
+ credentials: 'same-origin',
+ method: 'POST',
+ headers: HEADERS,
+ body: formData,
+ },
+ );
+};
export {
initiateProblemResponsesRequest,
fetchTaskStatus,
+ fetchDownloadsList,
};
diff --git a/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/reducers/index.js b/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/reducers/index.js
index 0c0c6a8c270c..c9d5f2133cec 100644
--- a/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/reducers/index.js
+++ b/lms/djangoapps/instructor/static/instructor/ProblemBrowser/data/reducers/index.js
@@ -1,5 +1,6 @@
import { combineReducers } from 'redux'; // eslint-disable-line
import { blocks, selectedBlock, rootBlock } from 'BlockBrowser/data/reducers'; // eslint-disable-line
+import blockBrowserActions from 'BlockBrowser/data/actions/constants'; // eslint-disable-line
import {
REPORT_GENERATION_ERROR,
REPORT_GENERATION_SUCCESS,
@@ -25,7 +26,7 @@ export const reportStatus = (state = initialState, action) => {
...state,
inProgress: action.inProgress,
succeeded: action.succeeded,
- reportPath: action.reportPath,
+ reportPath: action.downloadsData && action.downloadsData[0].url,
reportName: action.reportName,
error: null,
};
@@ -33,6 +34,8 @@ export const reportStatus = (state = initialState, action) => {
return { ...state, error: action.error, succeeded: false };
case REPORT_GENERATION_REFRESH_STATUS:
return { ...state, timeout: action.timeout };
+ case blockBrowserActions.SELECT_BLOCK:
+ return initialState;
default:
return state;
}
diff --git a/lms/djangoapps/instructor_task/tasks_helper/grades.py b/lms/djangoapps/instructor_task/tasks_helper/grades.py
index 1fda96f281a9..91d0cf69c8f7 100644
--- a/lms/djangoapps/instructor_task/tasks_helper/grades.py
+++ b/lms/djangoapps/instructor_task/tasks_helper/grades.py
@@ -1010,11 +1010,10 @@ def generate(cls, _xmodule_instance_args, _entry_id, course_id, task_input, acti
# Perform the upload
csv_name = cls._generate_upload_file_name(problem_locations, filter_types)
- report_name, report_path = upload_csv_to_report_store(rows, csv_name, course_id, start_date)
+ report_name = upload_csv_to_report_store(rows, csv_name, course_id, start_date)
current_step = {
'step': 'CSV uploaded',
'report_name': report_name,
- 'report_path': report_path,
}
return task_progress.update_task_state(extra_meta=current_step)
diff --git a/lms/djangoapps/instructor_task/tasks_helper/utils.py b/lms/djangoapps/instructor_task/tasks_helper/utils.py
index 607851f77f45..8a9afdb1eed4 100644
--- a/lms/djangoapps/instructor_task/tasks_helper/utils.py
+++ b/lms/djangoapps/instructor_task/tasks_helper/utils.py
@@ -44,9 +44,8 @@ def upload_csv_to_report_store(rows, csv_name, course_id, timestamp, config_name
)
report_store.store_rows(course_id, report_name, rows)
- report_path = report_store.storage.url(report_store.path_to(course_id, report_name))
tracker_emit(csv_name)
- return report_name, report_path
+ return report_name
def upload_zip_to_report_store(file, zip_name, course_id, timestamp, config_name='GRADES_DOWNLOAD'):
diff --git a/lms/templates/instructor/instructor_dashboard_2/data_download.html b/lms/templates/instructor/instructor_dashboard_2/data_download.html
index 67bc40dba005..c402ebb3fdd3 100644
--- a/lms/templates/instructor/instructor_dashboard_2/data_download.html
+++ b/lms/templates/instructor/instructor_dashboard_2/data_download.html
@@ -66,7 +66,8 @@ ${_("Reports")}
"courseId": course.id,
"excludeBlockTypes": ['html', 'video', 'discussion'],
"problemResponsesEndpoint": section_data['get_problem_responses_url'],
- "taskStatusEndpoint": "/instructor_task_status"
+ "taskStatusEndpoint": "/instructor_task_status",
+ "reportDownloadEndpoint": section_data['list_report_downloads_url']
}
)}