Merge pull request #24133 from cpennington/use-content-type-gating-in-dates-banner
Use content type gating in dates banner
This commit is contained in:
@@ -72,7 +72,7 @@ class DatesTabView(RetrieveAPIView):
|
||||
|
||||
course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=False)
|
||||
blocks = get_course_date_blocks(course, request.user, request, include_access=True, include_past_dates=True)
|
||||
display_reset_dates_text, _ = dates_banner_should_display(course_key, request)
|
||||
display_reset_dates_text = dates_banner_should_display(course_key, request)
|
||||
|
||||
learner_is_verified = False
|
||||
enrollment = get_enrollment(request.user.username, course_key_string)
|
||||
|
||||
@@ -107,6 +107,8 @@ from openedx.core.djangoapps.site_configuration import helpers as configuration_
|
||||
from openedx.core.djangoapps.util.user_messages import PageLevelMessages
|
||||
from openedx.core.djangoapps.zendesk_proxy.utils import create_zendesk_ticket
|
||||
from openedx.core.djangolib.markup import HTML, Text
|
||||
from openedx.core.lib.mobile_utils import is_request_from_mobile_app
|
||||
from openedx.features.content_type_gating.models import ContentTypeGatingConfig
|
||||
from openedx.features.course_duration_limits.access import generate_course_expired_fragment
|
||||
from openedx.features.course_experience import (
|
||||
COURSE_ENABLE_UNENROLLED_ACCESS_FLAG,
|
||||
@@ -1061,7 +1063,7 @@ def dates(request, course_id):
|
||||
user_timezone = user_timezone_locale['user_timezone']
|
||||
user_language = user_timezone_locale['user_language']
|
||||
|
||||
missed_deadlines, enrollment_mode = dates_banner_should_display(course_key, request)
|
||||
missed_deadlines = dates_banner_should_display(course_key, request)
|
||||
|
||||
context = {
|
||||
'course': course,
|
||||
@@ -1074,8 +1076,11 @@ def dates(request, course_id):
|
||||
'can_masquerade': can_masquerade,
|
||||
'masquerade': masquerade,
|
||||
'on_dates_tab': True,
|
||||
'content_type_gating_enabled': ContentTypeGatingConfig.enabled_for_enrollment(
|
||||
user=request.user,
|
||||
course_key=course_key,
|
||||
),
|
||||
'missed_deadlines': missed_deadlines,
|
||||
'enrollment_mode': enrollment_mode,
|
||||
'reset_deadlines_url': reverse(RESET_COURSE_DEADLINES_NAME),
|
||||
'reset_deadlines_redirect_url_base': COURSE_DATES_NAME,
|
||||
'reset_deadlines_redirect_url_id_dict': {'course_id': str(course.id)}
|
||||
@@ -1622,7 +1627,7 @@ def render_xblock(request, usage_key_string, check_if_enrolled=True):
|
||||
Returns an HttpResponse with HTML content for the xBlock with the given usage_key.
|
||||
The returned HTML is a chromeless rendering of the xBlock (excluding content of the containing courseware).
|
||||
"""
|
||||
from lms.urls import RENDER_XBLOCK_NAME, RESET_COURSE_DEADLINES_NAME
|
||||
from lms.urls import COURSE_DATES_NAME, RESET_COURSE_DEADLINES_NAME
|
||||
from openedx.features.course_experience.urls import COURSE_HOME_VIEW_NAME
|
||||
|
||||
usage_key = UsageKey.from_string(usage_key_string)
|
||||
@@ -1661,7 +1666,7 @@ def render_xblock(request, usage_key_string, check_if_enrolled=True):
|
||||
'mark-completed-on-view-after-delay': completion_service.get_complete_on_view_delay_ms()
|
||||
}
|
||||
|
||||
missed_deadlines, enrollment_mode = dates_banner_should_display(course_key, request)
|
||||
missed_deadlines = dates_banner_should_display(course_key, request)
|
||||
|
||||
context = {
|
||||
'fragment': block.render('student_view', context=student_view_context),
|
||||
@@ -1676,11 +1681,18 @@ def render_xblock(request, usage_key_string, check_if_enrolled=True):
|
||||
'staff_access': bool(request.user.has_perm(VIEW_XQA_INTERFACE, course)),
|
||||
'xqa_server': settings.FEATURES.get('XQA_SERVER', 'http://your_xqa_server.com'),
|
||||
'missed_deadlines': missed_deadlines,
|
||||
'enrollment_mode': enrollment_mode,
|
||||
'web_app_course_url': reverse(COURSE_HOME_VIEW_NAME, args=[course.id]),
|
||||
'on_courseware_page': True,
|
||||
'content_type_gating_enabled': ContentTypeGatingConfig.enabled_for_enrollment(
|
||||
user=request.user,
|
||||
course_key=course_key,
|
||||
),
|
||||
'verified_upgrade_link': verified_upgrade_deadline_link(request.user, course=course),
|
||||
'is_learning_mfe': request.META.get('HTTP_REFERER', '').startswith(settings.LEARNING_MICROFRONTEND_URL),
|
||||
'is_mobile_app': is_request_from_mobile_app(request),
|
||||
'reset_deadlines_url': reverse(RESET_COURSE_DEADLINES_NAME),
|
||||
'reset_deadlines_redirect_url_base': COURSE_DATES_NAME,
|
||||
'reset_deadlines_redirect_url_id_dict': {'course_id': str(course.id)}
|
||||
}
|
||||
return render_to_response('courseware/courseware-chromeless.html', context)
|
||||
|
||||
|
||||
@@ -17,76 +17,89 @@ from course_modes.models import CourseMode
|
||||
</div>
|
||||
% endif
|
||||
<%
|
||||
has_locked_assignments = any(hasattr(block, 'contains_gated_content') and block.contains_gated_content for block in course_date_blocks if isinstance(block, CourseAssignmentDate)) if (course_date_blocks and on_dates_tab) else False
|
||||
on_dates_tab_as_audit = on_dates_tab and enrollment_mode == CourseMode.AUDIT
|
||||
on_dates_tab_as_verified = on_dates_tab and enrollment_mode == CourseMode.VERIFIED
|
||||
on_course_outline_page_as_audit = on_course_outline_page and enrollment_mode == CourseMode.AUDIT
|
||||
on_course_outline_page_as_verified = on_course_outline_page and enrollment_mode == CourseMode.VERIFIED
|
||||
on_courseware_page_as_audit = on_courseware_page and enrollment_mode == CourseMode.AUDIT
|
||||
on_courseware_page_as_verified = on_courseware_page and enrollment_mode == CourseMode.VERIFIED
|
||||
additional_styling_class = 'on-mobile' if web_app_course_url else 'has-button'
|
||||
additional_styling_class = 'on-mobile' if is_mobile_app else 'has-button'
|
||||
%>
|
||||
% if (missed_deadlines and (on_dates_tab_as_verified or on_courseware_page_as_audit or on_courseware_page_as_verified)) or (on_dates_tab_as_audit and has_locked_assignments) or on_course_outline_page_as_audit or on_course_outline_page_as_verified:
|
||||
|
||||
<%def name="reset_dates_banner()">
|
||||
<div class="dates-banner ${additional_styling_class}">
|
||||
<div class="dates-banner-text">
|
||||
% if web_app_course_url:
|
||||
% if enrollment_mode == CourseMode.VERIFIED:
|
||||
${_('It looks like you missed some important deadlines based on our suggested schedule. ')}
|
||||
${_('To keep yourself on track, you can update this schedule and shift the past due assignments into the future by visiting ')}
|
||||
<a class="mobile-dates-link" href="${web_app_course_url}">edx.org</a>.
|
||||
${_(' Don’t worry—you won’t lose any of the progress you’ve made when you shift your due dates.')}
|
||||
% else:
|
||||
<strong>${_('You are auditing this course,')}</strong>
|
||||
${_(' which means that you are unable to participate in graded assignments.')}
|
||||
${_(' It looks like you missed some important deadlines based on our suggested schedule. To complete graded assignments as part of this course and shift the past due assignments into the future, you can upgrade today by visiting ')}
|
||||
<a class="mobile-dates-link" href="${verified_upgrade_link}">edx.org</a>.
|
||||
% endif
|
||||
% if is_mobile_app:
|
||||
${_('It looks like you missed some important deadlines based on our suggested schedule. ')}
|
||||
${_('To keep yourself on track, you can update this schedule and shift the past due assignments into the future by visiting ')}
|
||||
<a class="mobile-dates-link" href="${web_app_course_url}">edx.org</a>.
|
||||
${_(' Don’t worry—you won’t lose any of the progress you’ve made when you shift your due dates.')}
|
||||
% else:
|
||||
% if on_course_outline_page_as_verified or (missed_deadlines and (on_dates_tab_as_verified or on_courseware_page_as_verified)):
|
||||
<strong>${_('It looks like you missed some important deadlines based on our suggested schedule.')}</strong>
|
||||
${_('To keep yourself on track, you can update this schedule and shift the past due assignments into the future. Don’t worry—you won’t lose any of the progress you’ve made when you shift your due dates.')}
|
||||
% endif
|
||||
% if (on_dates_tab_as_audit and has_locked_assignments) or on_course_outline_page_as_audit or (on_courseware_page_as_audit and missed_deadlines):
|
||||
<strong>${_('You are auditing this course,')}</strong>
|
||||
${_(' which means that you are unable to participate in graded assignments.')}
|
||||
% if on_dates_tab:
|
||||
% if missed_deadlines:
|
||||
${_(' It looks like you missed some important deadlines based on our suggested schedule. To complete graded assignments as part of this course and shift the past due assignments into the future, you can upgrade today.')}
|
||||
% else:
|
||||
${_(' To complete graded assignments as part of this course, you can upgrade today.')}
|
||||
% endif
|
||||
% else:
|
||||
${_(' It looks like you missed some important deadlines based on our suggested schedule. To complete graded assignments as part of this course and shift the past due assignments into the future, you can upgrade today.')}
|
||||
% endif
|
||||
% endif
|
||||
<strong>${_('It looks like you missed some important deadlines based on our suggested schedule.')}</strong>
|
||||
${_('To keep yourself on track, you can update this schedule and shift the past due assignments into the future. Don’t worry—you won’t lose any of the progress you’ve made when you shift your due dates.')}
|
||||
% endif
|
||||
</div>
|
||||
% if not web_app_course_url:
|
||||
% if not is_mobile_app:
|
||||
<div class="upgrade-button">
|
||||
% if on_course_outline_page_as_verified or (missed_deadlines and (on_dates_tab_as_verified or on_courseware_page_as_verified)):
|
||||
<form method="post" action="${reset_deadlines_url}">
|
||||
<input type="hidden" id="csrf_token" name="csrfmiddlewaretoken" value="${csrf_token}">
|
||||
<input type="hidden" name="reset_deadlines_redirect_url_base" value="${reset_deadlines_redirect_url_base}">
|
||||
<input type="hidden" name="reset_deadlines_redirect_url_id_dict" value="${reset_deadlines_redirect_url_id_dict}">
|
||||
<button class="btn reset-deadlines-button">${_("Reset my deadlines")}</button>
|
||||
</form>
|
||||
% endif:
|
||||
% if (on_dates_tab_as_audit and has_locked_assignments) or on_course_outline_page_as_audit or (on_courseware_page_as_audit and missed_deadlines):
|
||||
<a href="${verified_upgrade_link}">
|
||||
<button type="button">
|
||||
% if on_dates_tab:
|
||||
% if missed_deadlines:
|
||||
${_('Upgrade to shift due dates')}
|
||||
% else:
|
||||
${_('Upgrade now')}
|
||||
% endif
|
||||
% else:
|
||||
${_('Upgrade to shift due dates')}
|
||||
% endif
|
||||
</button>
|
||||
</a>
|
||||
% endif
|
||||
<form method="post" action="${reset_deadlines_url}">
|
||||
<input type="hidden" id="csrf_token" name="csrfmiddlewaretoken" value="${csrf_token}">
|
||||
<input type="hidden" name="reset_deadlines_redirect_url_base" value="${reset_deadlines_redirect_url_base}">
|
||||
<input type="hidden" name="reset_deadlines_redirect_url_id_dict" value="${reset_deadlines_redirect_url_id_dict}">
|
||||
<button class="btn reset-deadlines-button">${_("Reset my deadlines")}</button>
|
||||
</form>
|
||||
</div>
|
||||
% endif
|
||||
</div>
|
||||
</%def>
|
||||
<%def name="upgrade_to_reset_banner()">
|
||||
<div class="dates-banner ${additional_styling_class}">
|
||||
<div class="dates-banner-text">
|
||||
% if is_mobile_app:
|
||||
<strong>${_('You are auditing this course,')}</strong>
|
||||
${_(' which means that you are unable to participate in graded assignments.')}
|
||||
${_(' It looks like you missed some important deadlines based on our suggested schedule. Graded assignments and schedule adjustment are available to Verified Track learners.')}
|
||||
% else:
|
||||
<strong>${_('You are auditing this course,')}</strong>
|
||||
${_(' which means that you are unable to participate in graded assignments.')}
|
||||
${_(' It looks like you missed some important deadlines based on our suggested schedule. To complete graded assignments as part of this course and shift the past due assignments into the future, you can upgrade today.')}
|
||||
% endif
|
||||
</div>
|
||||
% if not is_mobile_app:
|
||||
<div class="upgrade-button">
|
||||
<a href="${verified_upgrade_link}">
|
||||
<button type="button">
|
||||
${_('Upgrade to shift due dates')}
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
% endif
|
||||
</div>
|
||||
</%def>
|
||||
<%def name="upgrade_to_complete_graded_banner()">
|
||||
<div class="dates-banner ${additional_styling_class}">
|
||||
<div class="dates-banner-text">
|
||||
% if is_mobile_app:
|
||||
<strong>${_('You are auditing this course,')}</strong>
|
||||
${_(' which means that you are unable to participate in graded assignments.')}
|
||||
${_('Graded assignments are available to Verified Track learners.')}
|
||||
% else:
|
||||
<strong>${_('You are auditing this course,')}</strong>
|
||||
${_(' which means that you are unable to participate in graded assignments.')}
|
||||
${_(' To complete graded assignments as part of this course, you can upgrade today.')}
|
||||
% endif
|
||||
</div>
|
||||
% if not is_mobile_app:
|
||||
<div class="upgrade-button">
|
||||
<a href="${verified_upgrade_link}">
|
||||
<button type="button">
|
||||
${_('Upgrade now')}
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
% endif
|
||||
</div>
|
||||
</%def>
|
||||
% if on_dates_tab and content_type_gating_enabled and not missed_deadlines:
|
||||
${upgrade_to_complete_graded_banner()}
|
||||
% elif missed_deadlines:
|
||||
% if content_type_gating_enabled:
|
||||
${upgrade_to_reset_banner()}
|
||||
% else:
|
||||
${reset_dates_banner()}
|
||||
% endif
|
||||
% endif
|
||||
|
||||
|
||||
@@ -96,7 +96,6 @@ class ContentTypeGatingConfig(StackedConfigurationModel):
|
||||
``enabled_as_of`` before the enrollment was created.
|
||||
|
||||
Arguments:
|
||||
enrollment: The enrollment being queried.
|
||||
user: The user being queried.
|
||||
course_key: The CourseKey of the course being queried.
|
||||
"""
|
||||
|
||||
@@ -27,7 +27,7 @@ dates_banner_displayed = False
|
||||
%>
|
||||
<main role="main" class="course-outline" id="main" tabindex="-1">
|
||||
<div class="dates-banner-wrapper">
|
||||
% if enrollment_mode and relative_dates_flag_is_enabled and self_paced and not is_course_staff:
|
||||
% if relative_dates_flag_is_enabled and self_paced and not is_course_staff:
|
||||
<%include file="/dates_banner.html" />
|
||||
% endif
|
||||
</div>
|
||||
|
||||
@@ -25,6 +25,7 @@ from waffle.models import Switch
|
||||
from waffle.testutils import override_switch
|
||||
|
||||
from course_modes.models import CourseMode
|
||||
from course_modes.tests.factories import CourseModeFactory
|
||||
from lms.djangoapps.courseware.tests.factories import StaffFactory
|
||||
from lms.urls import RESET_COURSE_DEADLINES_NAME
|
||||
from gating import api as lms_gating_api
|
||||
@@ -33,6 +34,7 @@ from openedx.core.djangoapps.schedules.models import Schedule
|
||||
from openedx.core.djangoapps.schedules.tests.factories import ScheduleFactory
|
||||
from openedx.core.lib.gating import api as gating_api
|
||||
from openedx.features.course_experience import RELATIVE_DATES_FLAG
|
||||
from openedx.features.content_type_gating.models import ContentTypeGatingConfig
|
||||
from openedx.features.course_experience.views.course_outline import (
|
||||
DEFAULT_COMPLETION_TRACKING_START,
|
||||
CourseOutlineFragmentView
|
||||
@@ -170,20 +172,29 @@ class TestCourseOutlinePage(SharedModuleStoreTestCase):
|
||||
|
||||
@RELATIVE_DATES_FLAG.override(active=True)
|
||||
@ddt.data(
|
||||
(CourseMode.AUDIT, False, True),
|
||||
(CourseMode.VERIFIED, False, True),
|
||||
(CourseMode.MASTERS, False, False),
|
||||
(CourseMode.VERIFIED, True, False),
|
||||
([CourseMode.AUDIT, CourseMode.VERIFIED], CourseMode.AUDIT, False, True),
|
||||
([CourseMode.AUDIT, CourseMode.VERIFIED], CourseMode.VERIFIED, False, True),
|
||||
([CourseMode.AUDIT, CourseMode.VERIFIED, CourseMode.MASTERS], CourseMode.MASTERS, False, True),
|
||||
([CourseMode.PROFESSIONAL], CourseMode.PROFESSIONAL, False, True),
|
||||
([CourseMode.AUDIT, CourseMode.VERIFIED], CourseMode.VERIFIED, True, False),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_reset_course_deadlines_banner_shows_for_self_paced_course(
|
||||
self,
|
||||
course_modes,
|
||||
enrollment_mode,
|
||||
is_course_staff,
|
||||
should_display
|
||||
):
|
||||
ContentTypeGatingConfig.objects.create(
|
||||
enabled=True,
|
||||
enabled_as_of=datetime.datetime(2018, 1, 1),
|
||||
)
|
||||
course = self.courses[0]
|
||||
enrollment = CourseEnrollment.objects.get(course_id=course.id)
|
||||
for mode in course_modes:
|
||||
CourseModeFactory.create(course_id=course.id, mode_slug=mode)
|
||||
|
||||
enrollment = CourseEnrollment.objects.get(course_id=course.id, user=self.user)
|
||||
enrollment.mode = enrollment_mode
|
||||
enrollment.save()
|
||||
self.user.is_staff = is_course_staff
|
||||
|
||||
@@ -262,36 +262,46 @@ def dates_banner_should_display(course_key, request):
|
||||
incomplete sequentials and which enrollment mode is being
|
||||
dealt with for the current user and course.
|
||||
"""
|
||||
missed_deadlines = False
|
||||
course_enrollment = None
|
||||
if RELATIVE_DATES_FLAG.is_enabled(str(course_key)):
|
||||
course_overview = CourseOverview.objects.get(id=str(course_key))
|
||||
course_end_date = getattr(course_overview, 'end_date', None)
|
||||
is_self_paced = getattr(course_overview, 'self_paced', False)
|
||||
is_course_staff = bool(
|
||||
request.user and course_overview and has_access(request.user, 'staff', course_overview, course_overview.id)
|
||||
)
|
||||
if is_self_paced and (not is_course_staff) and (not course_end_date or timezone.now() < course_end_date):
|
||||
course_enrollment = CourseEnrollment.objects.filter(
|
||||
course=course_overview, user=request.user,
|
||||
).filter(
|
||||
Q(mode=CourseMode.AUDIT) | Q(mode=CourseMode.VERIFIED)
|
||||
).first()
|
||||
if course_enrollment:
|
||||
store = modulestore()
|
||||
course_usage_key = store.make_course_usage_key(course_key)
|
||||
block_data = get_course_blocks(request.user, course_usage_key, include_completion=True)
|
||||
for section_key in block_data.get_children(course_usage_key):
|
||||
if missed_deadlines:
|
||||
break
|
||||
for subsection_key in block_data.get_children(section_key):
|
||||
subsection_due_date = block_data.get_xblock_field(subsection_key, 'due', None)
|
||||
if subsection_due_date and (
|
||||
not block_data.get_xblock_field(subsection_key, 'complete', False)
|
||||
and block_data.get_xblock_field(subsection_key, 'graded', False)
|
||||
and subsection_due_date < timezone.now()
|
||||
):
|
||||
missed_deadlines = True
|
||||
break
|
||||
if not RELATIVE_DATES_FLAG.is_enabled(str(course_key)):
|
||||
return False
|
||||
|
||||
return missed_deadlines, getattr(course_enrollment, 'mode', None)
|
||||
course_overview = CourseOverview.objects.get(id=str(course_key))
|
||||
course_end_date = getattr(course_overview, 'end_date', None)
|
||||
is_self_paced = getattr(course_overview, 'self_paced', False)
|
||||
|
||||
# Only display the banner for self-paced courses
|
||||
if not is_self_paced:
|
||||
return False
|
||||
|
||||
# Only display the banner for enrolled users
|
||||
if not CourseEnrollment.is_enrolled(request.user, course_key):
|
||||
return False
|
||||
|
||||
# Don't display the banner for course staff
|
||||
is_course_staff = bool(
|
||||
request.user and course_overview and has_access(request.user, 'staff', course_overview, course_overview.id)
|
||||
)
|
||||
if is_course_staff:
|
||||
return False
|
||||
|
||||
# Don't display the banner if the course has ended
|
||||
if course_end_date and course_end_date < timezone.now():
|
||||
return False
|
||||
|
||||
store = modulestore()
|
||||
course_usage_key = store.make_course_usage_key(course_key)
|
||||
block_data = get_course_blocks(request.user, course_usage_key, include_completion=True)
|
||||
for section_key in block_data.get_children(course_usage_key):
|
||||
for subsection_key in block_data.get_children(section_key):
|
||||
subsection_due_date = block_data.get_xblock_field(subsection_key, 'due', None)
|
||||
if subsection_due_date and (
|
||||
not block_data.get_xblock_field(subsection_key, 'complete', False)
|
||||
and block_data.get_xblock_field(subsection_key, 'graded', False)
|
||||
and subsection_due_date < timezone.now()
|
||||
):
|
||||
# Display the banner if the due date for an incomplete graded subsection
|
||||
# has passed
|
||||
return True
|
||||
|
||||
# Don't display the banner if there were no missed deadlines
|
||||
return False
|
||||
|
||||
@@ -31,6 +31,7 @@ from openedx.core.djangoapps.content.course_overviews.models import CourseOvervi
|
||||
from openedx.core.djangoapps.plugin_api.views import EdxFragmentView
|
||||
from openedx.core.djangoapps.schedules.utils import reset_self_paced_schedule
|
||||
from openedx.features.course_experience import RELATIVE_DATES_FLAG
|
||||
from openedx.features.content_type_gating.models import ContentTypeGatingConfig
|
||||
from student.models import CourseEnrollment
|
||||
from util.milestones_helpers import get_course_content_milestones
|
||||
from xmodule.course_module import COURSE_VISIBILITY_PUBLIC
|
||||
@@ -96,17 +97,18 @@ class CourseOutlineFragmentView(EdxFragmentView):
|
||||
reset_deadlines_url = reverse(RESET_COURSE_DEADLINES_NAME)
|
||||
reset_deadlines_redirect_url_base = COURSE_HOME_VIEW_NAME
|
||||
|
||||
course_enrollment = None
|
||||
if not request.user.is_anonymous:
|
||||
course_enrollment = CourseEnrollment.objects.filter(course=course_overview, user=request.user).filter(
|
||||
Q(mode=CourseMode.AUDIT) | Q(mode=CourseMode.VERIFIED)).first()
|
||||
|
||||
context['reset_deadlines_url'] = reset_deadlines_url
|
||||
context['reset_deadlines_redirect_url_base'] = reset_deadlines_redirect_url_base
|
||||
context['reset_deadlines_redirect_url_id_dict'] = {'course_id': str(course.id)}
|
||||
context['enrollment_mode'] = getattr(course_enrollment, 'mode', None)
|
||||
context['verified_upgrade_link'] = verified_upgrade_deadline_link(request.user, course=course),
|
||||
context['on_course_outline_page'] = True,
|
||||
context['verified_upgrade_link'] = verified_upgrade_deadline_link(request.user, course=course)
|
||||
context['on_course_outline_page'] = True
|
||||
context['content_type_gating_enabled'] = ContentTypeGatingConfig.enabled_for_enrollment(
|
||||
user=request.user,
|
||||
course_key=course_key
|
||||
)
|
||||
# We use javascript to check whether to actually display this banner, so we let the banner assume
|
||||
# that deadlines have been missed.
|
||||
context['missed_deadlines'] = True
|
||||
|
||||
html = render_to_string('course_experience/course-outline-fragment.html', context)
|
||||
return Fragment(html)
|
||||
|
||||
Reference in New Issue
Block a user