Merge pull request #14562 from CredoReference/open_response_assessment_tab_for_instructor_dashboard
Open Response Assessment tab for Instructor Dashboard
This commit is contained in:
@@ -321,6 +321,30 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
|
||||
# Max number of student per page is one. Patched setting MAX_STUDENTS_PER_PAGE_GRADE_BOOK = 1
|
||||
self.assertEqual(len(response.mako_context['students']), 1) # pylint: disable=no-member
|
||||
|
||||
def test_open_response_assessment_page(self):
|
||||
"""
|
||||
Test that Open Responses is available only if course contains at least one ORA block
|
||||
"""
|
||||
ora_section = (
|
||||
'<li class="nav-item">'
|
||||
'<button type="button" class="btn-link" data-section="open_response_assessment">'
|
||||
'Open Responses'
|
||||
'</button>'
|
||||
'</li>'
|
||||
)
|
||||
|
||||
response = self.client.get(self.url)
|
||||
self.assertNotIn(ora_section, response.content)
|
||||
|
||||
course = ItemFactory.create(
|
||||
parent_location=self.course.location,
|
||||
category="course",
|
||||
display_name="Test course",
|
||||
)
|
||||
ItemFactory.create(parent_location=course.location, category="openassessment")
|
||||
response = self.client.get(self.url)
|
||||
self.assertIn(ora_section, response.content)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestInstructorDashboardPerformance(ModuleStoreTestCase, LoginEnrollmentTestCase, XssTestMixin):
|
||||
|
||||
@@ -38,6 +38,7 @@ from student.models import CourseEnrollment
|
||||
from shoppingcart.models import Coupon, PaidCourseRegistration, CourseRegCodeItem
|
||||
from course_modes.models import CourseMode, CourseModesArchive
|
||||
from student.roles import CourseFinanceAdminRole, CourseSalesAdminRole
|
||||
from lms.djangoapps.courseware.module_render import get_module_by_usage_id
|
||||
from certificates.models import (
|
||||
CertificateGenerationConfiguration,
|
||||
CertificateWhitelist,
|
||||
@@ -190,6 +191,10 @@ def instructor_dashboard_2(request, course_id):
|
||||
if certs_enabled and access['admin']:
|
||||
sections.append(_section_certificates(course))
|
||||
|
||||
openassessment_blocks = modulestore().get_items(course_key, qualifiers={'category': 'openassessment'})
|
||||
if len(openassessment_blocks) > 0:
|
||||
sections.append(_section_open_response_assessment(request, course, openassessment_blocks, access))
|
||||
|
||||
disable_buttons = not _is_small_course(course_key)
|
||||
|
||||
certificate_white_list = CertificateWhitelist.get_certificate_white_list(course_key)
|
||||
@@ -698,6 +703,48 @@ def _section_metrics(course, access):
|
||||
return section_data
|
||||
|
||||
|
||||
def _section_open_response_assessment(request, course, openassessment_blocks, access):
|
||||
"""Provide data for the corresponding dashboard section """
|
||||
course_key = course.id
|
||||
|
||||
ora_items = []
|
||||
parents = {}
|
||||
|
||||
for block in openassessment_blocks:
|
||||
block_parent_id = unicode(block.parent)
|
||||
result_item_id = unicode(block.location)
|
||||
if block_parent_id not in parents:
|
||||
parents[block_parent_id] = modulestore().get_item(block.parent)
|
||||
|
||||
ora_items.append({
|
||||
'id': result_item_id,
|
||||
'name': block.display_name,
|
||||
'parent_id': block_parent_id,
|
||||
'parent_name': parents[block_parent_id].display_name,
|
||||
'staff_assessment': 'staff-assessment' in block.assessment_steps,
|
||||
'url_base': reverse('xblock_view', args=[course.id, block.location, 'student_view']),
|
||||
'url_grade_available_responses': reverse('xblock_view', args=[course.id, block.location,
|
||||
'grade_available_responses_view']),
|
||||
})
|
||||
|
||||
openassessment_block = openassessment_blocks[0]
|
||||
block, __ = get_module_by_usage_id(
|
||||
request, unicode(course_key), unicode(openassessment_block.location),
|
||||
disable_staff_debug_info=True, course=course
|
||||
)
|
||||
section_data = {
|
||||
'fragment': block.render('ora_blocks_listing_view', context={
|
||||
'ora_items': ora_items,
|
||||
'ora_item_view_enabled': settings.FEATURES.get('ENABLE_XBLOCK_VIEW_ENDPOINT', False)
|
||||
}),
|
||||
'section_key': 'open_response_assessment',
|
||||
'section_display_name': _('Open Responses'),
|
||||
'access': access,
|
||||
'course_id': unicode(course_key),
|
||||
}
|
||||
return section_data
|
||||
|
||||
|
||||
def is_ecommerce_course(course_key):
|
||||
"""
|
||||
Checks if the given course is an e-commerce course or not, by checking its SKU value from
|
||||
|
||||
@@ -190,6 +190,9 @@ such that the value can be defined later than this assignment (file load order).
|
||||
}, {
|
||||
constructor: window.InstructorDashboard.sections.Certificates,
|
||||
$element: idashContent.find('.' + CSS_IDASH_SECTION + '#certificates')
|
||||
}, {
|
||||
constructor: window.InstructorDashboard.sections.OpenResponseAssessment,
|
||||
$element: idashContent.find('.' + CSS_IDASH_SECTION + '#open_response_assessment')
|
||||
}
|
||||
];
|
||||
if (edx.instructor_dashboard.proctoring !== void 0) {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/* globals _ */
|
||||
|
||||
(function(_) {
|
||||
'use strict';
|
||||
|
||||
var OpenResponseAssessment = (function() {
|
||||
function OpenResponseAssessmentBlock($section) {
|
||||
this.$section = $section;
|
||||
this.$section.data('wrapper', this);
|
||||
}
|
||||
|
||||
OpenResponseAssessmentBlock.prototype.onClickTitle = function() {
|
||||
var block = this.$section.find('.open-response-assessment');
|
||||
XBlock.initializeBlock($(block).find('.xblock')[0]);
|
||||
};
|
||||
|
||||
return OpenResponseAssessmentBlock;
|
||||
}());
|
||||
|
||||
if (typeof window.setup_debug === 'undefined') {
|
||||
// eslint-disable-next-line no-unused-vars, camelcase
|
||||
window.setup_debug = function(element_id, edit_link, staff_context) {
|
||||
// stub function.
|
||||
};
|
||||
}
|
||||
|
||||
_.defaults(window, {
|
||||
InstructorDashboard: {}
|
||||
});
|
||||
|
||||
_.defaults(window.InstructorDashboard, {
|
||||
sections: {}
|
||||
});
|
||||
|
||||
_.defaults(window.InstructorDashboard.sections, {
|
||||
OpenResponseAssessment: OpenResponseAssessment
|
||||
});
|
||||
|
||||
this.OpenResponseAssessment = OpenResponseAssessment;
|
||||
}).call(this, _);
|
||||
@@ -1482,6 +1482,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
// view - student admin
|
||||
// --------------------
|
||||
.instructor-dashboard-wrapper-2 section.idash-section#open_response_assessment {
|
||||
.open-response-assessment {
|
||||
padding-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
input[name="subject"] {
|
||||
width:600px;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.urlresolvers import reverse
|
||||
from openedx.core.djangolib.markup import HTML
|
||||
%>
|
||||
<%block name="bodyclass">view-in-course view-instructordash</%block>
|
||||
|
||||
@@ -63,6 +64,19 @@ from django.core.urlresolvers import reverse
|
||||
<script type="text/javascript" src="${static.url('js/views/notification.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/views/file_uploader.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/utils/animation.js')}"></script>
|
||||
% for section_data in sections:
|
||||
% if 'fragment' in section_data:
|
||||
${HTML(section_data['fragment'].head_html())}
|
||||
% endif
|
||||
% endfor
|
||||
</%block>
|
||||
|
||||
<%block name="js_extra">
|
||||
% for section_data in sections:
|
||||
% if 'fragment' in section_data:
|
||||
${HTML(section_data['fragment'].foot_html())}
|
||||
% endif
|
||||
% endfor
|
||||
</%block>
|
||||
|
||||
## Include Underscore templates
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<%page args="section_data" expression_filter="h"/>
|
||||
<%! from openedx.core.djangolib.markup import HTML %>
|
||||
|
||||
<section class="open-response-assessment">
|
||||
${HTML(section_data['fragment'].body_html())}
|
||||
</section>
|
||||
Reference in New Issue
Block a user