diff --git a/lms/djangoapps/course_home_api/dates/v1/serializers.py b/lms/djangoapps/course_home_api/dates/v1/serializers.py index c1f8712f4b..db4c7abb74 100644 --- a/lms/djangoapps/course_home_api/dates/v1/serializers.py +++ b/lms/djangoapps/course_home_api/dates/v1/serializers.py @@ -24,6 +24,7 @@ class DateSummarySerializer(serializers.Serializer): link_text = serializers.CharField() title = serializers.CharField() extra_info = serializers.CharField() + first_component_block_id = serializers.SerializerMethodField() def get_learner_has_access(self, block): learner_is_full_access = self.context.get('learner_is_full_access', False) @@ -37,6 +38,9 @@ class DateSummarySerializer(serializers.Serializer): return request.build_absolute_uri(block.link) return '' + def get_first_component_block_id(self, block): + return getattr(block, 'first_component_block_id', '') + class DatesTabSerializer(DatesBannerSerializerMixin, serializers.Serializer): """ diff --git a/lms/djangoapps/courseware/courses.py b/lms/djangoapps/courseware/courses.py index 00f966f480..bcbf28e906 100644 --- a/lms/djangoapps/courseware/courses.py +++ b/lms/djangoapps/courseware/courses.py @@ -73,7 +73,7 @@ log = logging.getLogger(__name__) # Used by get_course_assignments below. You shouldn't need to use this type directly. _Assignment = namedtuple( 'Assignment', ['block_key', 'title', 'url', 'date', 'contains_gated_content', 'complete', 'past_due', - 'assignment_type', 'extra_info'] + 'assignment_type', 'extra_info', 'first_component_block_id'] ) @@ -505,6 +505,7 @@ def get_course_assignment_date_blocks(course, user, request, num_return=None, date_block = CourseAssignmentDate(course, user) date_block.date = assignment.date date_block.contains_gated_content = assignment.contains_gated_content + date_block.first_component_block_id = assignment.first_component_block_id date_block.complete = assignment.complete date_block.assignment_type = assignment.assignment_type date_block.past_due = assignment.past_due @@ -539,6 +540,7 @@ def get_course_assignments(course_key, user, include_access=False): due = block_data.get_xblock_field(subsection_key, 'due') graded = block_data.get_xblock_field(subsection_key, 'graded', False) if due and graded: + first_component_block_id = get_first_component_of_block(subsection_key, block_data) contains_gated_content = include_access and block_data.get_xblock_field( subsection_key, 'contains_gated_content', False) title = block_data.get_xblock_field(subsection_key, 'display_name', _('Assignment')) @@ -554,7 +556,8 @@ def get_course_assignments(course_key, user, include_access=False): complete = is_block_structure_complete_for_assignments(block_data, subsection_key) past_due = not complete and due < now assignments.append(_Assignment( - subsection_key, title, url, due, contains_gated_content, complete, past_due, assignment_type, None + subsection_key, title, url, due, contains_gated_content, + complete, past_due, assignment_type, None, first_component_block_id )) # Load all dates for ORA blocks as separate assignments @@ -612,6 +615,7 @@ def get_course_assignments(course_key, user, include_access=False): url = reverse('jump_to', args=[course_key, descendent]) past_due = not complete and due and due < now + first_component_block_id = str(descendent) assignments.append(_Assignment( descendent, title, @@ -621,12 +625,24 @@ def get_course_assignments(course_key, user, include_access=False): complete, past_due, assignment_type, - _("Open Response Assessment due dates are set by your instructor and can't be shifted.") + _("Open Response Assessment due dates are set by your instructor and can't be shifted."), + first_component_block_id, )) return assignments +def get_first_component_of_block(block_key, block_data): + """ + This function returns the first leaf block of a section(block_key) + """ + descendents = block_data.get_children(block_key) + if descendents: + return get_first_component_of_block(descendents[0], block_data) + + return str(block_key) + + # TODO: Fix this such that these are pulled in as extra course-specific tabs. # arjun will address this by the end of October if no one does so prior to # then. diff --git a/lms/djangoapps/courseware/date_summary.py b/lms/djangoapps/courseware/date_summary.py index 6544934415..9050d05be6 100644 --- a/lms/djangoapps/courseware/date_summary.py +++ b/lms/djangoapps/courseware/date_summary.py @@ -388,6 +388,7 @@ class CourseAssignmentDate(DateSummary): self.assignment_link = '' self.assignment_title = None self.assignment_title_html = None + self.first_component_block_id = None self.contains_gated_content = False self.complete = None self.past_due = None diff --git a/openedx/features/calendar_sync/tests/test_ics.py b/openedx/features/calendar_sync/tests/test_ics.py index c2a5679496..773a643a0b 100644 --- a/openedx/features/calendar_sync/tests/test_ics.py +++ b/openedx/features/calendar_sync/tests/test_ics.py @@ -41,7 +41,7 @@ class TestIcsGeneration(TestCase): def make_assigment( self, block_key=None, title=None, url=None, date=None, contains_gated_content=False, complete=False, - past_due=False, assignment_type=None, extra_info=None + past_due=False, assignment_type=None, extra_info=None, first_component_block_id=None ): """ Bundles given info into a namedtupled like get_course_assignments returns """ return _Assignment( @@ -53,7 +53,8 @@ class TestIcsGeneration(TestCase): complete, past_due, assignment_type, - extra_info + extra_info, + first_component_block_id ) def expected_ics(self, *assignments):