<%block name="course_about_important_dates">
- ${_("Course Number")}
${course.display_number_with_default}
+ -
+
+
${_("Course Number")}
+ ${course.display_number_with_default}
+
% if not course.start_date_is_still_default:
<%
course_start_date = course.advertised_start or course.start
@@ -231,7 +234,11 @@
% endif
% if get_course_about_section(request, course, "prerequisites"):
-
${_("Requirements")}
${get_course_about_section(request, course, "prerequisites")}
+ -
+
+
${_("Requirements")}
+ ${get_course_about_section(request, course, "prerequisites")}
+
% endif
%block>
diff --git a/openedx/features/survey_report/static/survey_report/js/admin_banner.js b/openedx/features/survey_report/static/survey_report/js/admin_banner.js
index d8650321ba36..8dd9ba5565e0 100644
--- a/openedx/features/survey_report/static/survey_report/js/admin_banner.js
+++ b/openedx/features/survey_report/static/survey_report/js/admin_banner.js
@@ -1,11 +1,51 @@
$(document).ready(function(){
+ // Function to get user ID
+ function getUserId() {
+ return $('#userIdSurvey').val();
+ }
+
+ // Function to get current time in milliseconds
+ function getCurrentTime() {
+ return new Date().getTime();
+ }
+
+ // Function to set dismissal time and expiration time in local storage
+ function setDismissalAndExpirationTime(userId, dismissalTime) {
+ let expirationTime = dismissalTime + (30 * 24 * 60 * 60 * 1000); // 30 days
+ localStorage.setItem('bannerDismissalTime_' + userId, dismissalTime);
+ localStorage.setItem('bannerExpirationTime_' + userId, expirationTime);
+ }
+
+ // Function to check if banner should be shown or hidden
+ function checkBannerVisibility() {
+ let userId = getUserId();
+ let bannerDismissalTime = localStorage.getItem('bannerDismissalTime_' + userId);
+ let bannerExpirationTime = localStorage.getItem('bannerExpirationTime_' + userId);
+ let currentTime = getCurrentTime();
+
+ if (bannerDismissalTime && bannerExpirationTime && currentTime > bannerExpirationTime) {
+ // Banner was dismissed and it's not within the expiration period, so show it
+ $('#originalContent').show();
+ } else if (bannerDismissalTime && bannerExpirationTime && currentTime < bannerExpirationTime) {
+ // Banner was dismissed and it's within the expiration period, so hide it
+ $('#originalContent').hide();
+ } else {
+ // Banner has not been dismissed ever so we need to show it.
+ $('#originalContent').show();
+ }
+ }
+
+ // Click event for dismiss button
$('#dismissButton').click(function() {
$('#originalContent').slideUp('slow', function() {
- // If you want to do something after the slide-up, do it here.
- // For example, you can hide the entire div:
- // $(this).hide();
+ let userId = getUserId();
+ let dismissalTime = getCurrentTime();
+ setDismissalAndExpirationTime(userId, dismissalTime);
});
});
+
+ // Check banner visibility on page load
+ checkBannerVisibility();
// When the form is submitted
$("#survey_report_form").submit(function(event){
event.preventDefault(); // Prevent the form from submitting traditionally
diff --git a/openedx/features/survey_report/templates/survey_report/admin_banner.html b/openedx/features/survey_report/templates/survey_report/admin_banner.html
index fa0b37ecf751..e13eb655f63c 100644
--- a/openedx/features/survey_report/templates/survey_report/admin_banner.html
+++ b/openedx/features/survey_report/templates/survey_report/admin_banner.html
@@ -1,7 +1,7 @@
{% block survey_report_banner %}
{% load static %}
{% if show_survey_report_banner %}
-
+
diff --git a/requirements/common_constraints.txt b/requirements/common_constraints.txt
index 4abc9ae22cb3..605871970bd8 100644
--- a/requirements/common_constraints.txt
+++ b/requirements/common_constraints.txt
@@ -21,15 +21,14 @@ Django<5.0
# elasticsearch>=7.14.0 includes breaking changes in it which caused issues in discovery upgrade process.
# elastic search changelog: https://www.elastic.co/guide/en/enterprise-search/master/release-notes-7.14.0.html
+# See https://github.com/openedx/edx-platform/issues/35126 for more info
elasticsearch<7.14.0
# django-simple-history>3.0.0 adds indexing and causes a lot of migrations to be affected
-# opentelemetry requires version 6.x at the moment:
-# https://github.com/open-telemetry/opentelemetry-python/issues/3570
-# Normally this could be added as a constraint in edx-django-utils, where we're
-# adding the opentelemetry dependency. However, when we compile pip-tools.txt,
-# that uses version 7.x, and then there's no undoing that when compiling base.txt.
-# So we need to pin it globally, for now.
-# Ticket for unpinning: https://github.com/openedx/edx-lint/issues/407
-importlib-metadata<7
+# Cause: https://github.com/openedx/event-tracking/pull/290
+# event-tracking 2.4.1 upgrades to pymongo 4.4.0 which is not supported on edx-platform.
+# We will pin event-tracking to do not break existing installations
+# This can be unpinned once https://github.com/openedx/edx-platform/issues/34586
+# has been resolved and edx-platform is running with pymongo>=4.4.0
+event-tracking<2.4.1
diff --git a/requirements/constraints.txt b/requirements/constraints.txt
index 8f7a66f9cc2f..866ac9e3bf7d 100644
--- a/requirements/constraints.txt
+++ b/requirements/constraints.txt
@@ -62,14 +62,6 @@ pycodestyle<2.9.0
pylint<2.16.0 # greater version failing quality test. Fix them in seperate ticket.
-# adding these constraints to minimize boto3 and botocore changeset
-social-auth-core==4.3.0
-
-# social-auth-app-django versions after 5.2.0 has a problematic migration that will cause issues deployments with large
-# `social_auth_usersocialauth` tables. 5.1.0 has missing migration and 5.2.0 has that problematic migration.
-social-auth-app-django==5.0.0
-
-
# urllib3>=2.0.0 conflicts with elastic search && snowflake-connector-python packages
# which require urllib3<2 for now.
# Issue for unpinning: https://github.com/openedx/edx-platform/issues/32222
diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt
index 2ae5ba235a89..4ca96ccfe951 100644
--- a/requirements/edx/base.txt
+++ b/requirements/edx/base.txt
@@ -177,7 +177,7 @@ defusedxml==0.7.1
# ora2
# python3-openid
# social-auth-core
-django==4.2.13
+django==4.2.16
# via
# -c requirements/edx/../common_constraints.txt
# -c requirements/edx/../constraints.txt
@@ -246,6 +246,7 @@ django==4.2.13
# openedx-filters
# openedx-learning
# ora2
+ # social-auth-app-django
# super-csv
# xblock-google-drive
# xss-utils
@@ -566,6 +567,7 @@ enmerkar-underscore==2.3.0
# via -r requirements/edx/kernel.in
event-tracking==2.4.0
# via
+ # -c requirements/edx/../common_constraints.txt
# -r requirements/edx/kernel.in
# edx-completion
# edx-proctoring
@@ -612,9 +614,7 @@ idna==3.7
# snowflake-connector-python
# yarl
importlib-metadata==6.11.0
- # via
- # -c requirements/edx/../common_constraints.txt
- # markdown
+ # via markdown
importlib-resources==5.13.0
# via
# jsonschema
@@ -1097,14 +1097,12 @@ slumber==0.7.1
# edx-rest-api-client
snowflake-connector-python==3.10.0
# via edx-enterprise
-social-auth-app-django==5.0.0
+social-auth-app-django==5.4.1
# via
- # -c requirements/edx/../constraints.txt
# -r requirements/edx/kernel.in
# edx-auth-backends
-social-auth-core==4.3.0
+social-auth-core==4.5.4
# via
- # -c requirements/edx/../constraints.txt
# -r requirements/edx/kernel.in
# edx-auth-backends
# social-auth-app-django
diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt
index 8b1bb858efe2..5d5bf7c27147 100644
--- a/requirements/edx/development.txt
+++ b/requirements/edx/development.txt
@@ -347,7 +347,7 @@ distlib==0.3.8
# via
# -r requirements/edx/testing.txt
# virtualenv
-django==4.2.13
+django==4.2.16
# via
# -c requirements/edx/../common_constraints.txt
# -c requirements/edx/../constraints.txt
@@ -420,6 +420,7 @@ django==4.2.13
# openedx-filters
# openedx-learning
# ora2
+ # social-auth-app-django
# super-csv
# xblock-google-drive
# xss-utils
@@ -894,6 +895,7 @@ enmerkar-underscore==2.3.0
# -r requirements/edx/testing.txt
event-tracking==2.4.0
# via
+ # -c requirements/edx/../common_constraints.txt
# -r requirements/edx/doc.txt
# -r requirements/edx/testing.txt
# edx-completion
@@ -1033,7 +1035,6 @@ import-linter==2.0
# via -r requirements/edx/testing.txt
importlib-metadata==6.11.0
# via
- # -c requirements/edx/../common_constraints.txt
# -r requirements/edx/../pip-tools.txt
# -r requirements/edx/doc.txt
# -r requirements/edx/testing.txt
@@ -1945,15 +1946,13 @@ snowflake-connector-python==3.10.0
# -r requirements/edx/doc.txt
# -r requirements/edx/testing.txt
# edx-enterprise
-social-auth-app-django==5.0.0
+social-auth-app-django==5.4.1
# via
- # -c requirements/edx/../constraints.txt
# -r requirements/edx/doc.txt
# -r requirements/edx/testing.txt
# edx-auth-backends
-social-auth-core==4.3.0
+social-auth-core==4.5.4
# via
- # -c requirements/edx/../constraints.txt
# -r requirements/edx/doc.txt
# -r requirements/edx/testing.txt
# edx-auth-backends
diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt
index 9e1dee112300..efe2fdc4dfc4 100644
--- a/requirements/edx/doc.txt
+++ b/requirements/edx/doc.txt
@@ -227,7 +227,7 @@ defusedxml==0.7.1
# ora2
# python3-openid
# social-auth-core
-django==4.2.13
+django==4.2.16
# via
# -c requirements/edx/../common_constraints.txt
# -c requirements/edx/../constraints.txt
@@ -296,6 +296,7 @@ django==4.2.13
# openedx-filters
# openedx-learning
# ora2
+ # social-auth-app-django
# super-csv
# xblock-google-drive
# xss-utils
@@ -650,6 +651,7 @@ enmerkar-underscore==2.3.0
# via -r requirements/edx/base.txt
event-tracking==2.4.0
# via
+ # -c requirements/edx/../common_constraints.txt
# -r requirements/edx/base.txt
# edx-completion
# edx-proctoring
@@ -710,7 +712,6 @@ imagesize==1.4.1
# via sphinx
importlib-metadata==6.11.0
# via
- # -c requirements/edx/../common_constraints.txt
# -r requirements/edx/base.txt
# markdown
# sphinx
@@ -1300,14 +1301,12 @@ snowflake-connector-python==3.10.0
# via
# -r requirements/edx/base.txt
# edx-enterprise
-social-auth-app-django==5.0.0
+social-auth-app-django==5.4.1
# via
- # -c requirements/edx/../constraints.txt
# -r requirements/edx/base.txt
# edx-auth-backends
-social-auth-core==4.3.0
+social-auth-core==4.5.4
# via
- # -c requirements/edx/../constraints.txt
# -r requirements/edx/base.txt
# edx-auth-backends
# social-auth-app-django
diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt
index 452fec9a8643..522f119908c3 100644
--- a/requirements/edx/testing.txt
+++ b/requirements/edx/testing.txt
@@ -263,7 +263,7 @@ dill==0.3.8
# via pylint
distlib==0.3.8
# via virtualenv
-django==4.2.13
+django==4.2.16
# via
# -c requirements/edx/../common_constraints.txt
# -c requirements/edx/../constraints.txt
@@ -332,6 +332,7 @@ django==4.2.13
# openedx-filters
# openedx-learning
# ora2
+ # social-auth-app-django
# super-csv
# xblock-google-drive
# xss-utils
@@ -687,6 +688,7 @@ enmerkar-underscore==2.3.0
# via -r requirements/edx/base.txt
event-tracking==2.4.0
# via
+ # -c requirements/edx/../common_constraints.txt
# -r requirements/edx/base.txt
# edx-completion
# edx-proctoring
@@ -780,7 +782,6 @@ import-linter==2.0
# via -r requirements/edx/testing.in
importlib-metadata==6.11.0
# via
- # -c requirements/edx/../common_constraints.txt
# -r requirements/edx/base.txt
# markdown
# pytest-randomly
@@ -1466,14 +1467,12 @@ snowflake-connector-python==3.10.0
# via
# -r requirements/edx/base.txt
# edx-enterprise
-social-auth-app-django==5.0.0
+social-auth-app-django==5.4.1
# via
- # -c requirements/edx/../constraints.txt
# -r requirements/edx/base.txt
# edx-auth-backends
-social-auth-core==4.3.0
+social-auth-core==4.5.4
# via
- # -c requirements/edx/../constraints.txt
# -r requirements/edx/base.txt
# edx-auth-backends
# social-auth-app-django
diff --git a/requirements/pip-tools.txt b/requirements/pip-tools.txt
index 4b631a73d780..d95112e36170 100644
--- a/requirements/pip-tools.txt
+++ b/requirements/pip-tools.txt
@@ -11,9 +11,7 @@ click==8.1.6
# -c requirements/constraints.txt
# pip-tools
importlib-metadata==6.11.0
- # via
- # -c requirements/common_constraints.txt
- # build
+ # via build
packaging==24.0
# via build
pip-tools==7.4.1
diff --git a/scripts/user_retirement/requirements/base.txt b/scripts/user_retirement/requirements/base.txt
index 934f4293d699..1966c7bb8b05 100644
--- a/scripts/user_retirement/requirements/base.txt
+++ b/scripts/user_retirement/requirements/base.txt
@@ -39,7 +39,7 @@ click==8.1.6
# edx-django-utils
cryptography==42.0.7
# via pyjwt
-django==4.2.13
+django==4.2.16
# via
# -c scripts/user_retirement/requirements/../../../requirements/common_constraints.txt
# -c scripts/user_retirement/requirements/../../../requirements/constraints.txt
diff --git a/scripts/user_retirement/requirements/testing.txt b/scripts/user_retirement/requirements/testing.txt
index 2bae9bb1a272..823b1d66887c 100644
--- a/scripts/user_retirement/requirements/testing.txt
+++ b/scripts/user_retirement/requirements/testing.txt
@@ -56,7 +56,7 @@ cryptography==42.0.7
# pyjwt
ddt==1.7.2
# via -r scripts/user_retirement/requirements/testing.in
-django==4.2.13
+django==4.2.16
# via
# -r scripts/user_retirement/requirements/base.txt
# django-crum
diff --git a/xmodule/capa_block.py b/xmodule/capa_block.py
index e7d917fee601..5779ed367fe8 100644
--- a/xmodule/capa_block.py
+++ b/xmodule/capa_block.py
@@ -795,12 +795,25 @@ def generate_report_data(self, user_state_iterator, limit_responses=None):
}
yield (user_state.username, report)
+ @property
+ def course_end_date(self):
+ """
+ Return the end date of the problem's course
+ """
+
+ try:
+ course_block_key = self.runtime.course_entry.structure['root']
+ return self.runtime.course_entry.structure['blocks'][course_block_key].fields['end']
+ except (AttributeError, KeyError):
+ return None
+
@property
def close_date(self):
"""
Return the date submissions should be closed from.
"""
- due_date = self.due
+
+ due_date = self.due or self.course_end_date
if self.graceperiod is not None and due_date:
return due_date + self.graceperiod
diff --git a/xmodule/tests/test_capa_block.py b/xmodule/tests/test_capa_block.py
index 42494547822e..5da29ac3d20e 100644
--- a/xmodule/tests/test_capa_block.py
+++ b/xmodule/tests/test_capa_block.py
@@ -11,7 +11,7 @@
import random
import textwrap
import unittest
-from unittest.mock import DEFAULT, Mock, patch
+from unittest.mock import DEFAULT, Mock, patch, PropertyMock
import pytest
import ddt
@@ -656,6 +656,37 @@ def test_closed(self):
due=self.yesterday_str)
assert block.closed()
+ @patch.object(ProblemBlock, 'course_end_date', new_callable=PropertyMock)
+ def test_closed_for_archive(self, mock_course_end_date):
+
+ # Utility to create a datetime object in the past
+ def past_datetime(days):
+ return (datetime.datetime.now(UTC) - datetime.timedelta(days=days))
+
+ # Utility to create a datetime object in the future
+ def future_datetime(days):
+ return (datetime.datetime.now(UTC) + datetime.timedelta(days=days))
+
+ block = CapaFactory.create(max_attempts="1", attempts="0")
+
+ # For active courses without graceperiod
+ mock_course_end_date.return_value = future_datetime(10)
+ assert not block.closed()
+
+ # For archive courses without graceperiod
+ mock_course_end_date.return_value = past_datetime(10)
+ assert block.closed()
+
+ # For active courses with graceperiod
+ mock_course_end_date.return_value = future_datetime(10)
+ block.graceperiod = datetime.timedelta(days=2)
+ assert not block.closed()
+
+ # For archive courses with graceperiod
+ mock_course_end_date.return_value = past_datetime(2)
+ block.graceperiod = datetime.timedelta(days=3)
+ assert not block.closed()
+
def test_parse_get_params(self):
# Valid GET param dict
${_("Course Number")}
${course.display_number_with_default}${_("Course Number")}
+ ${course.display_number_with_default} +% endif % if get_course_about_section(request, course, "prerequisites"): -
${_("Requirements")}
${get_course_about_section(request, course, "prerequisites")}${_("Requirements")}
+ ${get_course_about_section(request, course, "prerequisites")} +