From 4c0fba2063f353339bec9385fbc8e520c5bb259c Mon Sep 17 00:00:00 2001 From: Bryann Valderrama <64033729+BryanttV@users.noreply.github.com> Date: Thu, 15 Feb 2024 09:44:28 -0500 Subject: [PATCH 1/4] feat: expose `hide_from_toc` field for course blocks in outline API (#33955) These changes are part of the effort made to implement https://openedx.atlassian.net/wiki/spaces/OEPM/pages/3853975595/Feature+Enhancement+Proposal+Hide+Sections+from+course+outline --- lms/djangoapps/course_api/blocks/serializers.py | 1 + lms/djangoapps/course_home_api/outline/serializers.py | 1 + .../course_home_api/outline/tests/test_view.py | 10 ++++++++++ openedx/features/course_experience/utils.py | 1 + 4 files changed, 13 insertions(+) diff --git a/lms/djangoapps/course_api/blocks/serializers.py b/lms/djangoapps/course_api/blocks/serializers.py index ac031600a02c..666724e357af 100644 --- a/lms/djangoapps/course_api/blocks/serializers.py +++ b/lms/djangoapps/course_api/blocks/serializers.py @@ -57,6 +57,7 @@ def __init__( SupportedFieldType('has_scheduled_content'), SupportedFieldType('weight'), SupportedFieldType('show_correctness'), + SupportedFieldType('hide_from_toc'), # 'student_view_data' SupportedFieldType(StudentViewTransformer.STUDENT_VIEW_DATA, StudentViewTransformer), # 'student_view_multi_device' diff --git a/lms/djangoapps/course_home_api/outline/serializers.py b/lms/djangoapps/course_home_api/outline/serializers.py index 29b46d30e967..db6cbdf3a1ab 100644 --- a/lms/djangoapps/course_home_api/outline/serializers.py +++ b/lms/djangoapps/course_home_api/outline/serializers.py @@ -54,6 +54,7 @@ def get_blocks(self, block): # pylint: disable=missing-function-docstring 'resume_block': block.get('resume_block', False), 'type': block_type, 'has_scheduled_content': block.get('has_scheduled_content'), + 'hide_from_toc': block.get('hide_from_toc'), }, } for child in children: diff --git a/lms/djangoapps/course_home_api/outline/tests/test_view.py b/lms/djangoapps/course_home_api/outline/tests/test_view.py index f02ad646ef48..eebaf19cf65b 100644 --- a/lms/djangoapps/course_home_api/outline/tests/test_view.py +++ b/lms/djangoapps/course_home_api/outline/tests/test_view.py @@ -404,6 +404,16 @@ def test_user_has_passing_grade(self): assert response.status_code == 200 assert response.data['user_has_passing_grade'] is True + def test_hide_from_toc_field(self): + """ + Test that the hide_from_toc field is returned in the response. + """ + CourseEnrollment.enroll(self.user, self.course.id) + response = self.client.get(self.url) + assert response.status_code == 200 + for block in response.data["course_blocks"]["blocks"].values(): + assert "hide_from_toc" in block + def assert_can_enroll(self, can_enroll): response = self.client.get(self.url) assert response.status_code == 200 diff --git a/openedx/features/course_experience/utils.py b/openedx/features/course_experience/utils.py index d58b54f6139f..4675d0a974e0 100644 --- a/openedx/features/course_experience/utils.py +++ b/openedx/features/course_experience/utils.py @@ -115,6 +115,7 @@ def recurse_mark_auth_denial(block): 'completion', 'complete', 'resume_block', + 'hide_from_toc', ], allow_start_dates_in_future=allow_start_dates_in_future, ) From d59dbbdfa50b4696800182f1ed8f5e9cf189ad95 Mon Sep 17 00:00:00 2001 From: Alejandro Cardenas Date: Thu, 15 Feb 2024 10:37:23 -0500 Subject: [PATCH 2/4] feat: add dismiss button to survey report banner (#34160) * feat: add dismiss button to survey report banner * refactor: move banner script to js file * fix: remove not in conditional --- lms/templates/admin/base_site.html | 6 ++- .../static/survey_report/js/admin_banner.js | 37 +++++++++++++++++++ .../templates/survey_report/admin_banner.html | 17 ++++++++- 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 openedx/features/survey_report/static/survey_report/js/admin_banner.js diff --git a/lms/templates/admin/base_site.html b/lms/templates/admin/base_site.html index 2dfd0bef7a50..cd8ab70e4f4b 100644 --- a/lms/templates/admin/base_site.html +++ b/lms/templates/admin/base_site.html @@ -1,5 +1,5 @@ {% extends "admin/base.html" %} -{% load i18n admin_urls %} +{% load i18n admin_urls static %} {% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %} {% block branding %}

{{ site_header|default:_('Django administration') }}

@@ -21,6 +21,10 @@

{{ site_header|default:_('D {% endblock %} +{% block extrahead %} + +{% endblock %} + {% block messages %}{{ block.super }} {% include "survey_report/admin_banner.html" %} {% endblock %} 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 new file mode 100644 index 000000000000..d8650321ba36 --- /dev/null +++ b/openedx/features/survey_report/static/survey_report/js/admin_banner.js @@ -0,0 +1,37 @@ +$(document).ready(function(){ + $('#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(); + }); + }); + // When the form is submitted + $("#survey_report_form").submit(function(event){ + event.preventDefault(); // Prevent the form from submitting traditionally + + // Make the AJAX request + $.ajax({ + url: $(this).attr("action"), + type: $(this).attr("method"), + data: $(this).serialize(), + success: function(response){ + // Hide the original content block + $("#originalContent").slideUp(400, function() { + //$(this).css('display', 'none'); + // Show the thank-you message block with slide down effect + $("#thankYouMessage").slideDown(400, function() { + // Wait for 3 seconds (3000 milliseconds) and then slide up the thank-you message + setTimeout(function() { + $("#thankYouMessage").slideUp(400); + }, 3000); + }); + }); + }, + error: function(error){ + // Handle any errors + console.error("Error sending report:", error); + } + }); + }); +}); 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 0e8034380e35..fa0b37ecf751 100644 --- a/openedx/features/survey_report/templates/survey_report/admin_banner.html +++ b/openedx/features/survey_report/templates/survey_report/admin_banner.html @@ -1,4 +1,5 @@ {% block survey_report_banner %} +{% load static %} {% if show_survey_report_banner %} + {% endif %} + + + {% endblock %} From fc86b431afb4c205b7aacdc98f95a2a7676c751c Mon Sep 17 00:00:00 2001 From: ayesha waris <73840786+ayesha-waris@users.noreply.github.com> Date: Thu, 15 Feb 2024 20:43:30 +0500 Subject: [PATCH 3/4] feat: modified author labels to add moderator (#34239) Co-authored-by: sohailfatima <23100065@lums.edu.pk> --- .../discussion/rest_api/serializers.py | 8 +++++--- .../discussion/rest_api/tests/test_api.py | 4 ++-- .../rest_api/tests/test_serializers.py | 16 ++++++++-------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/lms/djangoapps/discussion/rest_api/serializers.py b/lms/djangoapps/discussion/rest_api/serializers.py index 4ac573e76670..f8868cbed8c8 100644 --- a/lms/djangoapps/discussion/rest_api/serializers.py +++ b/lms/djangoapps/discussion/rest_api/serializers.py @@ -203,14 +203,16 @@ def get_author(self, obj): def _get_user_label(self, user_id): """ - Returns the role label (i.e. "Staff" or "Community TA") for the user + Returns the role label (i.e. "Staff", "Moderator" or "Community TA") for the user with the given id. """ - is_staff = user_id in self.context["course_staff_user_ids"] or user_id in self.context["moderator_user_ids"] + is_staff = user_id in self.context["course_staff_user_ids"] + is_moderator = user_id in self.context["moderator_user_ids"] is_ta = user_id in self.context["ta_user_ids"] return ( "Staff" if is_staff else + "Moderator" if is_moderator else "Community TA" if is_ta else None ) @@ -218,7 +220,7 @@ def _get_user_label(self, user_id): def _get_user_label_from_username(self, username): """ Returns role label of user from username - Possible Role Labels: Staff, Community TA or None + Possible Role Labels: Staff, Moderator, Community TA or None """ try: user = User.objects.get(username=username) diff --git a/lms/djangoapps/discussion/rest_api/tests/test_api.py b/lms/djangoapps/discussion/rest_api/tests/test_api.py index a9bf98c50a4e..3d08a9b51a0a 100644 --- a/lms/djangoapps/discussion/rest_api/tests/test_api.py +++ b/lms/djangoapps/discussion/rest_api/tests/test_api.py @@ -1930,7 +1930,7 @@ def test_basic_in_blackout_period_with_user_access(self, mock_emit): with self.assert_signal_sent(api, 'thread_created', sender=None, user=self.user, exclude_args=('post',)): actual = create_thread(self.request, self.minimal_data) expected = self.expected_thread_data({ - "author_label": "Staff", + "author_label": "Moderator", "id": "test_id", "course_id": str(self.course.id), "comment_list_url": "http://testserver/api/discussion/v1/comments/?thread_id=test_id", @@ -2339,7 +2339,7 @@ def test_success_in_black_out_with_user_access(self, parent_id, mock_emit): "thread_id": "test_thread", "parent_id": parent_id, "author": self.user.username, - "author_label": "Staff", + "author_label": "Moderator", "created_at": "2015-05-27T00:00:00Z", "updated_at": "2015-05-27T00:00:00Z", "raw_body": "Test body", diff --git a/lms/djangoapps/discussion/rest_api/tests/test_serializers.py b/lms/djangoapps/discussion/rest_api/tests/test_serializers.py index e2035c9299d9..5d958370c16a 100644 --- a/lms/djangoapps/discussion/rest_api/tests/test_serializers.py +++ b/lms/djangoapps/discussion/rest_api/tests/test_serializers.py @@ -102,9 +102,9 @@ def test_anonymity(self, role_name, anonymous, anonymous_to_peers, expected_seri assert actual_serialized_anonymous == expected_serialized_anonymous @ddt.data( - (FORUM_ROLE_ADMINISTRATOR, False, "Staff"), + (FORUM_ROLE_ADMINISTRATOR, False, "Moderator"), (FORUM_ROLE_ADMINISTRATOR, True, None), - (FORUM_ROLE_MODERATOR, False, "Staff"), + (FORUM_ROLE_MODERATOR, False, "Moderator"), (FORUM_ROLE_MODERATOR, True, None), (FORUM_ROLE_COMMUNITY_TA, False, "Community TA"), (FORUM_ROLE_COMMUNITY_TA, True, None), @@ -116,7 +116,7 @@ def test_author_labels(self, role_name, anonymous, expected_label): """ Test correctness of the author_label field. - The label should be "Staff", "Staff", or "Community TA" for the + The label should be "Staff", "Moderator", or "Community TA" for the Administrator, Moderator, and Community TA roles, respectively, but the label should not be present if the content is anonymous. @@ -274,7 +274,7 @@ def test_closed_by_label_field(self, role, visible): "unread_comments_count": 3, "closed_by": moderator }) - closed_by_label = "Staff" if visible else None + closed_by_label = "Moderator" if visible else None closed_by = moderator if visible else None can_delete = role != FORUM_ROLE_STUDENT editable_fields = ["abuse_flagged", "copy_link", "following", "read", "voted"] @@ -329,7 +329,7 @@ def test_edit_by_label_field(self, role, visible): "unread_comments_count": 3, "closed_by": None }) - edit_by_label = "Staff" if visible else None + edit_by_label = "Moderator" if visible else None can_delete = role != FORUM_ROLE_STUDENT last_edit = None if role == FORUM_ROLE_STUDENT else {"editor_username": moderator} editable_fields = ["abuse_flagged", "copy_link", "following", "read", "voted"] @@ -491,8 +491,8 @@ def test_endorsed_by(self, endorser_role_name, thread_anonymous): assert actual_endorser_anonymous == expected_endorser_anonymous @ddt.data( - (FORUM_ROLE_ADMINISTRATOR, "Staff"), - (FORUM_ROLE_MODERATOR, "Staff"), + (FORUM_ROLE_ADMINISTRATOR, "Moderator"), + (FORUM_ROLE_MODERATOR, "Moderator"), (FORUM_ROLE_COMMUNITY_TA, "Community TA"), (FORUM_ROLE_STUDENT, None), ) @@ -501,7 +501,7 @@ def test_endorsed_by_labels(self, role_name, expected_label): """ Test correctness of the endorsed_by_label field. - The label should be "Staff", "Staff", or "Community TA" for the + The label should be "Staff", "Moderator", or "Community TA" for the Administrator, Moderator, and Community TA roles, respectively. role_name is the name of the author's role. From 008467c6e51407187878d8aa1a5453da1af8f591 Mon Sep 17 00:00:00 2001 From: Ahtisham Shahid Date: Thu, 15 Feb 2024 23:13:44 +0500 Subject: [PATCH 4/4] fix: updated failing notification pref unit test (#34243) --- openedx/core/djangoapps/notifications/tests/test_views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openedx/core/djangoapps/notifications/tests/test_views.py b/openedx/core/djangoapps/notifications/tests/test_views.py index 23eb412487e8..45040e6b0638 100644 --- a/openedx/core/djangoapps/notifications/tests/test_views.py +++ b/openedx/core/djangoapps/notifications/tests/test_views.py @@ -518,6 +518,7 @@ def test_patch_user_notification_preference( non_editable_channels = expected_app_prefs['non_editable'].get(notification_type_name, []) if notification_channel not in non_editable_channels: expected_app_prefs['notification_types'][notification_type_name][notification_channel] = value + expected_data = remove_notifications_with_visibility_settings(expected_data) self.assertEqual(response.data, expected_data) event_name, event_data = mock_emit.call_args[0] self.assertEqual(event_name, 'edx.notifications.preferences.updated')