Commit ca685028 by Sarina Canelake

Merge pull request #3020 from edx/sarina/LMS-2357

Finish i18n of beta instructor dashboard
parents c2866949 454da6fe
...@@ -511,17 +511,35 @@ def get_students_features(request, course_id, csv=False): # pylint: disable=W06 ...@@ -511,17 +511,35 @@ def get_students_features(request, course_id, csv=False): # pylint: disable=W06
TO DO accept requests for different attribute sets. TO DO accept requests for different attribute sets.
""" """
available_features = analytics.basic.AVAILABLE_FEATURES available_features = analytics.basic.AVAILABLE_FEATURES
query_features = ['username', 'name', 'email', 'language', 'location', 'year_of_birth', 'gender', query_features = [
'level_of_education', 'mailing_address', 'goals'] 'username', 'name', 'email', 'language', 'location', 'year_of_birth',
'gender', 'level_of_education', 'mailing_address', 'goals'
]
student_data = analytics.basic.enrolled_students_features(course_id, query_features) student_data = analytics.basic.enrolled_students_features(course_id, query_features)
# Scrape the query features for i18n - can't translate here because it breaks further queries
# and how the coffeescript works. The actual translation will be done in data_download.coffee
query_features_names = {
'username': _('Username'),
'name': _('Name'),
'email': _('Email'),
'language': _('Language'),
'location': _('Location'),
'year_of_birth': _('Birth Year'),
'gender': _('Gender'),
'level_of_education': _('Level of Education'),
'mailing_address': _('Mailing Address'),
'goals': _('Goals'),
}
if not csv: if not csv:
response_payload = { response_payload = {
'course_id': course_id, 'course_id': course_id,
'students': student_data, 'students': student_data,
'students_count': len(student_data), 'students_count': len(student_data),
'queried_features': query_features, 'queried_features': query_features,
'feature_names': query_features_names,
'available_features': available_features, 'available_features': available_features,
} }
return JsonResponse(response_payload) return JsonResponse(response_payload)
......
...@@ -34,7 +34,7 @@ class ProfileDistributionWidget ...@@ -34,7 +34,7 @@ class ProfileDistributionWidget
@reset_display() @reset_display()
@get_profile_distributions @feature, @get_profile_distributions @feature,
error: std_ajax_err => @show_error "Error fetching distribution." error: std_ajax_err => @show_error gettext("Error fetching distribution.")
success: (data) => success: (data) =>
feature_res = data.feature_results feature_res = data.feature_results
if feature_res.type is 'EASY_CHOICE' if feature_res.type is 'EASY_CHOICE'
...@@ -74,7 +74,7 @@ class ProfileDistributionWidget ...@@ -74,7 +74,7 @@ class ProfileDistributionWidget
] ]
else else
console.warn("unable to show distribution #{feature_res.type}") console.warn("unable to show distribution #{feature_res.type}")
@show_error 'Unavailable metric display.' @show_error gettext('Unavailable metric display.')
# fetch distribution data from server. # fetch distribution data from server.
# `handler` can be either a callback for success # `handler` can be either a callback for success
...@@ -110,9 +110,11 @@ class GradeDistributionDisplay ...@@ -110,9 +110,11 @@ class GradeDistributionDisplay
load: -> load: ->
@get_grade_distributions @get_grade_distributions
error: std_ajax_err => @show_error "Error fetching grade distributions." error: std_ajax_err => @show_error gettext("Error fetching grade distributions.")
success: (data) => success: (data) =>
@$container.find('.last-updated').text "Last Updated: #{data.time}" time_updated = gettext("Last Updated: <%= timestamp %>")
full_time_updated = _.template(time_updated, {timestamp: data.time})
@$container.find('.last-updated').text full_time_updated
# populate selector # populate selector
@$problem_selector.empty() @$problem_selector.empty()
...@@ -145,8 +147,10 @@ class GradeDistributionDisplay ...@@ -145,8 +147,10 @@ class GradeDistributionDisplay
total_students = _.reduce ([0].concat grade_info), total_students = _.reduce ([0].concat grade_info),
(accum, {grade, max_grade, num_students}) -> accum + num_students (accum, {grade, max_grade, num_students}) -> accum + num_students
msg = gettext("<%= num_students %> students scored.")
full_msg = _.template(msg, {num_students: total_students})
# show total students # show total students
@$container.find('.display-text').text "#{total_students} students scored." @$container.find('.display-text').text full_msg
# render to graph # render to graph
graph_placeholder = $ '<div/>', class: 'graph-placeholder' graph_placeholder = $ '<div/>', class: 'graph-placeholder'
......
...@@ -75,7 +75,7 @@ class DataDownload ...@@ -75,7 +75,7 @@ class DataDownload
forceFitColumns: true forceFitColumns: true
rowHeight: 35 rowHeight: 35
columns = ({id: feature, field: feature, name: feature} for feature in data.queried_features) columns = ({id: feature, field: feature, name: data.feature_names[feature]} for feature in data.queried_features)
grid_data = data.students grid_data = data.students
$table_placeholder = $ '<div/>', class: 'slickgrid' $table_placeholder = $ '<div/>', class: 'slickgrid'
......
...@@ -69,8 +69,8 @@ class AuthListWidget extends MemberListWidget ...@@ -69,8 +69,8 @@ class AuthListWidget extends MemberListWidget
super $container, super $container,
title: $container.data 'display-name' title: $container.data 'display-name'
info: $container.data 'info-text' info: $container.data 'info-text'
labels: ["Username", "Email", "Revoke access"] labels: [gettext("Username"), gettext("Email"), gettext("Revoke access")]
add_placeholder: "Enter username or email" add_placeholder: gettext("Enter username or email")
add_btn_label: $container.data 'add-button-label' add_btn_label: $container.data 'add-button-label'
add_handler: (input) => @add_handler input add_handler: (input) => @add_handler input
...@@ -116,7 +116,8 @@ class AuthListWidget extends MemberListWidget ...@@ -116,7 +116,8 @@ class AuthListWidget extends MemberListWidget
# if there are members, show the list # if there are members, show the list
# create revoke button and insert it into the row # create revoke button and insert it into the row
$revoke_btn = $ '<div class="revoke"><i class="icon-remove-sign"></i> Revoke access</div>', label_trans = gettext("Revoke access")
$revoke_btn = $ _.template('<div class="revoke"><i class="icon-remove-sign"></i> <%= label %></div>', {label: label_trans}),
class: 'revoke' class: 'revoke'
$revoke_btn.click => $revoke_btn.click =>
@modify_member_access member.email, 'revoke', (error) => @modify_member_access member.email, 'revoke', (error) =>
......
...@@ -30,21 +30,25 @@ class SendEmail ...@@ -30,21 +30,25 @@ class SendEmail
@$btn_send.click => @$btn_send.click =>
if @$subject.val() == "" if @$subject.val() == ""
alert gettext("Your message must have a subject.") alert gettext("Your message must have a subject.")
else if @$emailEditor.save()['data'] == "" else if @$emailEditor.save()['data'] == ""
alert gettext("Your message cannot be blank.") alert gettext("Your message cannot be blank.")
else else
success_message = gettext("Your email was successfully queued for sending.") success_message = gettext("Your email was successfully queued for sending.")
send_to = @$send_to.val().toLowerCase() send_to = @$send_to.val().toLowerCase()
if send_to == "myself" if send_to == "myself"
send_to = gettext("yourself") confirm_message = gettext("You are about to send an email titled '<%= subject %>' to yourself. Is this OK?")
else if send_to == "staff" else if send_to == "staff"
send_to = gettext("everyone who is staff or instructor on this course") confirm_message = gettext("You are about to send an email titled '<%= subject %>' to everyone who is staff or instructor on this course. Is this OK?")
else else
send_to = gettext("ALL (everyone who is enrolled in this course as student, staff, or instructor)") confirm_message = gettext("You are about to send an email titled '<%= subject %>' to ALL (everyone who is enrolled in this course as student, staff, or instructor). Is this OK?")
success_message = gettext("Your email was successfully queued for sending. Please note that for large classes, it may take up to an hour (or more, if other courses are simultaneously sending email) to send all emails.") success_message = gettext("Your email was successfully queued for sending. Please note that for large classes, it may take up to an hour (or more, if other courses are simultaneously sending email) to send all emails.")
subject = gettext(@$subject.val())
confirm_message = gettext("You are about to send an email titled \"#{subject}\" to #{send_to}. Is this OK?") subject = @$subject.val()
if confirm confirm_message full_confirm_message = _.template(confirm_message, {subject: subject})
if confirm full_confirm_message
send_data = send_data =
action: 'send' action: 'send'
...@@ -87,7 +91,7 @@ class SendEmail ...@@ -87,7 +91,7 @@ class SendEmail
console.warn msg console.warn msg
@$task_response.empty() @$task_response.empty()
@$request_response_error.empty() @$request_response_error.empty()
@$request_response_error.text gettext(msg) @$request_response_error.text msg
$(".msg-confirm").css({"display":"none"}) $(".msg-confirm").css({"display":"none"})
display_response: (data_from_server) -> display_response: (data_from_server) ->
......
...@@ -42,47 +42,74 @@ create_task_list_table = ($table_tasks, tasks_data) -> ...@@ -42,47 +42,74 @@ create_task_list_table = ($table_tasks, tasks_data) ->
columns = [ columns = [
id: 'task_type' id: 'task_type'
field: 'task_type' field: 'task_type'
name: 'Task Type' ###
Translators: a "Task" is a background process such as grading students or sending email
###
name: gettext('Task Type')
minWidth: 102 minWidth: 102
, ,
id: 'task_input' id: 'task_input'
field: 'task_input' field: 'task_input'
name: 'Task inputs' ###
Translators: a "Task" is a background process such as grading students or sending email
###
name: gettext('Task inputs')
minWidth: 150 minWidth: 150
, ,
id: 'task_id' id: 'task_id'
field: 'task_id' field: 'task_id'
name: 'Task ID' ###
Translators: a "Task" is a background process such as grading students or sending email
###
name: gettext('Task ID')
minWidth: 150 minWidth: 150
, ,
id: 'requester' id: 'requester'
field: 'requester' field: 'requester'
name: 'Requester' ###
Translators: a "Requester" is a username that requested a task such as sending email
###
name: gettext('Requester')
minWidth: 80 minWidth: 80
, ,
id: 'created' id: 'created'
field: 'created' field: 'created'
name: 'Submitted' ###
Translators: A timestamp of when a task (eg, sending email) was submitted appears after this
###
name: gettext('Submitted')
minWidth: 120 minWidth: 120
, ,
id: 'duration_sec' id: 'duration_sec'
field: 'duration_sec' field: 'duration_sec'
name: 'Duration (sec)' ###
Translators: The length of a task (eg, sending email) in seconds appears this
###
name: gettext('Duration (sec)')
minWidth: 80 minWidth: 80
, ,
id: 'task_state' id: 'task_state'
field: 'task_state' field: 'task_state'
name: 'State' ###
Translators: The state (eg, "In progress") of a task (eg, sending email) appears after this.
###
name: gettext('State')
minWidth: 80 minWidth: 80
, ,
id: 'status' id: 'status'
field: 'status' field: 'status'
name: 'Task Status' ###
Translators: a "Task" is a background process such as grading students or sending email
###
name: gettext('Task Status')
minWidth: 80 minWidth: 80
, ,
id: 'task_message' id: 'task_message'
field: 'task_message' field: 'task_message'
name: 'Task Progress' ###
Translators: a "Task" is a background process such as grading students or sending email
###
name: gettext('Task Progress')
minWidth: 120 minWidth: 120
] ]
......
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
${_("Note: Users must have an activated {platform_name} account before they can be enrolled as a beta tester.").format(platform_name=settings.PLATFORM_NAME)} ${_("Note: Users must have an activated {platform_name} account before they can be enrolled as a beta tester.").format(platform_name=settings.PLATFORM_NAME)}
</label> </label>
<textarea rows="6" cols="50" name="student-emails-for-beta" placeholder="${_("Email addresses")}" spellcheck="false"></textarea> <textarea rows="6" cols="50" name="student-emails-for-beta" placeholder="${_("Email Addresses")}" spellcheck="false"></textarea>
</p> </p>
<div class="enroll-option"> <div class="enroll-option">
...@@ -84,8 +84,8 @@ ...@@ -84,8 +84,8 @@
</div> </div>
<div> <div>
<input type="button" name="beta-testers" class="enrollment-button" value="${_("Add beta tester(s)")}" data-endpoint="${ section_data['modify_beta_testers_button_url'] }" data-action="add" > <input type="button" name="beta-testers" class="enrollment-button" value="${_("Add beta testers")}" data-endpoint="${ section_data['modify_beta_testers_button_url'] }" data-action="add" >
<input type="button" name="beta-testers" class="enrollment-button" value="${_("Remove beta tester(s)")}" data-endpoint="${ section_data['modify_beta_testers_button_url'] }" data-action="remove" > <input type="button" name="beta-testers" class="enrollment-button" value="${_("Remove beta testers")}" data-endpoint="${ section_data['modify_beta_testers_button_url'] }" data-action="remove" >
</div> </div>
<div class="request-response"></div> <div class="request-response"></div>
...@@ -95,12 +95,14 @@ ...@@ -95,12 +95,14 @@
</div> </div>
<div class="vert-right member-lists-management"> <div class="vert-right member-lists-management">
## Translators: an "Administration List" is a list, such as Course Staff, that users can be added to.
<h2> ${_("Administration List Management")} </h2> <h2> ${_("Administration List Management")} </h2>
<div class="request-response-error"></div> <div class="request-response-error"></div>
<div class="wrapper-member-select"> <div class="wrapper-member-select">
<label for="member-lists-selector">Select an Administrator Group:</label> ## Translators: an "Administrator Group" is a group, such as Course Staff, that users can be added to.
<label for="member-lists-selector">${_("Select an Administrator Group:")}</label>
<select id="member-lists-selector" class="member-lists-selector"> <select id="member-lists-selector" class="member-lists-selector">
<option> ${_("Getting available lists...")} </option> <option> ${_("Getting available lists...")} </option>
</select> </select>
...@@ -150,7 +152,7 @@ ...@@ -150,7 +152,7 @@
"privileges.")}" "privileges.")}"
data-list-endpoint="${ section_data['list_course_role_members_url'] }" data-list-endpoint="${ section_data['list_course_role_members_url'] }"
data-modify-endpoint="${ section_data['modify_access_url'] }" data-modify-endpoint="${ section_data['modify_access_url'] }"
data-add-button-label="Add ${_("Beta Tester")}" data-add-button-label="${_("Add Beta Tester")}"
></div> ></div>
<div class="auth-list-container" <div class="auth-list-container"
...@@ -162,7 +164,7 @@ ...@@ -162,7 +164,7 @@
"They CAN add/delete other moderators and their posts are marked as 'staff'.")}" "They CAN add/delete other moderators and their posts are marked as 'staff'.")}"
data-list-endpoint="${ section_data['list_forum_members_url'] }" data-list-endpoint="${ section_data['list_forum_members_url'] }"
data-modify-endpoint="${ section_data['update_forum_role_membership_url'] }" data-modify-endpoint="${ section_data['update_forum_role_membership_url'] }"
data-add-button-label="Add ${_("Discussion Admin")}" data-add-button-label="${_("Add Discussion Admin")}"
></div> ></div>
%endif %endif
...@@ -189,7 +191,7 @@ ...@@ -189,7 +191,7 @@
"Their posts are marked 'Community TA'.")}" "Their posts are marked 'Community TA'.")}"
data-list-endpoint="${ section_data['list_forum_members_url'] }" data-list-endpoint="${ section_data['list_forum_members_url'] }"
data-modify-endpoint="${ section_data['update_forum_role_membership_url'] }" data-modify-endpoint="${ section_data['update_forum_role_membership_url'] }"
data-add-button-label="Add ${_("Community TA")}" data-add-button-label="${_("Add Community TA")}"
></div> ></div>
%endif %endif
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
<span class="tip">${_("(Max 128 characters)")}</span> <span class="tip">${_("(Max 128 characters)")}</span>
</li> </li>
<li class="field"> <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>
......
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