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

feat: option to show/hide ungraded assignment in progress page #29

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@ TWITTER_HASHTAG=''
TWITTER_URL=''
USER_INFO_COOKIE_NAME=''
OPTIMIZELY_FULL_STACK_SDK_KEY=''
SHOW_UNGRADED_ASSIGNMENT_PROGRESS=''
1 change: 1 addition & 0 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,4 @@ SESSION_COOKIE_DOMAIN='localhost'
CHAT_RESPONSE_URL='http://localhost:18000/api/learning_assistant/v1/course_id'
PRIVACY_POLICY_URL='http://localhost:18000/privacy'
OPTIMIZELY_FULL_STACK_SDK_KEY=''
SHOW_UNGRADED_ASSIGNMENT_PROGRESS=''
1 change: 1 addition & 0 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ TWITTER_HASHTAG='myedxjourney'
TWITTER_URL='https://twitter.com/edXOnline'
USER_INFO_COOKIE_NAME='edx-user-info'
PRIVACY_POLICY_URL='http://localhost:18000/privacy'
SHOW_UNGRADED_ASSIGNMENT_PROGRESS=''
117 changes: 115 additions & 2 deletions src/course-home/progress-tab/ProgressTab.test.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { Factory } from 'rosie';
import { getConfig } from '@edx/frontend-platform';
import { getConfig, setConfig } from '@edx/frontend-platform';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { breakpoints } from '@openedx/paragon';
Expand Down Expand Up @@ -545,6 +545,111 @@ describe('Progress Tab', () => {
await fetchAndRender();
expect(screen.getByText('Grades & Credit')).toBeInTheDocument();
});

it('does not render ungraded subsections when SHOW_UNGRADED_ASSIGNMENT_PROGRESS is false', async () => {
// The second assignment has has_graded_assignment set to false, so it should not be shown.
setTabData({
section_scores: [
{
display_name: 'First section',
subsections: [
{
assignment_type: 'Homework',
block_key: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@12345',
display_name: 'First subsection',
learner_has_access: true,
has_graded_assignment: true,
num_points_earned: 1,
num_points_possible: 2,
percent_graded: 1.0,
show_correctness: 'always',
show_grades: true,
url: 'http://learning.edx.org/course/course-v1:edX+Test+run/first_subsection',
},
],
},
{
display_name: 'Second section',
subsections: [
{
assignment_type: 'Homework',
display_name: 'Second subsection',
learner_has_access: true,
has_graded_assignment: false,
num_points_earned: 1,
num_points_possible: 1,
percent_graded: 1.0,
show_correctness: 'always',
show_grades: true,
url: 'http://learning.edx.org/course/course-v1:edX+Test+run/second_subsection',
},
],
},
],
});

await fetchAndRender();
expect(screen.getByText('First subsection')).toBeInTheDocument();
expect(screen.queryByText('Second subsection')).not.toBeInTheDocument();
});

it('renders both graded and ungraded subsections when SHOW_UNGRADED_ASSIGNMENT_PROGRESS is true', async () => {
// The second assignment has has_graded_assignment set to false.
setConfig({
...getConfig(),
SHOW_UNGRADED_ASSIGNMENT_PROGRESS: true,
});

setTabData({
section_scores: [
{
display_name: 'First section',
subsections: [
{
assignment_type: 'Homework',
block_key: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@12345',
display_name: 'First subsection',
learner_has_access: true,
has_graded_assignment: true,
num_points_earned: 1,
num_points_possible: 2,
percent_graded: 1.0,
show_correctness: 'always',
show_grades: true,
url: 'http://learning.edx.org/course/course-v1:edX+Test+run/first_subsection',
},
],
},
{
display_name: 'Second section',
subsections: [
{
assignment_type: 'Homework',
display_name: 'Second subsection',
learner_has_access: true,
has_graded_assignment: false,
num_points_earned: 1,
num_points_possible: 1,
percent_graded: 1.0,
show_correctness: 'always',
show_grades: true,
url: 'http://learning.edx.org/course/course-v1:edX+Test+run/second_subsection',
},
],
},
],
});

await fetchAndRender();
expect(screen.getByText('First subsection')).toBeInTheDocument();
expect(screen.getByText('Second subsection')).toBeInTheDocument();

// reset config for other tests
setConfig({
...getConfig(),
SHOW_UNGRADED_ASSIGNMENT_PROGRESS: false,
});
});
});

