diff --git a/lms/djangoapps/course_home_api/outline/v1/serializers.py b/lms/djangoapps/course_home_api/outline/v1/serializers.py index 74e5ec2fcf..78c3c04ceb 100644 --- a/lms/djangoapps/course_home_api/outline/v1/serializers.py +++ b/lms/djangoapps/course_home_api/outline/v1/serializers.py @@ -62,6 +62,11 @@ class EnrollAlertSerializer(serializers.Serializer): extra_text = serializers.CharField() +class ResumeCourseSerializer(serializers.Serializer): + has_visited_course = serializers.BooleanField() + url = serializers.URLField() + + class OutlineTabSerializer(serializers.Serializer): """ Serializer for the Outline Tab @@ -73,4 +78,5 @@ class OutlineTabSerializer(serializers.Serializer): enroll_alert = EnrollAlertSerializer() handouts_html = serializers.CharField() offer_html = serializers.CharField() + resume_course = ResumeCourseSerializer() welcome_message_html = serializers.CharField() diff --git a/lms/djangoapps/course_home_api/outline/v1/tests/test_views.py b/lms/djangoapps/course_home_api/outline/v1/tests/test_views.py index 56fbd69d8a..c41bcdb3d7 100644 --- a/lms/djangoapps/course_home_api/outline/v1/tests/test_views.py +++ b/lms/djangoapps/course_home_api/outline/v1/tests/test_views.py @@ -45,6 +45,11 @@ class OutlineTabTestViews(BaseCourseHomeTests): self.assertTrue(all((block.get('title') != "") for block in date_blocks)) self.assertTrue(all(block.get('date') for block in date_blocks)) + resume_course = response.data.get('resume_course') + resume_course_url = resume_course.get('url') + if resume_course_url: + self.assertIn('http://', resume_course_url) + @COURSE_HOME_MICROFRONTEND.override(active=True) @COURSE_HOME_MICROFRONTEND_OUTLINE_TAB.override(active=True) def test_get_authenticated_user_not_enrolled(self): diff --git a/lms/djangoapps/course_home_api/outline/v1/views.py b/lms/djangoapps/course_home_api/outline/v1/views.py index 4e2227a544..accaa098e7 100644 --- a/lms/djangoapps/course_home_api/outline/v1/views.py +++ b/lms/djangoapps/course_home_api/outline/v1/views.py @@ -14,6 +14,8 @@ from rest_framework.generics import RetrieveAPIView from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response +from completion.exceptions import UnavailableCompletionData +from completion.utilities import get_key_to_last_completed_block from course_modes.models import CourseMode from lms.djangoapps.course_api.blocks.transformers.blocks_api import BlocksAPITransformer from lms.djangoapps.course_blocks.api import get_course_block_access_transformers, get_course_blocks @@ -59,10 +61,6 @@ class OutlineTabView(RetrieveAPIView): Body consists of the following fields: - course_tools: List of serialized Course Tool objects. Each serialization has the following fields: - analytics_id: (str) The unique id given to the tool. - title: (str) The display title of the tool. - url: (str) The link to access the tool. course_blocks: blocks: List of serialized Course Block objects. Each serialization has the following fields: id: (str) The usage ID of the block. @@ -75,7 +73,31 @@ class OutlineTabView(RetrieveAPIView): xBlock on the web LMS. children: (list) If the block has child blocks, a list of IDs of the child blocks. + course_tools: List of serialized Course Tool objects. Each serialization has the following fields: + analytics_id: (str) The unique id given to the tool. + title: (str) The display title of the tool. + url: (str) The link to access the tool. + dates_widget: + course_date_blocks: List of serialized Course Dates objects. Each serialization has the following fields: + complete: (bool) Meant to only be used by assignments. Indicates completeness for an + assignment. + date: (datetime) The date time corresponding for the event + date_type: (str) The type of date (ex. course-start-date, assignment-due-date, etc.) + description: (str) The description for the date event + learner_has_access: (bool) Indicates if the learner has access to the date event + link: (str) An absolute link to content related to the date event + (ex. verified link or link to assignment) + title: (str) The title of the date event + dates_tab_link: (str) The URL to the Dates Tab + user_timezone: (str) The timezone of the given user + enroll_alert: + can_enroll: (bool) Whether the user can enroll in the given course + extra_text: (str) handouts_html: (str) Raw HTML for the handouts section of the course info + resume_course: + has_visited_course: (bool) Whether the user has ever visited the course + url: (str) The display name of the course block to resume + welcome_message_html: (str) Raw HTML for the course updates banner **Returns** @@ -158,11 +180,29 @@ class OutlineTabView(RetrieveAPIView): transformers = BlockStructureTransformers() transformers += get_course_block_access_transformers(request.user) transformers += [ - BlocksAPITransformer(None, None, depth=3), + BlocksAPITransformer(None, None, depth=4), ] course_blocks = get_course_blocks(request.user, course_usage_key, transformers, include_completion=True) + has_visited_course = False + try: + resume_block = get_key_to_last_completed_block(request.user, course.id) + has_visited_course = True + except UnavailableCompletionData: + resume_block = course_usage_key + + resume_path = reverse('jump_to', kwargs={ + 'course_id': course_key_string, + 'location': str(resume_block) + }) + resume_course_url = request.build_absolute_uri(resume_path) + + resume_course = { + 'has_visited_course': has_visited_course, + 'url': resume_course_url, + } + dates_widget = { 'course_date_blocks': [block for block in date_blocks if not isinstance(block, TodaysDate)], 'dates_tab_link': dates_tab_link, @@ -177,6 +217,7 @@ class OutlineTabView(RetrieveAPIView): 'enroll_alert': enroll_alert, 'handouts_html': handouts_html, 'offer_html': offer_html, + 'resume_course': resume_course, 'welcome_message_html': welcome_message_html, } context = self.get_serializer_context() diff --git a/lms/djangoapps/courseware/tabs.py b/lms/djangoapps/courseware/tabs.py index 0971b2fefa..1a0ee10f32 100644 --- a/lms/djangoapps/courseware/tabs.py +++ b/lms/djangoapps/courseware/tabs.py @@ -44,9 +44,9 @@ class CoursewareTab(EnrolledTab): def __init__(self, tab_dict): def link_func(course, reverse_func): if course_home_mfe_outline_tab_is_active(course.id): - return get_microfrontend_url(course_key=course.id, view_name=self.view_name) + return get_microfrontend_url(course_key=course.id, view_name='home') else: - reverse_name_func = lambda course_test: default_course_url_name(course_test.id) + reverse_name_func = lambda course: default_course_url_name(course.id) url_func = course_reverse_func_from_name_func(reverse_name_func) return url_func(course, reverse_func)