diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 749b9ef56e6d..47ffc2e31334 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,9 @@ These are notable changes in edx-platform. This is a rolling list of changes, in roughly chronological order, most recent first. Add your entries at or near the top. Include a label indicating the component affected. +LMS: Added alphabetical sorting of forum categories and subcategories. +It is hidden behind a false defaulted course level flag. + Studio: Allow course authors to set their course image on the schedule and details page, with support for JPEG and PNG images. diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py index 10bcf4a4e304..c583aec3d126 100644 --- a/common/lib/xmodule/xmodule/course_module.py +++ b/common/lib/xmodule/xmodule/course_module.py @@ -198,10 +198,8 @@ class CourseFields(object): tabs = List(help="List of tabs to enable in this course", scope=Scope.settings) end_of_course_survey_url = String(help="Url for the end-of-course survey", scope=Scope.settings) discussion_blackouts = List(help="List of pairs of start/end dates for discussion blackouts", scope=Scope.settings) - discussion_topics = Dict( - help="Map of topics names to ids", - scope=Scope.settings - ) + discussion_topics = Dict(help="Map of topics names to ids", scope=Scope.settings) + discussion_sort_alpha = Boolean(scope=Scope.settings, default=False, help="Sort forum categories and subcategories alphabetically.") testcenter_info = Dict(help="Dictionary of Test Center info", scope=Scope.settings) announcement = Date(help="Date this course is announced", scope=Scope.settings) cohort_config = Dict(help="Dictionary defining cohort configuration", scope=Scope.settings) diff --git a/lms/djangoapps/django_comment_client/tests/test_utils.py b/lms/djangoapps/django_comment_client/tests/test_utils.py index 555264cb5f8c..efc6e6c7a3d3 100644 --- a/lms/djangoapps/django_comment_client/tests/test_utils.py +++ b/lms/djangoapps/django_comment_client/tests/test_utils.py @@ -29,6 +29,128 @@ def test_merge_dict(self): self.assertEqual(utils.merge_dict(d1, d2), expected) +class CategorySortTestCase(TestCase): + def setUp(self): + self.category_map = { + 'entries': { + u'General': { + 'sort_key': u'General' + } + }, + 'subcategories': { + u'Tests': { + 'sort_key': u'Tests', + 'subcategories': {}, + 'entries': { + u'Quizzes': { + 'sort_key': None + }, u'All': { + 'sort_key': None + }, u'Final Exam': { + 'sort_key': None + }, + } + }, + u'Assignments': { + 'sort_key': u'Assignments', + 'subcategories': {}, + 'entries': { + u'Homework': { + 'sort_key': None + }, + u'All': { + 'sort_key': None + }, + } + } + } + } + + def test_alpha_sort_true(self): + expected_true = { + 'entries': { + u'General': { + 'sort_key': u'General' + } + }, + 'children': [u'Assignments', u'General', u'Tests'], + 'subcategories': { + u'Tests': { + 'sort_key': u'Tests', + 'subcategories': {}, + 'children': [u'All', u'Final Exam', u'Quizzes'], + 'entries': { + u'All': { + 'sort_key': 'All' + }, u'Final Exam': { + 'sort_key': 'Final Exam' + }, u'Quizzes': { + 'sort_key': 'Quizzes' + } + } + }, + u'Assignments': { + 'sort_key': u'Assignments', + 'subcategories': {}, + 'children': [u'All', u'Homework'], + 'entries': { + u'Homework': { + 'sort_key': 'Homework' + }, + u'All': { + 'sort_key': 'All' + }, + } + } + } + } + + utils.sort_map_entries(self.category_map, True) + self.assertEqual(self.category_map, expected_true) + + def test_alpha_sort_false(self): + expected_false = { + 'entries': { + u'General': { + 'sort_key': u'General' + } + }, + 'children': [u'Assignments', u'General', u'Tests'], + 'subcategories': { + u'Tests': { + 'sort_key': u'Tests', + 'subcategories': {}, + 'children': [u'Quizzes', u'All', u'Final Exam'], + 'entries': { + u'Quizzes': { + 'sort_key': None + }, u'All': { + 'sort_key': None + }, u'Final Exam': { + 'sort_key': None + }, + } + }, + u'Assignments': { + 'sort_key': u'Assignments', + 'subcategories': {}, + 'children': [u'All', u'Homework'], + 'entries': { + u'Homework': { + 'sort_key': None + }, + u'All': { + 'sort_key': None + }, + } + } + } + } + + utils.sort_map_entries(self.category_map, False) + self.assertEqual(self.category_map, expected_false) + + class AccessUtilsTestCase(TestCase): def setUp(self): self.course_id = 'edX/toy/2012_Fall' diff --git a/lms/djangoapps/django_comment_client/utils.py b/lms/djangoapps/django_comment_client/utils.py index c3e2708f67a4..9309f919d39a 100644 --- a/lms/djangoapps/django_comment_client/utils.py +++ b/lms/djangoapps/django_comment_client/utils.py @@ -125,14 +125,16 @@ def filter_unstarted_categories(category_map): return result_map - -def sort_map_entries(category_map): + +def sort_map_entries(category_map, sort_alpha): things = [] for title, entry in category_map["entries"].items(): + if entry["sort_key"] == None and sort_alpha: + entry["sort_key"] = title things.append((title, entry)) for title, category in category_map["subcategories"].items(): things.append((title, category)) - sort_map_entries(category_map["subcategories"][title]) + sort_map_entries(category_map["subcategories"][title], sort_alpha) category_map["children"] = [x[0] for x in sorted(things, key=lambda x: x[1]["sort_key"])] @@ -211,7 +213,8 @@ def initialize_discussion_info(course): category_map['entries'][topic] = {"id": entry["id"], "sort_key": entry.get("sort_key", topic), "start_date": datetime.now(UTC())} - sort_map_entries(category_map) + + sort_map_entries(category_map, course.discussion_sort_alpha) _DISCUSSIONINFO[course.id]['id_map'] = discussion_id_map _DISCUSSIONINFO[course.id]['category_map'] = category_map