Merge pull request #17484 from edx/sofiya/educator-2203

Add visual progress checkmarks to course outline
This commit is contained in:
Sofiya Semenova
2018-02-21 15:50:42 -05:00
committed by GitHub
5 changed files with 84 additions and 29 deletions

View File

@@ -365,8 +365,6 @@
@include margin-left(16px);
list-style-type: none;
border: 1px solid transparent;
border-radius: 2px;
a.outline-item {
display: flex;
@@ -377,6 +375,22 @@
border-top: 1px solid $border-color;
}
a.outline-item:hover {
text-decoration: none;
.vertical-details {
text-decoration: underline;
}
.complete-checkmark {
text-decoration: none;
}
}
.vertical-details {
float:left;
}
&:hover,
&:focus {
background-color: palette(primary, x-back);
@@ -399,11 +413,11 @@
// Course outline accordion
button.accordion-trigger, button.prerequisite-button {
margin: 2px;
padding: 10px 0 10px 0;
border: none;
width: 100%;
text-align: left;
margin: 0px;
.fa {
color: $blue;
@@ -414,6 +428,15 @@ button.accordion-trigger, button.prerequisite-button {
display: none;
}
.fa-check.fa.complete-checkmark {
border: 1px solid $green;
margin-right: $baseline / 2;
border-radius: 100px;
color: white;
background-color: $green;
float: right;
}
// Course outline
.course-outline {
.block-tree {

View File

@@ -27,6 +27,9 @@ from openedx.core.djangolib.markup import HTML, Text
id="${ section['id'] }">
<span class="fa fa-chevron-right ${ 'fa-rotate-90' if section_is_auto_opened else '' }" aria-hidden="true"></span>
<h3 class="section-title">${ section['display_name'] }</h3>
% if show_visual_progress and section.get('complete'):
<span class="complete-checkmark fa fa-check"></span>
% endif
</button>
<ol class="outline-item accordion-panel ${ '' if section_is_auto_opened else 'is-hidden' }"
id="${ section['id'] }_contents"
@@ -70,7 +73,10 @@ from openedx.core.djangolib.markup import HTML, Text
<span class="subsection-title">
${ subsection['display_name'] }
</span>
% endif
% if subsection.get('complete') and show_visual_progress:
<span class="complete-checkmark fa fa-check"></span>
% endif
% endif
<div class="details">
## There are behavior differences between rendering of subsections which have
@@ -150,6 +156,9 @@ from openedx.core.djangolib.markup import HTML, Text
${ vertical['display_name'] }
</span>
</div>
% if vertical.get('complete') and show_visual_progress:
<span class="complete-checkmark fa fa-check"></span>
% endif
</a>
</li>
% endfor

View File

@@ -379,12 +379,13 @@ class TestCourseOutlineResumeCourse(SharedModuleStoreTestCase, CompletionWaffleT
# first navigate to a sequential to make it the last accessed
chapter = course.children[0]
sequential = chapter.children[0]
vertical = sequential.children[0]
self.visit_sequential(course, chapter, sequential)
# check resume course buttons
response = self.visit_course_home(course, resume_count=2)
content = pq(response.content)
self.assertTrue(content('.action-resume-course').attr('href').endswith('/sequential/' + sequential.url_name))
self.assertTrue(content('.action-resume-course').attr('href').endswith('/vertical/' + vertical.url_name))
@override_switch(
'{}.{}'.format(

View File

@@ -6,7 +6,7 @@ from completion.waffle import visual_progress_enabled
from lms.djangoapps.course_api.blocks.api import get_blocks
from lms.djangoapps.course_blocks.utils import get_student_module_as_dict
from opaque_keys.edx.keys import CourseKey, UsageKey
from opaque_keys.edx.keys import CourseKey
from openedx.core.djangoapps.request_cache.middleware import request_cached
from xmodule.modulestore.django import modulestore
@@ -118,26 +118,18 @@ def get_course_outline_block_tree(request, course_id):
course_key = CourseKey.from_string(course_id)
course_usage_key = modulestore().make_course_usage_key(course_key)
if visual_progress_enabled(course_key=course_key):
# Deeper query for course tree traversing/marking complete
# and last completed block
block_types_filter = [
'course',
'chapter',
'sequential',
'vertical',
'html',
'problem',
'video',
'discussion'
]
else:
# Shallower query is sufficient for last accessed block
block_types_filter = [
'course',
'chapter',
'sequential'
]
# Deeper query for course tree traversing/marking complete
# and last completed block
block_types_filter = [
'course',
'chapter',
'sequential',
'vertical',
'html',
'problem',
'video',
'discussion'
]
all_blocks = get_blocks(
request,
course_usage_key,

View File

@@ -2,7 +2,10 @@
Views to show a course outline.
"""
import re
import datetime
import pytz
from django.contrib.auth.models import User
from django.template.context_processors import csrf
from django.template.loader import render_to_string
from opaque_keys.edx.keys import CourseKey
@@ -10,7 +13,9 @@ from web_fragments.fragment import Fragment
from courseware.courses import get_course_overview_with_access
from openedx.core.djangoapps.plugin_api.views import EdxFragmentView
from openedx.features.course_experience import waffle as waffle
from openedx.features.course_experience import waffle as course_experience_waffle
from completion import waffle as completion_waffle
from student.models import CourseEnrollment
from ..utils import get_course_outline_block_tree
from util.milestones_helpers import get_course_content_milestones
@@ -32,14 +37,19 @@ class CourseOutlineFragmentView(EdxFragmentView):
if not course_block_tree:
return None
# TODO: EDUCATOR-2283 Remove 'show_visual_progress' from context
# and remove the check for it in the HTML file
show_visual_progress = (completion_waffle.visual_progress_enabled(course_key) and
self.user_enrolled_after_completion_collection(request.user, course_key))
context = {
'csrf': csrf(request)['csrf_token'],
'course': course_overview,
'blocks': course_block_tree
'blocks': course_block_tree,
'show_visual_progress': show_visual_progress
}
# TODO: EDUCATOR-2283 Remove this check when the waffle flag is turned on in production
if waffle.new_course_outline_enabled(course_key=course_key):
if course_experience_waffle.new_course_outline_enabled(course_key=course_key):
xblock_display_names = self.create_xblock_id_and_name_dict(course_block_tree)
gated_content = self.get_content_milestones(request, course_key)
@@ -120,3 +130,23 @@ class CourseOutlineFragmentView(EdxFragmentView):
}
return course_content_milestones
def user_enrolled_after_completion_collection(self, user, course_key):
"""
Checks that the user has enrolled in the course after 01/24/2018, the date that
the completion API began data collection. If the user has enrolled in the course
before this date, they may see incomplete collection data. This is a temporary
check until all active enrollments are created after the date.
"""
begin_collection_date = datetime.datetime(2018, 01, 24, tzinfo=pytz.utc)
user = User.objects.get(username=user)
user_enrollment = CourseEnrollment.objects.get(
user=user,
course_id=course_key,
is_active=True
)
if user_enrollment and user_enrollment.created > begin_collection_date:
return True
return False