Files
frontend-app-ora-grading/src/data/thunkActions/grading.js
2021-10-21 10:11:45 -04:00

159 lines
5.4 KiB
JavaScript

import { StrictDict } from 'utils';
import { RequestKeys } from 'data/constants/requests';
import actions from 'data/actions';
import selectors from 'data/selectors';
import { gradingStatuses as statuses } from 'data/services/lms/constants';
import * as module from './grading';
import requests from './requests';
/**
* Prefetch the "next" submission in the selected queue. Only fetches the response info.
*/
export const prefetchNext = () => (dispatch, getState) => {
dispatch(requests.fetchSubmissionResponse({
requestKey: RequestKeys.prefetchNext,
submissionId: selectors.grading.next.submissionId(getState()),
onSuccess: (response) => {
dispatch(actions.grading.preloadNext(response));
},
}));
};
/**
* Prefetch the "previous" submission in the selected queue. Only fetches the response info.
*/
export const prefetchPrev = () => (dispatch, getState) => {
dispatch(requests.fetchSubmissionResponse({
requestKey: RequestKeys.prefetchPrev,
submissionId: selectors.grading.prev.submissionId(getState()),
onSuccess: (response) => {
dispatch(actions.grading.preloadPrev(response));
},
}));
};
/**
* Fetch the target neighbor submission's status, start grading if in progress,
* dispatches load action with the response (injecting submissionId). If hasNeighbor,
* also dispatches the prefetchAction to pre-fetch the new neighbor's response.
* @param {string} submissionId - target submission id
* @param {action} loadAction - redux action/thunkAction to load the submission status
* @param {bool} hasNeighbor - is there a new neighbor to be pre-fetched?
* @param {action} prefetchAction - redux action/thunkAction to prefetch the new
* neighbor's response.
*/
export const fetchNeighbor = ({
submissionId,
loadAction,
hasNeighbor,
prefetchAction,
}) => (dispatch) => {
dispatch(requests.fetchSubmissionStatus({
submissionId,
onSuccess: (response) => {
if (response.lockStatus === statuses.inProgress) {
dispatch(module.startGrading());
} else {
dispatch(module.stopGrading());
}
dispatch(loadAction({ ...response, submissionId }));
if (hasNeighbor) { dispatch(prefetchAction()); }
},
}));
};
/**
* Fetches the current status for the "next" submission in the selected queue,
* and calls loadNext with it to update the current selection index info.
* If the new index has a next submission available, preload its response.
*/
export const loadNext = () => (dispatch, getState) => {
dispatch(module.fetchNeighbor({
loadAction: actions.grading.loadNext,
hasNeighbor: selectors.grading.next.doesExist(getState()),
prefetchAction: module.prefetchNext,
submissionId: selectors.grading.next.submissionId(getState()),
}));
};
/**
* Fetches the current status for the "previous" submission in the selected queue,
* and calls loadPrev with it to update the current selection index info.
* If the new index has a previous submission available, preload its response.
*/
export const loadPrev = () => (dispatch, getState) => {
dispatch(module.fetchNeighbor({
loadAction: actions.grading.loadPrev,
hasNeighbor: selectors.grading.prev.doesExist(getState()),
prefetchAction: module.prefetchPrev,
submissionId: selectors.grading.prev.submissionId(getState()),
}));
};
/**
* Load a list of selected submissionIds, sets the app to review mode, and fetches the current
* selected submission's full data (grade data, status, and rubric).
* Then loads current selection and prefetches neighbors.
* @param {string[]} submissionIds - ordered list of submissionIds for selected submissions
*/
export const loadSelectionForReview = (submissionIds) => (dispatch, getState) => {
dispatch(requests.fetchSubmission({
submissionId: submissionIds[0],
onSuccess: (response) => {
dispatch(actions.grading.updateSelection(submissionIds));
dispatch(actions.grading.loadSubmission({
...response,
submissionId: submissionIds[0],
}));
dispatch(actions.app.setShowReview(true));
if (selectors.grading.next.doesExist(getState())) {
dispatch(module.prefetchNext());
}
if (selectors.grading.prev.doesExist(getState())) {
dispatch(module.prefetchPrev());
}
},
}));
};
/**
* Start grading the current submission.
* Attempts to lock the submisison, and on a success, sets the local grading state to
* True, and then loads initializes the grading process with GradeData associated with
* the current submission. If there is no grade data, generates an empty grade entry
* based on the rubric config.
*/
export const startGrading = () => (dispatch, getState) => {
dispatch(requests.setLock({
value: true,
submissionId: selectors.grading.selected.submissionId(getState()),
onSuccess: () => {
dispatch(actions.app.setGrading(true));
let gradeData = selectors.grading.selected.gradeData(getState());
if (!gradeData) {
gradeData = selectors.app.emptyGrade(getState());
}
dispatch(actions.grading.startGrading(gradeData));
},
}));
};
/**
* Stops the grading process for the current submisison
* Clears the local grade data for the current submission and sets grading state
* to False
*/
export const stopGrading = () => (dispatch) => {
dispatch(actions.grading.clearGrade());
dispatch(actions.app.setGrading(false));
};
export default StrictDict({
loadSelectionForReview,
loadNext,
loadPrev,
startGrading,
stopGrading,
});