Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Publish Grading Feature #2546

Closed
wants to merge 13 commits into from
2 changes: 1 addition & 1 deletion src/commons/achievement/utils/InsertFakeAchievements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ function insertFakeAchievements(
requiredCompletionFrac: 0
}
},
assessmentOverview.gradingStatus === 'graded'
assessmentOverview.gradingStatus === 'published'
);
}

Expand Down
12 changes: 12 additions & 0 deletions src/commons/application/actions/SessionActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
LOGOUT_GOOGLE,
NotificationConfiguration,
NotificationPreference,
PUBLISH_GRADES,
REAUTOGRADE_ANSWER,
REAUTOGRADE_SUBMISSION,
REMOVE_GITHUB_OCTOKIT_OBJECT_AND_ACCESS_TOKEN,
Expand All @@ -64,6 +65,7 @@ import {
SUBMIT_GRADING_AND_CONTINUE,
TimeOption,
Tokens,
UNPUBLISH_GRADES,
UNSUBMIT_SUBMISSION,
UPDATE_ALL_USER_XP,
UPDATE_ASSESSMENT,
Expand Down Expand Up @@ -230,6 +232,16 @@ export const unsubmitSubmission = (submissionId: number) =>
submissionId
});

export const unpublishGrades = (submissionId: number) =>
action(UNPUBLISH_GRADES, {
submissionId
});

export const publishGrades = (submissionId: number) =>
action(PUBLISH_GRADES, {
submissionId
});

/**
* Notification actions
*/
Expand Down
3 changes: 2 additions & 1 deletion src/commons/application/actions/__tests__/SessionActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,8 @@ test('updateGradingOverviews generates correct action object', () => {
groupName: 'group',
gradingStatus: 'excluded',
questionCount: 6,
gradedCount: 0
gradedCount: 0,
isGradingPublished: true
}
];

Expand Down
6 changes: 4 additions & 2 deletions src/commons/application/reducers/__tests__/SessionReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,8 @@ const gradingOverviewTest1: GradingOverview[] = [
groupName: 'group',
gradingStatus: 'excluded',
questionCount: 0,
gradedCount: 6
gradedCount: 6,
isGradingPublished: true
}
];

Expand All @@ -508,7 +509,8 @@ const gradingOverviewTest2: GradingOverview[] = [
groupName: 'another group',
gradingStatus: 'excluded',
questionCount: 6,
gradedCount: 0
gradedCount: 0,
isGradingPublished: false
}
];

