From 0b04259856fbdf227aa42d265ec71b63c3e15ebd Mon Sep 17 00:00:00 2001 From: Tasawer Nawaz Date: Wed, 31 Jan 2018 15:28:28 +0500 Subject: [PATCH 001/308] translate string on support form LEARNER-3962 --- .../support/static/support/jsx/single_support_form.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lms/djangoapps/support/static/support/jsx/single_support_form.jsx b/lms/djangoapps/support/static/support/jsx/single_support_form.jsx index 2ca8aa3ea6..9691df6933 100644 --- a/lms/djangoapps/support/static/support/jsx/single_support_form.jsx +++ b/lms/djangoapps/support/static/support/jsx/single_support_form.jsx @@ -151,7 +151,7 @@ class RenderForm extends React.Component { {`Search the ${this.props.context.platformName} Help Center`} + >{gettext(`Search the ${this.props.context.platformName} Help Center`)} From 64040c2dee907580067f16564298da18fa803f9e Mon Sep 17 00:00:00 2001 From: Feanil Patel Date: Thu, 1 Mar 2018 13:40:40 -0500 Subject: [PATCH 002/308] Reduce requirements complexity. This reverts commit 0ca5cb9b74a612542831c0ff02ff7bbcaf844122. --- requirements/edx/base.txt | 2 ++ requirements/edx/pre.txt | 9 +-------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index b1013b3c2d..c089924af3 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -100,6 +100,7 @@ pyjwkest==1.3.2 # TODO Replace PyJWT usage with pyjwkest PyJWT==1.4.0 pymongo==2.9.1 +pyparsing==2.0.7 python-memcached==1.48 django-memcached-hashring==0.1.2 python-openid==2.2.5 @@ -113,6 +114,7 @@ PyYAML==3.12 requests-oauthlib==0.4.1 rules==1.1.1 s3transfer==0.1.12 +numpy==1.6.2 scipy==0.14.0 Shapely==1.2.16 singledispatch==3.4.0.2 diff --git a/requirements/edx/pre.txt b/requirements/edx/pre.txt index 265cd46ad0..552f6ef8e0 100644 --- a/requirements/edx/pre.txt +++ b/requirements/edx/pre.txt @@ -4,11 +4,4 @@ # * @edx/ospr - to check licensing # * @edx/devops - to check system requirements -# Packaging pre-requisites. -pyparsing==2.0.7 -setuptools==37.0.0 -pip==9.0.1 - -# Numpy and scipy can't be installed in the same pip run. -# Install numpy before other things to help resolve the problem. -numpy==1.6.2 +# Empty file left here until all the places that expect it have been updated. From 041059f740c841c1a3719c3cded027571fc1fca9 Mon Sep 17 00:00:00 2001 From: Feanil Patel Date: Thu, 1 Mar 2018 13:47:31 -0500 Subject: [PATCH 003/308] Update the other requirements to use pyparsing 2.2.0 as well. --- common/lib/calc/setup.py | 2 +- common/lib/chem/setup.py | 2 +- requirements/edx-sandbox/base.txt | 2 +- requirements/edx/base.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/lib/calc/setup.py b/common/lib/calc/setup.py index 9354bb7b83..d62dd9b6eb 100644 --- a/common/lib/calc/setup.py +++ b/common/lib/calc/setup.py @@ -5,7 +5,7 @@ setup( version="0.2", packages=["calc"], install_requires=[ - "pyparsing==2.0.7", + "pyparsing==2.2.0", "numpy==1.6.2", "scipy==0.14.0", ], diff --git a/common/lib/chem/setup.py b/common/lib/chem/setup.py index c421877153..9affb3d665 100644 --- a/common/lib/chem/setup.py +++ b/common/lib/chem/setup.py @@ -5,7 +5,7 @@ setup( version="0.1.2", packages=["chem"], install_requires=[ - "pyparsing==2.0.7", + "pyparsing==2.2.0", "numpy==1.6.2", "scipy==0.14.0", "nltk==3.2.5", diff --git a/requirements/edx-sandbox/base.txt b/requirements/edx-sandbox/base.txt index 75796afe1f..5852d1a74b 100644 --- a/requirements/edx-sandbox/base.txt +++ b/requirements/edx-sandbox/base.txt @@ -12,5 +12,5 @@ nltk==3.2.5 numpy==1.6.2 networkx==1.7 sympy==0.7.1 -pyparsing==2.0.7 +pyparsing==2.2.0 cryptography==1.9 diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index c089924af3..78a3b8f18b 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -100,7 +100,7 @@ pyjwkest==1.3.2 # TODO Replace PyJWT usage with pyjwkest PyJWT==1.4.0 pymongo==2.9.1 -pyparsing==2.0.7 +pyparsing==2.2.0 python-memcached==1.48 django-memcached-hashring==0.1.2 python-openid==2.2.5 From 0ffe133f6852ff4e9ade2ca2eb03a95dd3eeeed8 Mon Sep 17 00:00:00 2001 From: Giulio Gratta Date: Tue, 20 Mar 2018 14:13:31 -0700 Subject: [PATCH 004/308] Encodes staff profile names as they can be unicode --- lms/djangoapps/dashboard/sysadmin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lms/djangoapps/dashboard/sysadmin.py b/lms/djangoapps/dashboard/sysadmin.py index 2788b83029..82d872b8e4 100644 --- a/lms/djangoapps/dashboard/sysadmin.py +++ b/lms/djangoapps/dashboard/sysadmin.py @@ -559,7 +559,7 @@ class Staffing(SysadminDashboardView): for role in roles: for user in role(course.id).users_with_role(): datum = [course.id, role, user.username, user.email, - user.profile.name] + user.profile.name.encode('utf-8')] data.append(datum) header = [_('course_id'), _('role'), _('username'), From 0419347adc6718702f61e935c86b1d596bb30828 Mon Sep 17 00:00:00 2001 From: Peter Pinch Date: Wed, 31 Jan 2018 10:10:11 -0500 Subject: [PATCH 005/308] remove physical constants and suffixes fix / remove old tests --- common/lib/calc/calc/calc.py | 13 +--------- common/lib/calc/calc/tests/test_calc.py | 29 ++++++---------------- common/lib/calc/calc/tests/test_preview.py | 13 +--------- 3 files changed, 10 insertions(+), 45 deletions(-) diff --git a/common/lib/calc/calc/calc.py b/common/lib/calc/calc/calc.py index b55055dcd1..225edb4955 100644 --- a/common/lib/calc/calc/calc.py +++ b/common/lib/calc/calc/calc.py @@ -75,21 +75,10 @@ DEFAULT_VARIABLES = { 'j': numpy.complex(0, 1), 'e': numpy.e, 'pi': numpy.pi, - 'k': scipy.constants.k, # Boltzmann: 1.3806488e-23 (Joules/Kelvin) - 'c': scipy.constants.c, # Light Speed: 2.998e8 (m/s) - 'T': 298.15, # Typical room temperature: 298.15 (Kelvin), same as 25C/77F - 'q': scipy.constants.e # Fund. Charge: 1.602176565e-19 (Coulombs) } -# We eliminated the following extreme suffixes: -# P (1e15), E (1e18), Z (1e21), Y (1e24), -# f (1e-15), a (1e-18), z (1e-21), y (1e-24) -# since they're rarely used, and potentially confusing. -# They may also conflict with variables if we ever allow e.g. -# 5R instead of 5*R SUFFIXES = { - '%': 0.01, 'k': 1e3, 'M': 1e6, 'G': 1e9, 'T': 1e12, - 'c': 1e-2, 'm': 1e-3, 'u': 1e-6, 'n': 1e-9, 'p': 1e-12 + '%': 0.01, } diff --git a/common/lib/calc/calc/tests/test_calc.py b/common/lib/calc/calc/tests/test_calc.py index 77acca9f48..73f130049b 100644 --- a/common/lib/calc/calc/tests/test_calc.py +++ b/common/lib/calc/calc/tests/test_calc.py @@ -88,13 +88,10 @@ class EvaluatorTest(unittest.TestCase): """ Test calc.py's unique functionality of interpreting si 'suffixes'. - For instance 'k' stand for 'kilo-' so '1k' should be 1,000 + For instance '%' stand for 1/100th so '1%' should be 0.01 """ test_mapping = [ - ('4.2%', 0.042), ('2.25k', 2250), ('8.3M', 8300000), - ('9.9G', 9.9e9), ('1.2T', 1.2e12), ('7.4c', 0.074), - ('5.4m', 0.0054), ('8.7u', 0.0000087), - ('5.6n', 5.6e-9), ('4.2p', 4.2e-12) + ('4.2%', 0.042) ] for (expr, answer) in test_mapping: @@ -355,7 +352,7 @@ class EvaluatorTest(unittest.TestCase): """ Test the default constants provided in calc.py - which are: j (complex number), e, pi, k, c, T, q + which are: j (complex number), e, pi """ # Of the form ('expr', python value, tolerance (or None for exact)) @@ -364,10 +361,6 @@ class EvaluatorTest(unittest.TestCase): ('j', 1j, None), ('e', 2.7183, 1e-4), ('pi', 3.1416, 1e-4), - ('k', 1.3806488e-23, 1e-26), # Boltzmann constant (Joules/Kelvin) - ('c', 2.998e8, 1e5), # Light Speed in (m/s) - ('T', 298.15, 0.01), # Typical room temperature (Kelvin) - ('q', 1.602176565e-19, 1e-22) # Fund. Charge (Coulombs) ] for (variable, value, tolerance) in default_variables: fail_msg = "Failed on constant '{0}', not within bounds".format( @@ -405,10 +398,6 @@ class EvaluatorTest(unittest.TestCase): calc.evaluator({}, {}, "sin(e)"), 0.41, delta=0.01 ) - self.assertAlmostEqual( - calc.evaluator({}, {}, "k*T/q"), - 0.025, delta=1e-3 - ) self.assertAlmostEqual( calc.evaluator({}, {}, "e^(j*pi)"), -1, delta=1e-5 @@ -484,17 +473,15 @@ class EvaluatorTest(unittest.TestCase): 8.0 ) - variables = {'t': 1.0} - self.assertEqual(calc.evaluator(variables, {}, "t"), 1.0) - self.assertEqual(calc.evaluator(variables, {}, "T"), 1.0) + variables = {'E': 1.0} self.assertEqual( - calc.evaluator(variables, {}, "t", case_sensitive=True), + calc.evaluator(variables, {}, "E", case_sensitive=True), 1.0 ) - # Recall 'T' is a default constant, with value 298.15 + # Recall 'e' is a default constant, with value 2.718 self.assertAlmostEqual( - calc.evaluator(variables, {}, "T", case_sensitive=True), - 298, delta=0.2 + calc.evaluator(variables, {}, "e", case_sensitive=True), + 2.718, delta=0.02 ) def test_simple_funcs(self): diff --git a/common/lib/calc/calc/tests/test_preview.py b/common/lib/calc/calc/tests/test_preview.py index 7db307a742..36d9acbd81 100644 --- a/common/lib/calc/calc/tests/test_preview.py +++ b/common/lib/calc/calc/tests/test_preview.py @@ -84,7 +84,7 @@ class LatexPreviewTest(unittest.TestCase): def test_number_suffix(self): """ Suffixes should be escaped. """ - self.assertEquals(preview.latex_preview('1.618k'), r'1.618\text{k}') + self.assertEquals(preview.latex_preview('1.618%'), r'1.618\text{%}') def test_number_sci_notation(self): """ Numbers with scientific notation should display nicely """ @@ -97,17 +97,6 @@ class LatexPreviewTest(unittest.TestCase): r'-6.0221413\!\times\!10^{+23}' ) - def test_number_sci_notation_suffix(self): - """ Test numbers with both of these. """ - self.assertEquals( - preview.latex_preview('6.0221413E+23k'), - r'6.0221413\!\times\!10^{+23}\text{k}' - ) - self.assertEquals( - preview.latex_preview('-6.0221413E+23k'), - r'-6.0221413\!\times\!10^{+23}\text{k}' - ) - def test_variable_simple(self): """ Simple valid variables should pass through. """ self.assertEquals(preview.latex_preview('x', variables=['x']), 'x') From 8a579d92362c15874ab6e4480b4ad157d56c8f4b Mon Sep 17 00:00:00 2001 From: Jillian Vogel Date: Thu, 22 Mar 2018 17:02:13 +1030 Subject: [PATCH 006/308] Set SWIFT_CONTENT_LENGTH_FROM_FD=False Works around a bug with Django SWIFT storage uploads in edx-platform, cf https://github.com/dennisv/django-storage-swift/pull/100 Also adds SWIFT_LAZY_CONNECT to cms.envs.openstack, to balance with the lms settings. --- cms/envs/openstack.py | 2 ++ lms/envs/openstack.py | 1 + requirements/edx/openstack.txt | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cms/envs/openstack.py b/cms/envs/openstack.py index 53a2e91c5e..a69dd166c5 100644 --- a/cms/envs/openstack.py +++ b/cms/envs/openstack.py @@ -17,6 +17,8 @@ SWIFT_NAME_PREFIX = FILE_UPLOAD_STORAGE_PREFIX SWIFT_USE_TEMP_URLS = AUTH_TOKENS.get('SWIFT_USE_TEMP_URLS', False) SWIFT_TEMP_URL_KEY = AUTH_TOKENS.get('SWIFT_TEMP_URL_KEY') SWIFT_TEMP_URL_DURATION = AUTH_TOKENS.get('SWIFT_TEMP_URL_DURATION', 1800) # seconds +SWIFT_CONTENT_LENGTH_FROM_FD = AUTH_TOKENS.get('SWIFT_CONTENT_LENGTH_FROM_FD', False) +SWIFT_LAZY_CONNECT = AUTH_TOKENS.get('SWIFT_LAZY_CONNECT', True) if AUTH_TOKENS.get('SWIFT_REGION_NAME'): SWIFT_EXTRA_OPTIONS = {'region_name': AUTH_TOKENS['SWIFT_REGION_NAME']} diff --git a/lms/envs/openstack.py b/lms/envs/openstack.py index 10b5f1472c..bf420c5053 100644 --- a/lms/envs/openstack.py +++ b/lms/envs/openstack.py @@ -18,6 +18,7 @@ SWIFT_USE_TEMP_URLS = AUTH_TOKENS.get('SWIFT_USE_TEMP_URLS', False) SWIFT_TEMP_URL_KEY = AUTH_TOKENS.get('SWIFT_TEMP_URL_KEY') SWIFT_TEMP_URL_DURATION = AUTH_TOKENS.get('SWIFT_TEMP_URL_DURATION', 1800) # seconds SWIFT_CONTENT_TYPE_FROM_FD = AUTH_TOKENS.get('SWIFT_CONTENT_TYPE_FROM_FD', True) +SWIFT_CONTENT_LENGTH_FROM_FD = AUTH_TOKENS.get('SWIFT_CONTENT_LENGTH_FROM_FD', False) SWIFT_LAZY_CONNECT = AUTH_TOKENS.get('SWIFT_LAZY_CONNECT', True) if AUTH_TOKENS.get('SWIFT_REGION_NAME'): diff --git a/requirements/edx/openstack.txt b/requirements/edx/openstack.txt index 2b3d1c1dbb..1d576b1082 100644 --- a/requirements/edx/openstack.txt +++ b/requirements/edx/openstack.txt @@ -3,4 +3,4 @@ # # OpenStack swift backend for django storage API -django-storage-swift==1.2.18 +django-storage-swift==1.2.19 From b44114d1717d98c312ab45d15e3d56234b4c10d6 Mon Sep 17 00:00:00 2001 From: Jillian Vogel Date: Wed, 21 Mar 2018 14:12:31 +1030 Subject: [PATCH 007/308] Shows the account activation message in the sidebar and removes the DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR flag, since this feature is now always on. Marks the top banner as deprecated. --- .../student/tests/test_activate_account.py | 28 ------------------- common/djangoapps/student/views/dashboard.py | 17 ++--------- lms/envs/common.py | 3 -- .../registration/activate_account_notice.html | 28 ------------------- 4 files changed, 2 insertions(+), 74 deletions(-) delete mode 100644 lms/templates/registration/activate_account_notice.html diff --git a/common/djangoapps/student/tests/test_activate_account.py b/common/djangoapps/student/tests/test_activate_account.py index 30cd2e1a7a..62430bf432 100644 --- a/common/djangoapps/student/tests/test_activate_account.py +++ b/common/djangoapps/student/tests/test_activate_account.py @@ -112,7 +112,6 @@ class TestActivateAccount(TestCase): def test_activation_without_keys(self, mock_segment_identify): self.assert_no_tracking(mock_segment_identify) - @override_settings(FEATURES=dict(settings.FEATURES, DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR=True)) def test_account_activation_message(self): """ Verify that account correct activation message is displayed. @@ -149,33 +148,6 @@ class TestActivateAccount(TestCase): response = self.client.get(reverse('dashboard')) self.assertNotContains(response, expected_message, html=True) - @override_settings(FEATURES=dict(settings.FEATURES, DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR=False)) - def test_account_activation_message_disabled(self): - """ - Verify that old account activation message is displayed when - DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR is disabled. - """ - # Log in with test user. - self.login() - expected_message = render_to_string( - 'registration/activate_account_notice.html', - {'email': self.user.email} - ) - - response = self.client.get(reverse('dashboard')) - self.assertContains(response, expected_message, html=True) - - # Now make sure account activation message goes away when user activated the account - self.user.is_active = True - self.user.save() - self.login() - expected_message = render_to_string( - 'registration/activate_account_notice.html', - {'email': self.user.email} - ) - response = self.client.get(reverse('dashboard')) - self.assertNotContains(response, expected_message, html=True) - def test_account_activation_notification_on_logistration(self): """ Verify that logistration page displays success/error/info messages diff --git a/common/djangoapps/student/views/dashboard.py b/common/djangoapps/student/views/dashboard.py index 4b81553c6f..f9d44c84b3 100644 --- a/common/djangoapps/student/views/dashboard.py +++ b/common/djangoapps/student/views/dashboard.py @@ -599,16 +599,9 @@ def student_dashboard(request): ) course_optouts = Optout.objects.filter(user=user).values_list('course_id', flat=True) + # Display activation message in sidebar sidebar_account_activation_message = '' - banner_account_activation_message = '' - display_account_activation_message_on_sidebar = configuration_helpers.get_value( - 'DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR', - settings.FEATURES.get('DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR', False) - ) - - # Display activation message in sidebar if DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR - # flag is active. Otherwise display existing message at the top. - if display_account_activation_message_on_sidebar and not user.is_active: + if not user.is_active: sidebar_account_activation_message = render_to_string( 'registration/account_activation_sidebar_notice.html', { @@ -617,11 +610,6 @@ def student_dashboard(request): 'activation_email_support_link': activation_email_support_link } ) - elif not user.is_active: - banner_account_activation_message = render_to_string( - 'registration/activate_account_notice.html', - {'email': user.email} - ) enterprise_message = get_dashboard_consent_notification(request, user, course_enrollments) @@ -789,7 +777,6 @@ def student_dashboard(request): 'course_entitlement_available_sessions': course_entitlement_available_sessions, 'unfulfilled_entitlement_pseudo_sessions': unfulfilled_entitlement_pseudo_sessions, 'course_optouts': course_optouts, - 'banner_account_activation_message': banner_account_activation_message, 'sidebar_account_activation_message': sidebar_account_activation_message, 'staff_access': staff_access, 'errored_courses': errored_courses, diff --git a/lms/envs/common.py b/lms/envs/common.py index 4cf56e2341..b45fbc4dca 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -376,9 +376,6 @@ FEATURES = { # See LEARNER-493 'ENABLE_ONE_CLICK_PROGRAM_PURCHASE': False, - # Whether to display account activation notification on dashboard. - 'DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR': False, - # Allow users to change their email address. 'ALLOW_EMAIL_ADDRESS_CHANGE': True, diff --git a/lms/templates/registration/activate_account_notice.html b/lms/templates/registration/activate_account_notice.html deleted file mode 100644 index 80b809943e..0000000000 --- a/lms/templates/registration/activate_account_notice.html +++ /dev/null @@ -1,28 +0,0 @@ -<%page expression_filter="h"/> -<%! -from django.utils.translation import ugettext as _ -from openedx.core.djangolib.markup import HTML, Text -%> -
-
-
-

${_("You're almost there!")}

-
-

${Text(_( - "There's just one more step: Before you " - "enroll in a course, you need to activate " - "your account. We've sent an email message to " - "{email_start}{email}{email_end} with " - "instructions for activating your account. If " - "you don't receive this message, check your " - "spam folder." - )).format( - email_start=HTML(""), - email_end=HTML(""), - email=email, - )} -

-
-
-
-
\ No newline at end of file From 22ee400b158cb1b45caa47e9d3275e42aab66686 Mon Sep 17 00:00:00 2001 From: Jillian Vogel Date: Wed, 21 Mar 2018 14:27:50 +1030 Subject: [PATCH 008/308] Adds HIDE_DASHBOARD_COURSES_UNTIL_ACTIVATED Site Configuration and feature flag When set, it hides the Courses list on the Learner Dashboard page if the learner has not yet activated their account. --- common/djangoapps/student/tests/test_views.py | 22 +++++++++++++++++++ common/djangoapps/student/views/dashboard.py | 5 +++++ lms/envs/common.py | 3 +++ lms/templates/dashboard.html | 3 ++- 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/common/djangoapps/student/tests/test_views.py b/common/djangoapps/student/tests/test_views.py index ed841fd031..186abf0a16 100644 --- a/common/djangoapps/student/tests/test_views.py +++ b/common/djangoapps/student/tests/test_views.py @@ -264,6 +264,11 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin, 'DASHBOARD_TWITTER': True, }, } + MOCK_SETTINGS_HIDE_COURSES = { + 'FEATURES': { + 'HIDE_DASHBOARD_COURSES_UNTIL_ACTIVATED': True, + } + } def setUp(self): """ @@ -611,6 +616,23 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin, response = self.client.get(self.path) self.assertEqual(pq(response.content)(self.EMAIL_SETTINGS_ELEMENT_ID).length, 0) + @patch.multiple('django.conf.settings', **MOCK_SETTINGS_HIDE_COURSES) + def test_hide_dashboard_courses_until_activated(self): + """ + Verify that when the HIDE_DASHBOARD_COURSES_UNTIL_ACTIVATED feature is enabled, + inactive users don't see the Courses list, but active users still do. + """ + # Ensure active users see the course list + self.assertTrue(self.user.is_active) + response = self.client.get(reverse('dashboard')) + self.assertIn('You are not enrolled in any courses yet.', response.content) + + # Ensure inactive users don't see the course list + self.user.is_active = False + self.user.save() + response = self.client.get(reverse('dashboard')) + self.assertNotIn('You are not enrolled in any courses yet.', response.content) + @staticmethod def _remove_whitespace_from_html_string(html): return ''.join(html.split()) diff --git a/common/djangoapps/student/views/dashboard.py b/common/djangoapps/student/views/dashboard.py index f9d44c84b3..fcd144159f 100644 --- a/common/djangoapps/student/views/dashboard.py +++ b/common/djangoapps/student/views/dashboard.py @@ -559,6 +559,10 @@ def student_dashboard(request): activation_email_support_link = configuration_helpers.get_value( 'ACTIVATION_EMAIL_SUPPORT_LINK', settings.ACTIVATION_EMAIL_SUPPORT_LINK ) or settings.SUPPORT_SITE_LINK + hide_dashboard_courses_until_activated = configuration_helpers.get_value( + 'HIDE_DASHBOARD_COURSES_UNTIL_ACTIVATED', + settings.FEATURES.get('HIDE_DASHBOARD_COURSES_UNTIL_ACTIVATED', False) + ) # Get the org whitelist or the org blacklist for the current site site_org_whitelist, site_org_blacklist = get_org_black_and_whitelist_for_site() @@ -806,6 +810,7 @@ def student_dashboard(request): 'disable_courseware_js': True, 'display_course_modes_on_dashboard': enable_verified_certificates and display_course_modes_on_dashboard, 'display_sidebar_on_dashboard': display_sidebar_on_dashboard, + 'display_dashboard_courses': (user.is_active or not hide_dashboard_courses_until_activated), } if ecommerce_service.is_enabled(request.user): diff --git a/lms/envs/common.py b/lms/envs/common.py index b45fbc4dca..a67f57d174 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -137,6 +137,9 @@ FEATURES = { # Can be turned off if course lists need to be hidden. Effects views and templates. 'COURSES_ARE_BROWSABLE': True, + # Set to hide the courses list on the Learner Dashboard if they are not enrolled in any courses yet. + 'HIDE_DASHBOARD_COURSES_UNTIL_ACTIVATED': False, + # Enables ability to restrict enrollment in specific courses by the user account login method 'RESTRICT_ENROLL_BY_REG_METHOD': False, diff --git a/lms/templates/dashboard.html b/lms/templates/dashboard.html index 8a330f3ec7..2c9c4ca994 100644 --- a/lms/templates/dashboard.html +++ b/lms/templates/dashboard.html @@ -120,7 +120,7 @@ from student.models import CourseEnrollment
- + % if display_dashboard_courses:
<%include file="learner_dashboard/_dashboard_navigation_courses.html"/> @@ -222,6 +222,7 @@ from student.models import CourseEnrollment % endif
+ % endif
%if sidebar_account_activation_message: