Commit faf796b5 by Adam

Merge pull request #1125 from edx/adam/remove-instr-dash-buttons

disable buttons for legacy and beta instr dash
parents a617988c e3758461
......@@ -5,6 +5,7 @@ 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: Disable data download buttons on the instructor dashboard for large courses
LMS: Refactor and clean student dashboard templates.
......
......@@ -9,6 +9,7 @@ from mitxmako.shortcuts import render_to_response
from django.core.urlresolvers import reverse
from django.utils.html import escape
from django.http import Http404
from django.conf import settings
from courseware.access import has_access
from courseware.courses import get_course_by_id
......@@ -45,10 +46,19 @@ def instructor_dashboard_2(request, course_id):
_section_analytics(course_id),
]
enrollment_count = sections[0]['enrollment_count']
disable_buttons = False
max_enrollment_for_buttons = settings.MITX_FEATURES.get("MAX_ENROLLMENT_INSTR_BUTTONS")
if max_enrollment_for_buttons is not None:
disable_buttons = enrollment_count > max_enrollment_for_buttons
context = {
'course': course,
'old_dashboard_url': reverse('instructor_dashboard', kwargs={'course_id': course_id}),
'sections': sections,
'disable_buttons': disable_buttons,
}
return render_to_response('instructor/instructor_dashboard_2/instructor_dashboard_2.html', context)
......
......@@ -105,12 +105,15 @@ def instructor_dashboard(request, course_id):
else:
idash_mode = request.session.get('idash_mode', 'Grades')
enrollment_number = CourseEnrollment.objects.filter(course_id=course_id, is_active=1).count()
# assemble some course statistics for output to instructor
def get_course_stats_table():
datatable = {'header': ['Statistic', 'Value'],
'title': _u('Course Statistics At A Glance'),
}
data = [['# Enrolled', CourseEnrollment.objects.filter(course_id=course_id, is_active=1).count()]]
datatable = {
'header': ['Statistic', 'Value'],
'title': _u('Course Statistics At A Glance'),
}
data = [['# Enrolled', enrollment_number]]
data += [['Date', timezone.now().isoformat()]]
data += compute_course_stats(course).items()
if request.user.is_staff:
......@@ -832,35 +835,43 @@ def instructor_dashboard(request, course_id):
if not datatable:
course_stats = get_course_stats_table()
# disable buttons for large courses
disable_buttons = False
max_enrollment_for_buttons = settings.MITX_FEATURES.get("MAX_ENROLLMENT_INSTR_BUTTONS")
if max_enrollment_for_buttons is not None:
disable_buttons = enrollment_number > max_enrollment_for_buttons
#----------------------------------------
# context for rendering
context = {'course': course,
'staff_access': True,
'admin_access': request.user.is_staff,
'instructor_access': instructor_access,
'forum_admin_access': forum_admin_access,
'datatable': datatable,
'course_stats': course_stats,
'msg': msg,
'modeflag': {idash_mode: 'selectedmode'},
'studio_url': studio_url,
'to_option': email_to_option, # email
'subject': email_subject, # email
'editor': email_editor, # email
'email_msg': email_msg, # email
'show_email_tab': show_email_tab, # email
'problems': problems, # psychometrics
'plots': plots, # psychometrics
'course_errors': modulestore().get_item_errors(course.location),
'instructor_tasks': instructor_tasks,
'offline_grade_log': offline_grades_available(course_id),
'cohorts_ajax_url': reverse('cohorts', kwargs={'course_id': course_id}),
'analytics_results': analytics_results,
}
context = {
'course': course,
'staff_access': True,
'admin_access': request.user.is_staff,
'instructor_access': instructor_access,
'forum_admin_access': forum_admin_access,
'datatable': datatable,
'course_stats': course_stats,
'msg': msg,
'modeflag': {idash_mode: 'selectedmode'},
'studio_url': studio_url,
'to_option': email_to_option, # email
'subject': email_subject, # email
'editor': email_editor, # email
'email_msg': email_msg, # email
'show_email_tab': show_email_tab, # email
'problems': problems, # psychometrics
'plots': plots, # psychometrics
'course_errors': modulestore().get_item_errors(course.location),
'instructor_tasks': instructor_tasks,
'offline_grade_log': offline_grades_available(course_id),
'cohorts_ajax_url': reverse('cohorts', kwargs={'course_id': course_id}),
'analytics_results': analytics_results,
'disable_buttons': disable_buttons
}
if settings.MITX_FEATURES.get('ENABLE_INSTRUCTOR_BETA_DASHBOARD'):
context['beta_dashboard_url'] = reverse('instructor_dashboard_2', kwargs={'course_id': course_id})
......
......@@ -182,6 +182,10 @@ MITX_FEATURES = {
# Automatically approve student identity verification attempts
'AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING': False,
# Disable instructor dash buttons for downloading course data
# when enrollment exceeds this number
'MAX_ENROLLMENT_INSTR_BUTTONS': 200,
}
# Used for A/B testing
......
......@@ -219,6 +219,11 @@ $action-secondary-disabled-fg: $white;
$header-graphic-super-color: $m-blue-d1;
$header-graphic-sub-color: $m-gray-d2;
// State-based colors
$error-color: $error-red;
$warning-color: $m-pink;
$confirm-color: $m-green;
// ====================
// MISC: visual horizontal rules
......
......@@ -40,6 +40,8 @@
}
}
// ====================
// system feedback - messages
.msg {
border-radius: 1px;
......@@ -51,15 +53,51 @@
}
}
// TYPE: warning
.msg-warning {
border-top: 2px solid $warning-color;
background: tint($warning-color,95%);
.copy {
color: $warning-color;
}
}
// TYPE: confirm
.msg-confirm {
border-top: 2px solid green;
background: tint(green,90%);
border-top: 2px solid $confirm-color;
background: tint($confirm-color,95%);
.copy {
color: $confirm-color;
}
}
// TYPE: confirm
.msg-error {
border-top: 2px solid $error-color;
background: tint($error-color,95%);
.copy {
color: green;
color: $error-color;
}
}
// ====================
// inline copy
.copy-confirm {
color: $confirm-color;
}
.copy-warning {
color: $warning-color;
}
.copy-error {
color: $error-color;
}
.list-advice {
list-style: none;
padding: 0;
......
......@@ -18,6 +18,77 @@
right: 15px;
font-size: 11pt;
}
// system feedback - messages
.msg {
border-radius: 1px;
padding: 10px 15px;
margin-bottom: 20px;
.copy {
font-weight: 600;
}
}
// TYPE: warning
.msg-warning {
border-top: 2px solid $warning-color;
background: tint($warning-color,95%);
.copy {
color: $warning-color;
}
}
// TYPE: confirm
.msg-confirm {
border-top: 2px solid $confirm-color;
background: tint($confirm-color,95%);
.copy {
color: $confirm-color;
}
}
// TYPE: confirm
.msg-error {
border-top: 2px solid $error-color;
background: tint($error-color,95%);
.copy {
color: $error-color;
}
}
// ====================
// inline copy
.copy-confirm {
color: $confirm-color;
}
.copy-warning {
color: $warning-color;
}
.copy-error {
color: $error-color;
}
.list-advice {
list-style: none;
padding: 0;
margin: 20px 0;
.item {
font-weight: 600;
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
}
}
}
section.instructor-dashboard-content-2 {
......
......@@ -146,35 +146,59 @@ function goto( mode)
%if modeflag.get('Grades'):
%if offline_grade_log:
<p><font color='orange'>Pre-computed grades ${offline_grade_log} available: Use?
<input type='checkbox' name='use_offline_grades' value='${_("yes")}'></font> </p>
<p>
<span class="copy-warning">Pre-computed grades ${offline_grade_log} available: Use?
<input type='checkbox' name='use_offline_grades' value='${_("yes")}'>
</span>
</p>
%endif
<hr width="40%" style="align:left">
<h2>${_("Grade Downloads")}</h2>
% if disable_buttons:
<div class="msg msg-warning">
<div class="copy">
<p>
${_("Note: some of these buttons are known to time out for larger "
"courses. We have temporarily disabled those features for courses "
"with more than {max_enrollment} students. We are urgently working on "
"fixing this issue. Thank you for your patience as we continue "
"working to improve the platform!").format(
max_enrollment=settings.MITX_FEATURES['MAX_ENROLLMENT_INSTR_BUTTONS']
)}
</p>
</div>
</div>
% endif
<p>
<a href="${reverse('gradebook', kwargs=dict(course_id=course.id))}">${_("Gradebook")}</a>
<a href="${reverse('gradebook', kwargs=dict(course_id=course.id))}" class="${'is-disabled' if disable_buttons else ''}">${_("Gradebook")}</a>
</p>
<p>
<a href="${reverse('grade_summary', kwargs=dict(course_id=course.id))}">${_("Grade summary")}</a>
<a href="${reverse('grade_summary', kwargs=dict(course_id=course.id))}" class="${'is-disabled' if disable_buttons else ''}">${_("Grade summary")}</a>
</p>
<p>
<input type="submit" name="action" value="Dump list of enrolled students">
<input type="submit" name="action" value="Dump list of enrolled students" class="${'is-disabled' if disable_buttons else ''}">
</p>
<p>
<input type="submit" name="action" value="Dump Grades for all students in this course">
<input type="submit" name="action" value="Download CSV of all student grades for this course">
<input type="submit" name="action" value="Dump Grades for all students in this course" class="${'is-disabled' if disable_buttons else ''}">
<input type="submit" name="action" value="Download CSV of all student grades for this course" class="${'is-disabled' if disable_buttons else ''}">
</p>
<p>
<input type="submit" name="action" value="Dump all RAW grades for all students in this course">
<input type="submit" name="action" value="Download CSV of all RAW grades">
<input type="submit" name="action" value="Dump all RAW grades for all students in this course" class="${'is-disabled' if disable_buttons else ''}">
<input type="submit" name="action" value="Download CSV of all RAW grades" class="${'is-disabled' if disable_buttons else ''}">
</p>
<p>
<input type="submit" name="action" value="Download CSV of answer distributions">
<input type="submit" name="action" value="Dump description of graded assignments configuration">
<input type="submit" name="action" value="Download CSV of answer distributions" class="${'is-disabled' if disable_buttons else ''}">
<input type="submit" name="action" value="Dump description of graded assignments configuration" class="${'is-disabled' if disable_buttons else ''}">
</p>
<hr width="40%" style="align:left">
......@@ -188,7 +212,7 @@ function goto( mode)
<p>${_("The assignments defined for this course should match the ones stored in the gradebook, for this to work properly!")}</p>
<ul>
<li>${_("Gradebook name:")} <font color="green">${rg.get('name','None defined!')}</font>
<li>${_("Gradebook name:")} <span class="copy-confirm">${rg.get('name','None defined!')}</span>
<br/>
<br/>
<input type="submit" name="action" value="List assignments available in remote gradebook">
......@@ -369,9 +393,26 @@ function goto( mode)
%if modeflag.get('Enrollment'):
<hr width="40%" style="align:left">
<p>
<input type="submit" name="action" value="List enrolled students">
<input type="submit" name="action" value="List students who may enroll but may not have yet signed up">
<h2>${_("Enrollment Data")}</h2>
% if disable_buttons:
<div class="msg msg-warning">
<div class="copy">
<p>
${_("Note: some of these buttons are known to time out for larger "
"courses. We have temporarily disabled those features for courses "
"with more than {max_enrollment} students. We are urgently working on "
"fixing this issue. Thank you for your patience as we continue "
"working to improve the platform!").format(
max_enrollment=settings.MITX_FEATURES['MAX_ENROLLMENT_INSTR_BUTTONS']
)}
</p>
</div>
</div>
% endif
<input type="submit" name="action" value="List enrolled students" class="${'is-disabled' if disable_buttons else ''}">
<input type="submit" name="action" value="List students who may enroll but may not have yet signed up" class="${'is-disabled' if disable_buttons else ''}">
<hr width="40%" style="align:left">
%if settings.MITX_FEATURES.get('REMOTE_GRADEBOOK_URL','') and instructor_access:
......@@ -382,7 +423,7 @@ function goto( mode)
<p>${_("Pull enrollment from remote gradebook")}</p>
<ul>
<li>${_("Gradebook name:")} <font color="green">${rg.get('name','None defined!')}</font>
<li>${_("Gradebook name:")} <span class="copy-confirm">${rg.get('name','None defined!')}</span>
<li>${_("Section:")} <input type="text" name="gradebook_section" size=40 value="${rg.get('section','')}"></li>
</ul>
<input type="submit" name="action" value="List sections available in remote gradebook">
......@@ -392,7 +433,7 @@ function goto( mode)
<hr width="40%" style="align:left">
%endif
<h2>${_("Batch Enrollment")}</h2>
<p>${_("Enroll or un-enroll one or many students: enter emails, separated by new lines or commas;")}</p>
<textarea rows="6" cols="70" name="multiple_students"></textarea>
<p>
......
<%! from django.utils.translation import ugettext as _ %>
<%page args="section_data"/>
<input type="button" name="list-profiles" value="${_("List enrolled students with profile information")}" data-endpoint="${ section_data['get_students_features_url'] }" >
<input type="button" name="list-profiles" value="CSV" data-csv="true" class="csv" data-endpoint="${ section_data['get_students_features_url'] }" >
<h2>${_("Data Download")}</h2>
% if disable_buttons:
<div class="msg msg-warning">
<div class="copy">
<p>
${_("Note: some of these buttons are known to time out for larger "
"courses. We have temporarily disabled those features for courses "
"with more than {max_enrollment} students. We are urgently working on "
"fixing this issue. Thank you for your patience as we continue "
"working to improve the platform!").format(
max_enrollment=settings.MITX_FEATURES['MAX_ENROLLMENT_INSTR_BUTTONS']
)}
</p>
</div>
</div>
<br>
% endif
<input type="button" name="list-profiles" value="${_("List enrolled students with profile information")}" data-endpoint="${ section_data['get_students_features_url'] }" class="${'is-disabled' if disable_buttons else ''}">
<input type="button" name="list-profiles" value="CSV" data-csv="true" class="csv ${'is-disabled' if disable_buttons else ''}" data-endpoint="${ section_data['get_students_features_url'] }" >
<br>
## <input type="button" name="list-grades" value="Student grades">
## <input type="button" name="list-profiles" value="CSV" data-csv="true" class="csv">
......@@ -10,8 +29,7 @@
## <input type="button" name="list-answer-distributions" value="Answer distributions (x students got y points)">
## <br>
<input type="button" name="dump-gradeconf" value="${_("Grading Configuration")}" data-endpoint="${ section_data['get_grading_config_url'] }">
<input type="button" name="list-anon-ids" value="${_("Get Student Anonymized IDs CSV")}" data-csv="true" class="csv" data-endpoint="${ section_data['get_anon_ids_url'] }">
<input type="button" name="list-anon-ids" value="${_("Get Student Anonymized IDs CSV")}" data-csv="true" class="csv" data-endpoint="${ section_data['get_anon_ids_url'] }" class="${'is-disabled' if disable_buttons else ''}">
<div class="data-display">
<div class="data-display-text"></div>
......
......@@ -79,7 +79,7 @@
%if settings.MITX_FEATURES.get('ENABLE_INSTRUCTOR_BACKGROUND_TASKS') and section_data['access']['instructor']:
<div class="course-specific-container action-type-container">
<H2>${_('Course-specific grade adjustment')}</h2>
<h2>${_('Course-specific grade adjustment')}</h2>
<div class="request-response-error"></div>
<p>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment