Merge pull request #28233 from edx/ddumesnil/hide-content-after-due-progress-aa-912
fix: AA-912: Hide URL after due date if subsection is marked as hide …
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
"""
|
||||
Progress Tab Serializers
|
||||
"""
|
||||
from datetime import datetime
|
||||
|
||||
from rest_framework import serializers
|
||||
from rest_framework.reverse import reverse
|
||||
from pytz import UTC
|
||||
|
||||
from lms.djangoapps.course_home_api.mixins import VerifiedModeSerializerMixin
|
||||
|
||||
|
||||
@@ -20,8 +24,8 @@ class SubsectionScoresSerializer(serializers.Serializer):
|
||||
Serializer for subsections in section_scores
|
||||
"""
|
||||
assignment_type = serializers.CharField(source='format')
|
||||
display_name = serializers.CharField()
|
||||
block_key = serializers.SerializerMethodField()
|
||||
display_name = serializers.CharField()
|
||||
has_graded_assignment = serializers.BooleanField(source='graded')
|
||||
learner_has_access = serializers.SerializerMethodField()
|
||||
num_points_earned = serializers.FloatField(source='graded_total.earned')
|
||||
@@ -46,6 +50,15 @@ class SubsectionScoresSerializer(serializers.Serializer):
|
||||
return problem_scores
|
||||
|
||||
def get_url(self, subsection):
|
||||
"""
|
||||
Returns the URL for the subsection while taking into account if the course team has
|
||||
marked the subsection's visibility as hide after due.
|
||||
"""
|
||||
hide_url_date = (subsection.self_paced and subsection.end) or subsection.due
|
||||
if (not self.context['staff_access'] and subsection.hide_after_due and hide_url_date
|
||||
and datetime.now(UTC) > hide_url_date):
|
||||
return None
|
||||
|
||||
relative_path = reverse('jump_to', args=[self.context['course_key'], subsection.location])
|
||||
request = self.context['request']
|
||||
return request.build_absolute_uri(relative_path)
|
||||
|
||||
@@ -208,3 +208,22 @@ class ProgressTabTestViews(BaseCourseHomeTests):
|
||||
|
||||
response = self.client.get(self.url)
|
||||
assert response.data['username'] == other_user.username
|
||||
|
||||
@override_waffle_flag(COURSE_HOME_MICROFRONTEND_PROGRESS_TAB, active=True)
|
||||
def test_url_hidden_if_subsection_hide_after_due(self):
|
||||
chapter = ItemFactory(parent=self.course, category='chapter')
|
||||
yesterday = now() - timedelta(days=1)
|
||||
hide_after_due_subsection = ItemFactory(
|
||||
parent=chapter, category='sequential', hide_after_due=True, due=yesterday
|
||||
)
|
||||
|
||||
CourseEnrollment.enroll(self.user, self.course.id)
|
||||
|
||||
response = self.client.get(self.url)
|
||||
assert response.status_code == 200
|
||||
|
||||
sections = response.data['section_scores']
|
||||
regular_subsection = sections[0]['subsections'][0] # default sequence that parent class gives us
|
||||
hide_after_due_subsection = sections[1]['subsections'][0]
|
||||
assert regular_subsection['url'] is not None
|
||||
assert hide_after_due_subsection['url'] is None
|
||||
|
||||
@@ -86,7 +86,8 @@ class ProgressTabView(RetrieveAPIView):
|
||||
('always', 'never', 'past_due', values defined in
|
||||
common/lib/xmodule/xmodule/modulestore/inheritance.py)
|
||||
show_grades: (bool) a bool for whether to show grades based on the access the user has
|
||||
url: (str) the absolute path url to the Subsection
|
||||
url: (str or None) the absolute path url to the Subsection or None if the Subsection is no longer accessible
|
||||
to the learner due to a hide_after_due course team setting
|
||||
enrollment_mode: (str) a str representing the enrollment the user has ('audit', 'verified', ...)
|
||||
grading_policy:
|
||||
assignment_policies: List of serialized assignment grading policy objects, each has the following fields:
|
||||
|
||||
@@ -27,9 +27,14 @@ class SubsectionGradeBase(metaclass=ABCMeta):
|
||||
self.display_name = block_metadata_utils.display_name_with_default(subsection)
|
||||
self.url_name = block_metadata_utils.url_name_for_block(subsection)
|
||||
|
||||
self.format = getattr(subsection, 'format', '')
|
||||
self.due = getattr(subsection, 'due', None)
|
||||
self.end = getattr(subsection, 'end', None)
|
||||
self.format = getattr(subsection, 'format', '')
|
||||
self.graded = getattr(subsection, 'graded', False)
|
||||
transformer_data = getattr(subsection, 'transformer_data', None)
|
||||
hidden_content_data = transformer_data and subsection.transformer_data.get('hidden_content')
|
||||
self.hide_after_due = hidden_content_data and hidden_content_data.fields.get('merged_hide_after_due')
|
||||
self.self_paced = subsection.self_paced
|
||||
self.show_correctness = getattr(subsection, 'show_correctness', '')
|
||||
|
||||
self.course_version = getattr(subsection, 'course_version', None)
|
||||
|
||||
@@ -3,16 +3,18 @@
|
||||
<%namespace name='static' file='/static_content.html'/>
|
||||
<%def name="online_help_token()"><% return "progress" %></%def>
|
||||
<%!
|
||||
from datetime import datetime
|
||||
|
||||
from django.conf import settings
|
||||
from django.urls import reverse
|
||||
from django.utils.http import urlquote_plus
|
||||
from django.utils.translation import ugettext as _
|
||||
from pytz import UTC
|
||||
|
||||
from common.djangoapps.course_modes.models import CourseMode
|
||||
from lms.djangoapps.certificates.data import CertificateStatuses
|
||||
from lms.djangoapps.grades.api import constants as grades_constants
|
||||
from django.utils.translation import ugettext as _
|
||||
from openedx.core.djangolib.markup import HTML, Text
|
||||
from django.urls import reverse
|
||||
from django.conf import settings
|
||||
from django.utils.http import urlquote_plus
|
||||
from six import text_type
|
||||
|
||||
from openedx.features.enterprise_support.utils import get_enterprise_learner_generic_name
|
||||
%>
|
||||
|
||||
@@ -73,7 +75,7 @@ username = get_enterprise_learner_generic_name(request) or student.username
|
||||
%if certificate_data:
|
||||
<div class="auto-cert-message" id="course-success">
|
||||
<div class="has-actions">
|
||||
<% post_url = reverse('generate_user_cert', args=[text_type(course.id)]) %>
|
||||
<% post_url = reverse('generate_user_cert', args=[str(course.id)]) %>
|
||||
<div class="msg-content">
|
||||
<h4 class="hd hd-4 title">${_(certificate_data.title)}</h4>
|
||||
<p class="copy">${_(certificate_data.msg)}</p>
|
||||
@@ -169,20 +171,33 @@ username = get_enterprise_learner_generic_name(request) or student.username
|
||||
%for section in chapter['sections']:
|
||||
<div>
|
||||
<%
|
||||
hide_url_date = (section.self_paced and section.end) or section.due
|
||||
hide_url = not staff_access and section.hide_after_due and hide_url_date and datetime.now(UTC) > hide_url_date
|
||||
|
||||
earned = section.graded_total.earned
|
||||
total = section.graded_total.possible
|
||||
|
||||
percentageString = "{0:.0%}".format(section.percent_graded) if total > 0 or earned > 0 else ""
|
||||
%>
|
||||
<h4 class="hd hd-4">
|
||||
<a href="${reverse('courseware_section', kwargs=dict(course_id=text_type(course.id), chapter=chapter['url_name'], section=section.url_name))}">
|
||||
${ section.display_name}
|
||||
%if hide_url:
|
||||
<p class="d-inline">${section.display_name}
|
||||
%if (total > 0 or earned > 0) and section.show_grades(staff_access):
|
||||
<span class="sr">
|
||||
${_("{earned} of {total} possible points").format(earned='{:.3n}'.format(float(earned)), total='{:.3n}'.format(float(total)))}
|
||||
</span>
|
||||
%endif
|
||||
</a>
|
||||
<span class="sr">
|
||||
${_("{earned} of {total} possible points").format(earned='{:.3n}'.format(float(earned)), total='{:.3n}'.format(float(total)))}
|
||||
</span>
|
||||
%endif
|
||||
</p>
|
||||
%else:
|
||||
<a href="${reverse('courseware_section', kwargs=dict(course_id=str(course.id), chapter=chapter['url_name'], section=section.url_name))}">
|
||||
${ section.display_name}
|
||||
%if (total > 0 or earned > 0) and section.show_grades(staff_access):
|
||||
<span class="sr">
|
||||
${_("{earned} of {total} possible points").format(earned='{:.3n}'.format(float(earned)), total='{:.3n}'.format(float(total)))}
|
||||
</span>
|
||||
%endif
|
||||
</a>
|
||||
%endif
|
||||
%if (total > 0 or earned > 0) and section.show_grades(staff_access):
|
||||
<span> ${"({0:.3n}/{1:.3n}) {2}".format( float(earned), float(total), percentageString )}</span>
|
||||
%endif
|
||||
|
||||
@@ -327,7 +327,6 @@ class TransformerData(FieldData):
|
||||
"""
|
||||
Data structure to encapsulate collected data for a transformer.
|
||||
"""
|
||||
pass # lint-amnesty, pylint: disable=unnecessary-pass
|
||||
|
||||
|
||||
class TransformerDataMap(dict):
|
||||
|
||||
Reference in New Issue
Block a user