Commit d8a857db by Julia Hansbrough Committed by Brian Wilson

Changed GET to POST and xmodule HTML editor call, section CSS

parent 867d3ba1
...@@ -89,3 +89,4 @@ Akshay Jagadeesh <akjags@gmail.com> ...@@ -89,3 +89,4 @@ Akshay Jagadeesh <akjags@gmail.com>
Nick Parlante <nick.parlante@cs.stanford.edu> Nick Parlante <nick.parlante@cs.stanford.edu>
Marko Seric <marko.seric@math.uzh.ch> Marko Seric <marko.seric@math.uzh.ch>
Felipe Montoya <felipe.montoya@edunext.co> Felipe Montoya <felipe.montoya@edunext.co>
Julia Hansbrough <julia@edx.org>
...@@ -5,10 +5,12 @@ These are notable changes in edx-platform. This is a rolling list of changes, ...@@ -5,10 +5,12 @@ 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 in roughly chronological order, most recent first. Add your entries at or near
the top. Include a label indicating the component affected. the top. Include a label indicating the component affected.
LMS: Fix issue with CourseMode expiration dates LMS: Fix issue with CourseMode expiration dates
LMS: Add PaidCourseRegistration mode, where payment is required before course registration. LMS: Ported bulk emailing to the beta instructor dashboard.
LMS: Add PaidCourseRegistration mode, where payment is required before course
registration.
LMS: Add split testing functionality for internal use. LMS: Add split testing functionality for internal use.
......
...@@ -53,7 +53,6 @@ class TestInstructorDashboardEmailView(ModuleStoreTestCase): ...@@ -53,7 +53,6 @@ class TestInstructorDashboardEmailView(ModuleStoreTestCase):
@patch.dict(settings.MITX_FEATURES, {'ENABLE_INSTRUCTOR_EMAIL': True}) @patch.dict(settings.MITX_FEATURES, {'ENABLE_INSTRUCTOR_EMAIL': True})
def test_email_flag_true(self): 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 # Assert that the URL for the email view is in the response
response = self.client.get(self.url) response = self.client.get(self.url)
self.assertTrue(self.email_link in response.content) self.assertTrue(self.email_link in response.content)
......
...@@ -106,6 +106,43 @@ def require_query_params(*args, **kwargs): ...@@ -106,6 +106,43 @@ def require_query_params(*args, **kwargs):
return wrapped return wrapped
return decorator 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): def require_level(level):
""" """
...@@ -749,19 +786,19 @@ def send_email(request, course_id): ...@@ -749,19 +786,19 @@ def send_email(request, course_id):
@ensure_csrf_cookie @ensure_csrf_cookie
@cache_control(no_cache=True, no_store=True, must_revalidate=True) @cache_control(no_cache=True, no_store=True, must_revalidate=True)
@require_level('staff') @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): def send_email(request, course_id):
""" """
Send an email to self, staff, or everyone involved in a course. 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 - 'send_to' specifies what group the email should be sent to
- 'subject' specifies email's subject - 'subject' specifies email's subject
- 'message' specifies email's content - 'message' specifies email's content
""" """
course = get_course_by_id(course_id) course = get_course_by_id(course_id)
send_to = request.GET.get("send_to") send_to = request.POST.get("send_to")
subject = request.GET.get("subject") subject = request.POST.get("subject")
message = request.GET.get("message") message = request.POST.get("message")
text_message = html_to_text(message) text_message = html_to_text(message)
email = CourseEmail( email = CourseEmail(
course_id=course_id, course_id=course_id,
......
...@@ -160,12 +160,15 @@ def _section_data_download(course_id): ...@@ -160,12 +160,15 @@ def _section_data_download(course_id):
def _section_send_email(course_id, access, course): def _section_send_email(course_id, access, course):
""" Provide data for the corresponding bulk email section """ """ Provide data for the corresponding bulk email section """
html_module = HtmlDescriptor(course.system, DictFieldData({'data': ''}), ScopeIds(None, None, None, None)) 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_data = {
'section_key': 'send_email', 'section_key': 'send_email',
'section_display_name': _('Email'), 'section_display_name': _('Email'),
'access': access, 'access': access,
'send_email': reverse('send_email',kwargs={'course_id': course_id}), '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 return section_data
......
...@@ -28,6 +28,7 @@ MITX_FEATURES['ENABLE_MANUAL_GIT_RELOAD'] = True ...@@ -28,6 +28,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_PSYCHOMETRICS'] = False # real-time psychometrics (eg item response theory analysis in instructor dashboard)
MITX_FEATURES['ENABLE_INSTRUCTOR_ANALYTICS'] = True MITX_FEATURES['ENABLE_INSTRUCTOR_ANALYTICS'] = True
MITX_FEATURES['ENABLE_SERVICE_STATUS'] = True MITX_FEATURES['ENABLE_SERVICE_STATUS'] = True
MITX_FEATURES['ENABLE_INSTRUCTOR_EMAIL'] = True
MITX_FEATURES['ENABLE_HINTER_INSTRUCTOR_VIEW'] = True MITX_FEATURES['ENABLE_HINTER_INSTRUCTOR_VIEW'] = True
MITX_FEATURES['ENABLE_INSTRUCTOR_BETA_DASHBOARD'] = True MITX_FEATURES['ENABLE_INSTRUCTOR_BETA_DASHBOARD'] = True
MITX_FEATURES['MULTIPLE_ENROLLMENT_ROLES'] = True MITX_FEATURES['MULTIPLE_ENROLLMENT_ROLES'] = True
......
...@@ -23,6 +23,8 @@ class SendEmail ...@@ -23,6 +23,8 @@ class SendEmail
@$btn_send.click => @$btn_send.click =>
success_message = gettext('Your email was successfully queued for sending.')
send_data = send_data =
action: 'send' action: 'send'
send_to: @$send_to.val() send_to: @$send_to.val()
...@@ -30,10 +32,11 @@ class SendEmail ...@@ -30,10 +32,11 @@ class SendEmail
message: @$emailEditor.save()['data'] message: @$emailEditor.save()['data']
$.ajax $.ajax
type: 'POST'
dataType: 'json' dataType: 'json'
url: @$btn_send.data 'endpoint' url: @$btn_send.data 'endpoint'
data: send_data 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.') error: std_ajax_err => @fail_with_error gettext('Error sending email.')
fail_with_error: (msg) -> fail_with_error: (msg) ->
......
...@@ -241,6 +241,60 @@ section.instructor-dashboard-content-2 { ...@@ -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 { .instructor-dashboard-wrapper-2 section.idash-section#membership {
$half_width: $baseline * 20; $half_width: $baseline * 20;
...@@ -538,3 +592,7 @@ section.instructor-dashboard-content-2 { ...@@ -538,3 +592,7 @@ section.instructor-dashboard-content-2 {
right: $baseline; right: $baseline;
} }
} }
input[name="subject"] {
width:600px;
}
...@@ -6,7 +6,10 @@ ...@@ -6,7 +6,10 @@
<script type="text/javascript" src="jsi18n/"></script> <script type="text/javascript" src="jsi18n/"></script>
<div class="vert-left send-email"> <div class="vert-left send-email">
<h2> ${_("Send Email")} </h2> <h2> ${_("Send Email")} </h2>
<label for="id_to">${_("Send to:")}</label> <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"> <select id="id_to" name="send_to">
<option value="myself">${_("Myself")}</option> <option value="myself">${_("Myself")}</option>
%if to_option == "staff": %if to_option == "staff":
...@@ -20,24 +23,27 @@ ...@@ -20,24 +23,27 @@
<option value="all">${_("All (students, staff and instructors)")}</option> <option value="all">${_("All (students, staff and instructors)")}</option>
%endif %endif
</select> </select>
</li>
<br/> <br/>
<label for="id_subject">${_("Subject: ")}</label> <li class="field">
<label for="id_subject">${_("Subject: ")}</label><br/>
<input type="text" id="id_subject" name="subject"> <input type="text" id="id_subject" name="subject">
<br/> </li>
<li class="field">
<label>Message:</label> <label>Message:</label>
<div class="email-editor"> <div class="email-editor">
${ section_data['editor'] } ${ section_data['editor'] }
</div> </div>
<input type="hidden" name="message" value=""> <input type="hidden" name="message" value="">
<br/> </li>
</ul>
<div class="submit-email-action"> <div class="submit-email-action">
${_("Please try not to email students more than once a day. Before sending your email, consider:")} ${_("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 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> <li class="item">${_("Have you sent the email to yourself first to make sure you're happy with how it's displayed?")}</li>
</ul> </ul>
</div> </div>
<input type="button" name="send" value="${_("Send")}" data-endpoint="${ section_data['send_email'] }" > <input type="button" name="send" value="${_("Send Email")}" data-endpoint="${ section_data['send_email'] }" >
<div class="request-response"></div>
<div class="request-response-error"></div> <div class="request-response-error"></div>
</div> </div>
\ No newline at end of file
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