diff --git a/lms/djangoapps/instructor/views/api.py b/lms/djangoapps/instructor/views/api.py index 4021bedfb4..59496a9753 100644 --- a/lms/djangoapps/instructor/views/api.py +++ b/lms/djangoapps/instructor/views/api.py @@ -511,17 +511,35 @@ def get_students_features(request, course_id, csv=False): # pylint: disable=W06 TO DO accept requests for different attribute sets. """ available_features = analytics.basic.AVAILABLE_FEATURES - query_features = ['username', 'name', 'email', 'language', 'location', 'year_of_birth', 'gender', - 'level_of_education', 'mailing_address', 'goals'] + query_features = [ + '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) + # 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: response_payload = { 'course_id': course_id, 'students': student_data, 'students_count': len(student_data), 'queried_features': query_features, + 'feature_names': query_features_names, 'available_features': available_features, } return JsonResponse(response_payload) diff --git a/lms/static/coffee/src/instructor_dashboard/analytics.coffee b/lms/static/coffee/src/instructor_dashboard/analytics.coffee index 9955f8ee11..3736624540 100644 --- a/lms/static/coffee/src/instructor_dashboard/analytics.coffee +++ b/lms/static/coffee/src/instructor_dashboard/analytics.coffee @@ -34,7 +34,7 @@ class ProfileDistributionWidget @reset_display() @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) => feature_res = data.feature_results if feature_res.type is 'EASY_CHOICE' @@ -74,7 +74,7 @@ class ProfileDistributionWidget ] else 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. # `handler` can be either a callback for success @@ -110,9 +110,11 @@ class GradeDistributionDisplay load: -> @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) => - @$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 @$problem_selector.empty() @@ -145,8 +147,10 @@ class GradeDistributionDisplay total_students = _.reduce ([0].concat grade_info), (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 - @$container.find('.display-text').text "#{total_students} students scored." + @$container.find('.display-text').text full_msg # render to graph graph_placeholder = $ '
', class: 'graph-placeholder' diff --git a/lms/static/coffee/src/instructor_dashboard/data_download.coffee b/lms/static/coffee/src/instructor_dashboard/data_download.coffee index b8f89c5fe8..d2e0260e42 100644 --- a/lms/static/coffee/src/instructor_dashboard/data_download.coffee +++ b/lms/static/coffee/src/instructor_dashboard/data_download.coffee @@ -75,7 +75,7 @@ class DataDownload forceFitColumns: true 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 $table_placeholder = $ '
', class: 'slickgrid' diff --git a/lms/static/coffee/src/instructor_dashboard/membership.coffee b/lms/static/coffee/src/instructor_dashboard/membership.coffee index d66e4c5e11..a71043fccd 100644 --- a/lms/static/coffee/src/instructor_dashboard/membership.coffee +++ b/lms/static/coffee/src/instructor_dashboard/membership.coffee @@ -69,8 +69,8 @@ class AuthListWidget extends MemberListWidget super $container, title: $container.data 'display-name' info: $container.data 'info-text' - labels: ["Username", "Email", "Revoke access"] - add_placeholder: "Enter username or email" + labels: [gettext("Username"), gettext("Email"), gettext("Revoke access")] + add_placeholder: gettext("Enter username or email") add_btn_label: $container.data 'add-button-label' add_handler: (input) => @add_handler input @@ -116,7 +116,8 @@ class AuthListWidget extends MemberListWidget # if there are members, show the list # create revoke button and insert it into the row - $revoke_btn = $ '
Revoke access
', + label_trans = gettext("Revoke access") + $revoke_btn = $ _.template('
<%= label %>
', {label: label_trans}), class: 'revoke' $revoke_btn.click => @modify_member_access member.email, 'revoke', (error) => diff --git a/lms/static/coffee/src/instructor_dashboard/send_email.coffee b/lms/static/coffee/src/instructor_dashboard/send_email.coffee index edf6a07003..772dddad21 100644 --- a/lms/static/coffee/src/instructor_dashboard/send_email.coffee +++ b/lms/static/coffee/src/instructor_dashboard/send_email.coffee @@ -30,21 +30,25 @@ class SendEmail @$btn_send.click => if @$subject.val() == "" alert gettext("Your message must have a subject.") + else if @$emailEditor.save()['data'] == "" alert gettext("Your message cannot be blank.") + else success_message = gettext("Your email was successfully queued for sending.") send_to = @$send_to.val().toLowerCase() 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" - 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 - 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.") - subject = gettext(@$subject.val()) - confirm_message = gettext("You are about to send an email titled \"#{subject}\" to #{send_to}. Is this OK?") - if confirm confirm_message + + subject = @$subject.val() + full_confirm_message = _.template(confirm_message, {subject: subject}) + + if confirm full_confirm_message send_data = action: 'send' @@ -87,7 +91,7 @@ class SendEmail console.warn msg @$task_response.empty() @$request_response_error.empty() - @$request_response_error.text gettext(msg) + @$request_response_error.text msg $(".msg-confirm").css({"display":"none"}) display_response: (data_from_server) -> diff --git a/lms/static/coffee/src/instructor_dashboard/util.coffee b/lms/static/coffee/src/instructor_dashboard/util.coffee index 14a2f2b8ca..839472ef73 100644 --- a/lms/static/coffee/src/instructor_dashboard/util.coffee +++ b/lms/static/coffee/src/instructor_dashboard/util.coffee @@ -42,47 +42,74 @@ create_task_list_table = ($table_tasks, tasks_data) -> columns = [ id: '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 , id: '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 , id: '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 , id: 'requester' field: 'requester' - name: 'Requester' + ### + Translators: a "Requester" is a username that requested a task such as sending email + ### + name: gettext('Requester') minWidth: 80 , id: '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 , id: '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 , id: '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 , id: '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 , id: '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 ] diff --git a/lms/templates/instructor/instructor_dashboard_2/membership.html b/lms/templates/instructor/instructor_dashboard_2/membership.html index 3e4002917c..17b3acd010 100644 --- a/lms/templates/instructor/instructor_dashboard_2/membership.html +++ b/lms/templates/instructor/instructor_dashboard_2/membership.html @@ -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)} - +

@@ -84,8 +84,8 @@
- - + +
@@ -95,12 +95,14 @@
+ ## Translators: an "Administration List" is a list, such as Course Staff, that users can be added to.

${_("Administration List Management")}

- + ## Translators: an "Administrator Group" is a group, such as Course Staff, that users can be added to. + @@ -150,7 +152,7 @@ "privileges.")}" data-list-endpoint="${ section_data['list_course_role_members_url'] }" data-modify-endpoint="${ section_data['modify_access_url'] }" - data-add-button-label="Add ${_("Beta Tester")}" + data-add-button-label="${_("Add Beta Tester")}" >
%endif @@ -189,7 +191,7 @@ "Their posts are marked 'Community TA'.")}" data-list-endpoint="${ section_data['list_forum_members_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")}" >
%endif diff --git a/lms/templates/instructor/instructor_dashboard_2/send_email.html b/lms/templates/instructor/instructor_dashboard_2/send_email.html index cb8afb88a1..2e157af047 100644 --- a/lms/templates/instructor/instructor_dashboard_2/send_email.html +++ b/lms/templates/instructor/instructor_dashboard_2/send_email.html @@ -32,7 +32,7 @@ ${_("(Max 128 characters)")}
  • - +