Expand Down
2 changes: 2 additions & 0 deletions src/commons/application/types/SessionTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const LOGIN = 'LOGIN';
export const LOGOUT_GOOGLE = 'LOGOUT_GOOGLE';
export const LOGIN_GITHUB = 'LOGIN_GITHUB';
export const LOGOUT_GITHUB = 'LOGOUT_GITHUB';
export const PUBLISH_GRADES = 'PUBLISH_GRADES';
export const SET_TOKENS = 'SET_TOKENS';
export const SET_USER = 'SET_USER';
export const SET_COURSE_CONFIGURATION = 'SET_COURSE_CONFIGURATION';
Expand All @@ -45,6 +46,7 @@ export const REAUTOGRADE_SUBMISSION = 'REAUTOGRADE_SUBMISSION';
export const REAUTOGRADE_ANSWER = 'REAUTOGRADE_ANSWER';
export const REMOVE_GITHUB_OCTOKIT_OBJECT_AND_ACCESS_TOKEN =
'REMOVE_GITHUB_OCTOKIT_OBJECT_AND_ACCESS_TOKEN';
export const UNPUBLISH_GRADES = 'UNPUBLISH_GRADES';
export const UNSUBMIT_SUBMISSION = 'UNSUBMIT_SUBMISSION';
export const UPDATE_ASSESSMENT_OVERVIEWS = 'UPDATE_ASSESSMENT_OVERVIEWS';
export const UPDATE_TOTAL_XP = 'UPDATE_TOTAL_XP';
Expand Down
11 changes: 8 additions & 3 deletions src/commons/assessment/Assessment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ const Assessment: React.FC<AssessmentProps> = props => {
renderGradingStatus: boolean
) => {
const showGrade =
overview.gradingStatus === 'graded' || !props.assessmentConfiguration.isManuallyGraded;
overview.gradingStatus === 'published' || !props.assessmentConfiguration.isManuallyGraded;
const ratio = isMobileBreakpoint ? 5 : 3;
return (
<div key={index}>
Expand Down Expand Up @@ -414,10 +414,15 @@ const makeGradingStatus = (gradingStatus: string) => {
let tooltip: string;

switch (gradingStatus) {
case GradingStatuses.graded:
case GradingStatuses.published:
iconName = IconNames.TICK;
intent = Intent.SUCCESS;
tooltip = 'Fully graded';
tooltip = 'Grade published';
break;
case GradingStatuses.graded:
iconName = IconNames.TIME;
intent = Intent.WARNING;
tooltip = 'Grading in progress';
break;
case GradingStatuses.grading:
iconName = IconNames.TIME;
Expand Down
1 change: 1 addition & 0 deletions src/commons/assessment/AssessmentTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type AssessmentWorkspaceParams = {

export enum GradingStatuses {
excluded = 'excluded',
published = 'published',
graded = 'graded',
grading = 'grading',
none = 'none'
Expand Down
9 changes: 6 additions & 3 deletions src/commons/mocks/GradingMocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ export const mockGradingOverviews: GradingOverview[] = [
groupName: '1D',
gradingStatus: 'graded',
questionCount: 6,
gradedCount: 6
gradedCount: 6,
isGradingPublished: false
},
{
xpAdjustment: -2,
Expand All @@ -40,7 +41,8 @@ export const mockGradingOverviews: GradingOverview[] = [
groupName: '1F',
gradingStatus: 'grading',
questionCount: 6,
gradedCount: 2
gradedCount: 2,
isGradingPublished: false
},
{
xpAdjustment: 4,
Expand All @@ -58,7 +60,8 @@ export const mockGradingOverviews: GradingOverview[] = [
groupName: '1F',
gradingStatus: 'none',
questionCount: 6,
gradedCount: 0
gradedCount: 0,
isGradingPublished: false
}
];

Expand Down
4 changes: 3 additions & 1 deletion src/commons/notificationBadge/NotificationBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,10 @@ const makeNotificationMessage = (type: NotificationType) => {
return 'This submission is new.';
case NotificationTypes.unsubmitted:
return 'This assessment has been unsubmitted.';
case NotificationTypes.unpublished_grading:
return 'Grades have been hidden for this assessment.';
case NotificationTypes.graded:
return 'This assessment has been manually graded.';
return 'Grades have been published for this assessment.';
case NotificationTypes.new_message:
return 'There are new messages.';
default:
Expand Down
1 change: 1 addition & 0 deletions src/commons/notificationBadge/NotificationBadgeTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export enum NotificationTypes {
graded = 'graded',
submitted = 'submitted',
unsubmitted = 'unsubmitted',
unpublished_grading = 'unpublished_grading',
new_message = 'new_message'
}

Expand Down
2 changes: 1 addition & 1 deletion src/commons/profile/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ const Profile: React.FC<ProfileProps> = props => {
.filter(
item =>
item.status === AssessmentStatuses.submitted &&
(item.gradingStatus === GradingStatuses.graded ||
(item.gradingStatus === GradingStatuses.published ||
item.gradingStatus === GradingStatuses.excluded)
)
.map((assessment, index) => {
Expand Down
41 changes: 41 additions & 0 deletions src/commons/sagas/BackendSaga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,15 @@ import {
FETCH_TOTAL_XP_ADMIN,
FETCH_USER_AND_COURSE,
NotificationConfiguration,
PUBLISH_GRADES,
REAUTOGRADE_ANSWER,
REAUTOGRADE_SUBMISSION,
SUBMIT_ANSWER,
SUBMIT_GRADING,
SUBMIT_GRADING_AND_CONTINUE,
TimeOption,
Tokens,
UNPUBLISH_GRADES,
UNSUBMIT_SUBMISSION,
UPDATE_ASSESSMENT_CONFIGS,
UPDATE_COURSE_CONFIG,
Expand Down Expand Up @@ -110,9 +112,11 @@ import {
postAuth,
postCreateCourse,
postGrading,
postPublishGrades,
postReautogradeAnswer,
postReautogradeSubmission,
postSourcecast,
postUnpublishGrades,
postUnsubmit,
putAssessmentConfigs,
putCourseConfig,
Expand Down Expand Up @@ -455,6 +459,43 @@ function* BackendSaga(): SagaIterator {
}
);

/**
* Publishes the grades for the submission and refreshes the grading overviews to reflect backend
* changes to the grading published status.
*/
yield takeEvery(
PUBLISH_GRADES,
function* (action: ReturnType<typeof actions.publishGrades>): any {
const tokens: Tokens = yield selectTokens();
const { submissionId } = action.payload;

const resp: Response | null = yield postPublishGrades(submissionId, tokens);
if (!resp || !resp.ok) {
return yield handleResponseError(resp);
}

yield call(showSuccessMessage, 'Publish successful', 1000);
}
);

/**
* Unpublished the grades for the submission and refreshes the whole page automatically.
*/
yield takeEvery(
UNPUBLISH_GRADES,
function* (action: ReturnType<typeof actions.unpublishGrades>): any {
const tokens: Tokens = yield selectTokens();
const { submissionId } = action.payload;

const resp: Response | null = yield postUnpublishGrades(submissionId, tokens);
if (!resp || !resp.ok) {
return yield handleResponseError(resp);
}

yield call(showSuccessMessage, 'Unpublish successful', 1000);
}
);

const sendGrade = function* (
action:
| ReturnType<typeof actions.submitGrading>
Expand Down
55 changes: 48 additions & 7 deletions src/commons/sagas/RequestsSaga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,8 @@ export const getAssessmentOverviews = async (
overview.isManuallyGraded,
overview.status,
overview.gradedCount,
overview.questionCount
overview.questionCount,
overview.isGradingPublished
);
delete overview.gradedCount;
delete overview.questionCount;
Expand Down Expand Up @@ -476,7 +477,8 @@ export const getUserAssessmentOverviews = async (
overview.isManuallyGraded,
overview.status,
overview.gradedCount,
overview.questionCount
overview.questionCount,
overview.isGradingPublished
);
delete overview.gradedCount;
delete overview.questionCount;
Expand Down Expand Up @@ -631,6 +633,7 @@ export const getGradingOverviews = async (
gradingStatus: 'none',
questionCount: overview.assessment.questionCount,
gradedCount: overview.gradedCount,
isGradingPublished: overview.isGradingPublished,
// XP
initialXp: overview.xp,
xpAdjustment: overview.xpAdjustment,
Expand All @@ -642,7 +645,8 @@ export const getGradingOverviews = async (
overview.assessment.isManuallyGraded,
gradingOverview.submissionStatus,
gradingOverview.gradedCount,
gradingOverview.questionCount
gradingOverview.questionCount,
gradingOverview.isGradingPublished
);
return gradingOverview;
})
Expand Down Expand Up @@ -777,6 +781,40 @@ export const postUnsubmit = async (
return resp;
};

/**
* POST /courses/{courseId}/admin/grading/{submissionId}/unpublish_grades
*/
export const postUnpublishGrades = async (
submissionId: number,
tokens: Tokens
): Promise<Response | null> => {
const resp = await request(
`${courseId()}/admin/grading/${submissionId}/unpublish_grades`,
'POST',
{
...tokens,
noHeaderAccept: true
}
);

return resp;
};

/**
* POST /courses/{courseId}/admin/grading/{submissionId}/publish_grades
*/
export const postPublishGrades = async (
submissionId: number,
tokens: Tokens
): Promise<Response | null> => {
const resp = await request(`${courseId()}/admin/grading/${submissionId}/publish_grades`, 'POST', {
...tokens,
noHeaderAccept: true
});

return resp;
};

/**
* GET /courses/{courseId}/notifications
*/
Expand Down Expand Up @@ -1356,16 +1394,19 @@ const computeGradingStatus = (
isManuallyGraded: boolean,
submissionStatus: any,
numGraded: number,
numQuestions: number
numQuestions: number,
isGradingPublished: boolean
): GradingStatus =>
// isGraded refers to whether the assessment type is graded or not, as specified in
// the respective assessment configuration
isManuallyGraded && submissionStatus === 'submitted'
? numGraded === 0
? 'none'
: numGraded === numQuestions
? 'graded'
: 'grading'
: numGraded < numQuestions
? 'grading'
: isGradingPublished
? 'published'
: 'graded'
: 'excluded';

const courseId: () => string = () => {
Expand Down
1 change: 1 addition & 0 deletions src/features/grading/GradingTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export type GradingOverview = {
gradingStatus: GradingStatus;
questionCount: number;
gradedCount: number;
isGradingPublished: boolean;
};

export type GradingOverviewWithNotifications = {
Expand Down
Loading