describe('Grade Summary', () => {
Expand Down Expand Up @@ -809,7 +914,7 @@ describe('Progress Tab', () => {

// Open the problem score drawer
fireEvent.click(problemScoreDrawerToggle);
expect(screen.getByText('Problem Scores:')).toBeInTheDocument();
expect(screen.getAllByText('Graded Scores:').length).toBeGreaterThan(1);
expect(screen.getAllByText('0/1')).toHaveLength(3);
});

Expand All @@ -821,6 +926,14 @@ describe('Progress Tab', () => {
expect(screen.getByText('Detailed grades')).toBeInTheDocument();
expect(screen.getByText('You currently have no graded problem scores.')).toBeInTheDocument();
});

it('renders Detailed Grades table when section scores are populated', async () => {
await fetchAndRender();
expect(screen.getByText('Detailed grades')).toBeInTheDocument();

expect(screen.getByText('First subsection'));
expect(screen.getByText('Second subsection'));
});
});

describe('Certificate Status', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { useSelector } from 'react-redux';

import { getConfig } from '@edx/frontend-platform';
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
Expand Down Expand Up @@ -28,6 +29,11 @@ const DetailedGrades = ({ intl }) => {
} = useModel('progress', courseId);

const hasSectionScores = sectionScores.length > 0;
const showUngradedAssignments = (
getConfig().SHOW_UNGRADED_ASSIGNMENT_PROGRESS === 'true'
|| getConfig().SHOW_UNGRADED_ASSIGNMENT_PROGRESS === true
);
const emptyTableMsg = showUngradedAssignments ? messages.detailedGradesEmpty : messages.detailedGradesEmptyOnlyGraded;

const logOutlineLinkClick = () => {
sendTrackEvent('edx.ui.lms.course_progress.detailed_grades.course_outline_link.clicked', {
Expand All @@ -54,7 +60,25 @@ const DetailedGrades = ({ intl }) => {

return (
<section className="text-dark-700">
<h3 className="h4 mb-3">{intl.formatMessage(messages.detailedGrades)}</h3>
<h3 className="h4">{intl.formatMessage(messages.detailedGrades)}</h3>
<ul className="micro mb-3 pl-3 text-gray-700">
<li>
<b>{intl.formatMessage(messages.practiceScoreLabel)} </b>
<FormattedMessage
id="progress.detailedGrades.practice-label.info.text"
defaultMessage="Scores from non-graded activities meant for practice and self-assessment."
description="Information text about non-graded practice score label"
/>
</li>
<li>
<b>{intl.formatMessage(messages.gradedScoreLabel)} </b>
<FormattedMessage
id="progress.detailedGrades.problem-label.info.text"
defaultMessage="Scores from activities that contribute to your final grade."
description="Information text about graded problem score label"
/>
</li>
</ul>
{gradesFeatureIsPartiallyLocked && (
<div className="mb-3 small ml-0 d-inline">
<Icon className="mr-1 mt-1 d-inline-flex" style={{ height: '1rem', width: '1rem' }} src={Blocked} data-testid="blocked-icon" />
Expand All @@ -65,9 +89,9 @@ const DetailedGrades = ({ intl }) => {
<DetailedGradesTable />
)}
{!hasSectionScores && (
<p className="small">{intl.formatMessage(messages.detailedGradesEmpty)}</p>
<p className="small">{intl.formatMessage(emptyTableMsg)}</p>
)}
{overviewTabUrl && (
{overviewTabUrl && !showUngradedAssignments && (
<p className="x-small m-0">
<FormattedMessage
id="progress.ungradedAlert"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { useSelector } from 'react-redux';

import { getConfig } from '@edx/frontend-platform';
import {
getLocale, injectIntl, intlShape, isRtl,
} from '@edx/frontend-platform/i18n';
Expand All @@ -20,13 +21,18 @@ const DetailedGradesTable = ({ intl }) => {
} = useModel('progress', courseId);

const isLocaleRtl = isRtl(getLocale());
const showUngradedAssignments = (
getConfig().SHOW_UNGRADED_ASSIGNMENT_PROGRESS === 'true'
|| getConfig().SHOW_UNGRADED_ASSIGNMENT_PROGRESS === true
);
return (
sectionScores.map((chapter) => {
const subsectionScores = chapter.subsections.filter(
(subsection) => !!(
subsection.hasGradedAssignment
&& subsection.showGrades
&& (subsection.numPointsPossible > 0 || subsection.numPointsEarned > 0)),
(showUngradedAssignments || subsection.hasGradedAssignment)
&& subsection.showGrades
&& (subsection.numPointsPossible > 0 || subsection.numPointsEarned > 0)
),
);

if (subsectionScores.length === 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ import messages from '../messages';

const ProblemScoreDrawer = ({ intl, problemScores, subsection }) => {
const isLocaleRtl = isRtl(getLocale());

const scoreLabel = subsection.hasGradedAssignment ? messages.gradedScoreLabel : messages.practiceScoreLabel;

return (
<span className="row w-100 m-0 x-small ml-4 pt-2 pl-1 text-gray-700 flex-nowrap">
<span id="problem-score-label" className="col-auto p-0">{intl.formatMessage(messages.problemScoreLabel)}</span>
<span id="problem-score-label" className="col-auto p-0">{intl.formatMessage(scoreLabel)}</span>
<div className={classNames('col', 'p-0', { 'greyed-out': !subsection.learnerHasAccess })}>
<ul className="list-unstyled row w-100 m-0" aria-labelledby="problem-score-label">
{problemScores.map((problemScore, i) => (
Expand All @@ -31,7 +34,10 @@ ProblemScoreDrawer.propTypes = {
earned: PropTypes.number.isRequired,
possible: PropTypes.number.isRequired,
})).isRequired,
subsection: PropTypes.shape({ learnerHasAccess: PropTypes.bool }).isRequired,
subsection: PropTypes.shape({
learnerHasAccess: PropTypes.bool,
hasGradedAssignment: PropTypes.bool,
}).isRequired,
};

export default injectIntl(ProblemScoreDrawer);
16 changes: 13 additions & 3 deletions src/course-home/progress-tab/grades/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,14 @@ const messages = defineMessages({
defaultMessage: 'Detailed grades',
description: 'Headline for the (detailed grade) section in the progress tab',
},
detailedGradesEmpty: {
detailedGradesEmptyOnlyGraded: {
id: 'progress.detailedGrades.emptyTable',
defaultMessage: 'You currently have no graded problem scores.',
description: 'It indicate that there are no graded problem or assignments to be scored',
},
detailedGradesEmpty: {
id: 'progress.detailedGrades.including-ungraded.emptyTable',
defaultMessage: 'You currently have no graded or ungraded problem scores.',
description: 'It indicate that there are no problem or assignments to be scored',
},
footnotesTitle: {
Expand Down Expand Up @@ -158,11 +163,16 @@ const messages = defineMessages({
defaultMessage: 'Passing grade',
description: 'Label for mark on the (grade bar) chart which indicate the poisition of passing grade on the bar',
},
problemScoreLabel: {
gradedScoreLabel: {
id: 'progress.detailedGrades.problemScore.label',
defaultMessage: 'Problem Scores:',
defaultMessage: 'Graded Scores:',
description: 'Label text which precedes detailed view of all scores per assignment',
},
practiceScoreLabel: {
id: 'progress.detailedGrades.practice.problemScore.label',
defaultMessage: 'Practice Scores:',
description: 'Label text which precedes detailed view of all ungraded problem scores per assignment',
},
problemScoreToggleAltText: {
id: 'progress.detailedGrades.problemScore.toggleButton',
defaultMessage: 'Toggle individual problem scores for {subsectionTitle}',
Expand Down
1 change: 1 addition & 0 deletions src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ initialize({
PROCTORED_EXAM_RULES_URL: process.env.PROCTORED_EXAM_RULES_URL || null,
CHAT_RESPONSE_URL: process.env.CHAT_RESPONSE_URL || null,
PRIVACY_POLICY_URL: process.env.PRIVACY_POLICY_URL || null,
SHOW_UNGRADED_ASSIGNMENT_PROGRESS: process.env.SHOW_UNGRADED_ASSIGNMENT_PROGRESS || false,
}, 'LearnerAppConfig');
},
},
Expand Down
Loading