Changed GET to POST and xmodule HTML editor call, section CSS
This commit is contained in:
1
AUTHORS
1
AUTHORS
@@ -89,3 +89,4 @@ Akshay Jagadeesh <akjags@gmail.com>
|
||||
Nick Parlante <nick.parlante@cs.stanford.edu>
|
||||
Marko Seric <marko.seric@math.uzh.ch>
|
||||
Felipe Montoya <felipe.montoya@edunext.co>
|
||||
Julia Hansbrough <julia@edx.org>
|
||||
|
||||
@@ -7,6 +7,8 @@ the top. Include a label indicating the component affected.
|
||||
|
||||
LMS: Disable data download buttons on the instructor dashboard for large courses
|
||||
|
||||
LMS: Ported bulk emailing to the beta instructor dashboard.
|
||||
|
||||
LMS: Refactor and clean student dashboard templates.
|
||||
|
||||
LMS: Fix issue with CourseMode expiration dates
|
||||
|
||||
@@ -53,7 +53,6 @@ class TestInstructorDashboardEmailView(ModuleStoreTestCase):
|
||||
|
||||
@patch.dict(settings.MITX_FEATURES, {'ENABLE_INSTRUCTOR_EMAIL': True})
|
||||
def test_email_flag_true(self):
|
||||
from nose.tools import set_trace; set_trace()
|
||||
# Assert that the URL for the email view is in the response
|
||||
response = self.client.get(self.url)
|
||||
self.assertTrue(self.email_link in response.content)
|
||||
|
||||
@@ -106,6 +106,43 @@ def require_query_params(*args, **kwargs):
|
||||
return wrapped
|
||||
return decorator
|
||||
|
||||
def require_post_params(*args, **kwargs):
|
||||
"""
|
||||
Checks for required paremters or renders a 400 error.
|
||||
(decorator with arguments)
|
||||
|
||||
`args` is a *list of required GET parameter names.
|
||||
`kwargs` is a **dict of required GET parameter names
|
||||
to string explanations of the parameter
|
||||
"""
|
||||
required_params = []
|
||||
required_params += [(arg, None) for arg in args]
|
||||
required_params += [(key, kwargs[key]) for key in kwargs]
|
||||
# required_params = e.g. [('action', 'enroll or unenroll'), ['emails', None]]
|
||||
|
||||
def decorator(func): # pylint: disable=C0111
|
||||
def wrapped(*args, **kwargs): # pylint: disable=C0111
|
||||
request = args[0]
|
||||
|
||||
error_response_data = {
|
||||
'error': 'Missing required query parameter(s)',
|
||||
'parameters': [],
|
||||
'info': {},
|
||||
}
|
||||
|
||||
for (param, extra) in required_params:
|
||||
default = object()
|
||||
if request.POST.get(param, default) == default:
|
||||
error_response_data['parameters'] += [param]
|
||||
error_response_data['info'][param] = extra
|
||||
|
||||
if len(error_response_data['parameters']) > 0:
|
||||
return JsonResponse(error_response_data, status=400)
|
||||
else:
|
||||
return func(*args, **kwargs)
|
||||
return wrapped
|
||||
return decorator
|
||||
|
||||
|
||||
def require_level(level):
|
||||
"""
|
||||
@@ -749,19 +786,19 @@ def send_email(request, course_id):
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
@require_query_params(send_to="sending to whom", subject="subject line", message="message text")
|
||||
@require_post_params(send_to="sending to whom", subject="subject line", message="message text")
|
||||
def send_email(request, course_id):
|
||||
"""
|
||||
Send an email to self, staff, or everyone involved in a course.
|
||||
Query Paramaters:
|
||||
Query Parameters:
|
||||
- 'send_to' specifies what group the email should be sent to
|
||||
- 'subject' specifies email's subject
|
||||
- 'message' specifies email's content
|
||||
"""
|
||||
course = get_course_by_id(course_id)
|
||||
send_to = request.GET.get("send_to")
|
||||
subject = request.GET.get("subject")
|
||||
message = request.GET.get("message")
|
||||
send_to = request.POST.get("send_to")
|
||||
subject = request.POST.get("subject")
|
||||
message = request.POST.get("message")
|
||||
text_message = html_to_text(message)
|
||||
email = CourseEmail(
|
||||
course_id=course_id,
|
||||
|
||||
@@ -138,6 +138,7 @@ def _section_student_admin(course_id, access):
|
||||
'section_display_name': _('Student Admin'),
|
||||
'access': access,
|
||||
'get_student_progress_url_url': reverse('get_student_progress_url', kwargs={'course_id': course_id}),
|
||||
'enrollment_url': reverse('students_update_enrollment', kwargs={'course_id': course_id}),
|
||||
'reset_student_attempts_url': reverse('reset_student_attempts', kwargs={'course_id': course_id}),
|
||||
'rescore_problem_url': reverse('rescore_problem', kwargs={'course_id': course_id}),
|
||||
'list_instructor_tasks_url': reverse('list_instructor_tasks', kwargs={'course_id': course_id}),
|
||||
@@ -160,12 +161,15 @@ def _section_data_download(course_id):
|
||||
def _section_send_email(course_id, access, course):
|
||||
""" Provide data for the corresponding bulk email section """
|
||||
html_module = HtmlDescriptor(course.system, DictFieldData({'data': ''}), ScopeIds(None, None, None, None))
|
||||
fragment = course.system.render(html_module, None, 'studio_view')
|
||||
fragment = wrap_xmodule('xmodule_edit.html', html_module, 'studio_view', fragment, None)
|
||||
email_editor = fragment.content
|
||||
section_data = {
|
||||
'section_key': 'send_email',
|
||||
'section_display_name': _('Email'),
|
||||
'access': access,
|
||||
'send_email': reverse('send_email',kwargs={'course_id': course_id}),
|
||||
'editor': wrap_xmodule(html_module.get_html, html_module, 'xmodule_edit.html')()
|
||||
'editor': email_editor
|
||||
}
|
||||
return section_data
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ MITX_FEATURES['ENABLE_MANUAL_GIT_RELOAD'] = True
|
||||
MITX_FEATURES['ENABLE_PSYCHOMETRICS'] = False # real-time psychometrics (eg item response theory analysis in instructor dashboard)
|
||||
MITX_FEATURES['ENABLE_INSTRUCTOR_ANALYTICS'] = True
|
||||
MITX_FEATURES['ENABLE_SERVICE_STATUS'] = True
|
||||
MITX_FEATURES['ENABLE_INSTRUCTOR_EMAIL'] = True
|
||||
MITX_FEATURES['ENABLE_HINTER_INSTRUCTOR_VIEW'] = True
|
||||
MITX_FEATURES['ENABLE_INSTRUCTOR_BETA_DASHBOARD'] = True
|
||||
MITX_FEATURES['MULTIPLE_ENROLLMENT_ROLES'] = True
|
||||
|
||||
@@ -22,6 +22,8 @@ class SendEmail
|
||||
# attach click handlers
|
||||
|
||||
@$btn_send.click =>
|
||||
|
||||
success_message = gettext('Your email was successfully queued for sending.')
|
||||
|
||||
send_data =
|
||||
action: 'send'
|
||||
@@ -30,10 +32,11 @@ class SendEmail
|
||||
message: @$emailEditor.save()['data']
|
||||
|
||||
$.ajax
|
||||
type: 'POST'
|
||||
dataType: 'json'
|
||||
url: @$btn_send.data 'endpoint'
|
||||
data: send_data
|
||||
success: (data) => @display_response gettext('Your email was successfully queued for sending.')
|
||||
success: (data) => @display_response ("<div class=\"msg msg-confirm\"><p class=\"copy\">" + success_message + "</p></div>")
|
||||
error: std_ajax_err => @fail_with_error gettext('Error sending email.')
|
||||
|
||||
fail_with_error: (msg) ->
|
||||
|
||||
@@ -241,6 +241,60 @@ section.instructor-dashboard-content-2 {
|
||||
}
|
||||
}
|
||||
|
||||
.instructor-dashboard-wrapper-2 section.idash-section#send_email {
|
||||
// form fields
|
||||
.list-fields {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
.field {
|
||||
margin-bottom: 20px;
|
||||
padding: 0;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// system feedback - messages
|
||||
.msg {
|
||||
|
||||
|
||||
.copy {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.msg-confirm {
|
||||
background: tint(green,90%);
|
||||
|
||||
.copy {
|
||||
color: green;
|
||||
}
|
||||
}
|
||||
|
||||
.list-advice {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 20px 0;
|
||||
|
||||
.item {
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.msg .copy {
|
||||
font-weight: 600; }
|
||||
.msg-confirm {
|
||||
background: #e5f2e5; }
|
||||
}
|
||||
|
||||
|
||||
.instructor-dashboard-wrapper-2 section.idash-section#membership {
|
||||
$half_width: $baseline * 20;
|
||||
@@ -538,3 +592,7 @@ section.instructor-dashboard-content-2 {
|
||||
right: $baseline;
|
||||
}
|
||||
}
|
||||
|
||||
input[name="subject"] {
|
||||
width:600px;
|
||||
}
|
||||
|
||||
@@ -6,38 +6,44 @@
|
||||
<script type="text/javascript" src="jsi18n/"></script>
|
||||
<div class="vert-left send-email">
|
||||
<h2> ${_("Send Email")} </h2>
|
||||
<label for="id_to">${_("Send to:")}</label>
|
||||
<select id="id_to" name="send_to">
|
||||
<option value="myself">${_("Myself")}</option>
|
||||
%if to_option == "staff":
|
||||
<option value="staff" selected="selected">${_("Staff and instructors")}</option>
|
||||
%else:
|
||||
<option value="staff">${_("Staff and instructors")}</option>
|
||||
%endif
|
||||
%if to_option == "all":
|
||||
<option value="all" selected="selected">${_("All (students, staff and instructors)")}</option>
|
||||
%else:
|
||||
<div class="request-response msg msg-confirm"></div>
|
||||
<ul class="list-fields">
|
||||
<li class="field">
|
||||
<label for="id_to">${_("Send to:")}</label><br/>
|
||||
<select id="id_to" name="send_to">
|
||||
<option value="myself">${_("Myself")}</option>
|
||||
%if to_option == "staff":
|
||||
<option value="staff" selected="selected">${_("Staff and instructors")}</option>
|
||||
%else:
|
||||
<option value="staff">${_("Staff and instructors")}</option>
|
||||
%endif
|
||||
%if to_option == "all":
|
||||
<option value="all" selected="selected">${_("All (students, staff and instructors)")}</option>
|
||||
%else:
|
||||
<option value="all">${_("All (students, staff and instructors)")}</option>
|
||||
%endif
|
||||
</select>
|
||||
<br/>
|
||||
<label for="id_subject">${_("Subject: ")}</label>
|
||||
<input type="text" id="id_subject" name="subject">
|
||||
<br/>
|
||||
<label>Message:</label>
|
||||
<div class="email-editor">
|
||||
${ section_data['editor'] }
|
||||
</div>
|
||||
<input type="hidden" name="message" value="">
|
||||
%endif
|
||||
</select>
|
||||
</li>
|
||||
<br/>
|
||||
<li class="field">
|
||||
<label for="id_subject">${_("Subject: ")}</label><br/>
|
||||
<input type="text" id="id_subject" name="subject">
|
||||
</li>
|
||||
<li class="field">
|
||||
<label>Message:</label>
|
||||
<div class="email-editor">
|
||||
${ section_data['editor'] }
|
||||
</div>
|
||||
<input type="hidden" name="message" value="">
|
||||
</li>
|
||||
</ul>
|
||||
<div class="submit-email-action">
|
||||
${_("Please try not to email students more than once a day. Before sending your email, consider:")}
|
||||
<ul>
|
||||
<ul class="list-advice">
|
||||
<li class="item">${_("Have you read over the email to make sure it says everything you want to say?")}</li>
|
||||
<li class="item">${_("Have you sent the email to yourself first to make sure you're happy with how it's displayed?")}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="button" name="send" value="${_("Send")}" data-endpoint="${ section_data['send_email'] }" >
|
||||
<div class="request-response"></div>
|
||||
<input type="button" name="send" value="${_("Send Email")}" data-endpoint="${ section_data['send_email'] }" >
|
||||
<div class="request-response-error"></div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user