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(palm): warn when relative dates are past due and can't be shifted #663

Merged
merged 2 commits into from
Jun 10, 2024
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
16 changes: 9 additions & 7 deletions lms/templates/problem.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,21 +68,23 @@ <h3 class="hd hd-3 problem-header" id="${ short_id }-problem-title" aria-describ
</span>
<span class="sr">(${submit_disabled_cta['description']})</span>
% else:
<form class="submit-cta" method="post" action="${submit_disabled_cta['link']}">
<form class="submit-cta" method="post" action="${submit_disabled_cta.get('link')}">
% if submit_disabled_cta.get('link'):
<input type="hidden" id="csrf_token" name="csrfmiddlewaretoken" value="${csrf_token}">
% for form_name, form_value in submit_disabled_cta['form_values'].items():
<input type="hidden" name="${form_name}" value="${form_value}">
% endfor
<button class="submit-cta-link-button btn-link btn-small">
${submit_disabled_cta['link_name']}
</button>
<span class="submit-cta-description" tabindex="0" role="note" aria-label="description">
<span data-tooltip="${submit_disabled_cta['description']}" data-tooltip-show-on-click="true"
class="fa fa-info-circle fa-lg" aria-hidden="true">
</span>
% endif
<span class="submit-cta-description" tabindex="0" role="note" aria-label="description">
<span data-tooltip="${submit_disabled_cta['description']}" data-tooltip-show-on-click="true"
class="fa fa-info-circle fa-lg" aria-hidden="true">
</span>
<span class="sr">(${submit_disabled_cta['description']})</span>
</form>
</span>
<span class="sr">(${submit_disabled_cta['description']})</span>
</form>
% endif
% endif
<div class="submission-feedback ${'cta-enabled' if submit_disabled_cta else ''}" id="submission_feedback_${short_id}">
Expand Down
2 changes: 1 addition & 1 deletion lms/templates/vert_module.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ <h2 class="hd hd-2 unit-title">${unit_title}</h2>
<div class="banner-cta-button">
<button class="btn btn-outline-primary" onclick="emit_event(${vertical_banner_cta['event_data']})">${vertical_banner_cta['link_name']}</button>
</div>
% else:
% elif vertical_banner_cta.get('link'):
<div class="banner-cta-button">
<form method="post" action="${vertical_banner_cta['link']}">
<input type="hidden" id="csrf_token" name="csrfmiddlewaretoken" value="${csrf_token}">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from lms.djangoapps.courseware.tests.helpers import MasqueradeMixin
from openedx.core.djangoapps.schedules.models import Schedule
from openedx.features.course_experience import RELATIVE_DATES_DISABLE_RESET_FLAG, RELATIVE_DATES_FLAG
from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.factories import CourseFactory


@ddt.ddt
Expand Down
10 changes: 8 additions & 2 deletions openedx/features/course_experience/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,19 @@ def get_start_block(block):
return get_start_block(first_child)


def dates_banner_should_display(course_key, user):
def dates_banner_should_display(course_key, user, allow_warning=False):
"""
Return whether or not the reset banner should display,
determined by whether or not a course has any past-due,
incomplete sequentials and which enrollment mode is being
dealt with for the current user and course.

Args:
course_key (CourseKey)
user (User)
allow_warning (bool): whether to ignore relative_dates_disable_reset_flag, in order to render
warnings for past-due incomplete units.

Returns:
(missed_deadlines, missed_gated_content):
missed_deadlines is True if the user has missed any graded content deadlines
Expand All @@ -155,7 +161,7 @@ def dates_banner_should_display(course_key, user):
if not RELATIVE_DATES_FLAG.is_enabled(course_key):
return False, False

if RELATIVE_DATES_DISABLE_RESET_FLAG.is_enabled(course_key):
if RELATIVE_DATES_DISABLE_RESET_FLAG.is_enabled(course_key) and not allow_warning:
# The `missed_deadlines` value is ignored by `reset_course_deadlines` views. Instead, they check the value of
# `missed_gated_content` to determine if learners can reset the deadlines by themselves.
# We could have added this logic directly to `reset_self_paced_schedule`, but this function is used in other
Expand Down
16 changes: 12 additions & 4 deletions openedx/features/personalized_learner_schedules/call_to_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from xmodule.util.misc import is_xblock_an_assignment
from openedx.core.djangolib.markup import HTML, Text
from openedx.core.lib.mobile_utils import is_request_from_mobile_app
from openedx.features.course_experience import RELATIVE_DATES_DISABLE_RESET_FLAG
from openedx.features.course_experience.url_helpers import is_request_from_learning_mfe
from openedx.features.course_experience.utils import dates_banner_should_display

Expand All @@ -37,7 +38,10 @@ def get_ctas(self, xblock, category, completed):
request = get_current_request()

course_key = xblock.scope_ids.usage_id.context_key
missed_deadlines, missed_gated_content = dates_banner_should_display(course_key, request.user)
missed_deadlines, missed_gated_content = dates_banner_should_display(
course_key, request.user, allow_warning=True
)

# Not showing in the missed_gated_content case because those learners are not eligible
# to shift due dates.
if missed_gated_content:
Expand All @@ -52,13 +56,13 @@ def get_ctas(self, xblock, category, completed):
# xblock is a capa problem, and the submit button is disabled. Check if it's because of a personalized
# schedule due date being missed, and if so, we can offer to shift it.
if self._is_block_shiftable(xblock, category):
ctas.append(self._make_reset_deadlines_cta(xblock, category, is_learning_mfe))
ctas.append(self._make_deadlines_cta(course_key, xblock, category, is_learning_mfe))

elif category == self.VERTICAL_BANNER and not completed and missed_deadlines:
# xblock is a vertical, so we'll check all the problems inside it. If there are any that will show a
# a "shift dates" CTA under CAPA_SUBMIT_DISABLED, then we'll also show the same CTA as a vertical banner.
if any(self._is_block_shiftable(item, category) for item in xblock.get_children()):
ctas.append(self._make_reset_deadlines_cta(xblock, category, is_learning_mfe))
ctas.append(self._make_deadlines_cta(course_key, xblock, category, is_learning_mfe))

return ctas

Expand Down Expand Up @@ -107,11 +111,15 @@ def _log_past_due_warning(name):
PersonalizedLearnerScheduleCallToAction.past_due_class_warnings.add(name)

@classmethod
def _make_reset_deadlines_cta(cls, xblock, category, is_learning_mfe=False):
def _make_deadlines_cta(cls, course_key, xblock, category, is_learning_mfe=False):
"""
Constructs a call to action object containing the necessary information for the view
"""
from lms.urls import RESET_COURSE_DEADLINES_NAME

if RELATIVE_DATES_DISABLE_RESET_FLAG.is_enabled(course_key):
return {"description": _("The deadline to complete this assignment has passed.")}

course_key = xblock.scope_ids.usage_id.context_key

cta_data = {
Expand Down
Loading