Setting for observers to see student names in notifications
Test plan - As an observer (who is observing a student either through the observer role linked to a student or through an observer enrollment linked to a student enrollment - Verify that you can see the setting in user's notification settings - Verify that when you send a submission graded or submission grade changed notification (email, html email, twitter, text, summary) you get the student's name in the notification - Other notifications should be updated in the future, but will be on other commits Change-Id: Ia05b42b8d0a80e5aa41de2cc5151caa258142fda Reviewed-on: https://gerrit.instructure.com/167854 Tested-by: Jenkins Product-Review: Matthew Goodwin <mattg@instructure.com> Reviewed-by: Jeremy Stanley <jeremy@instructure.com> QA-Review: Jeremy Stanley <jeremy@instructure.com>
This commit is contained in:
parent
f10280169f
commit
a1ba84d88a
|
@ -69,6 +69,7 @@ export default class NotificationPreferences {
|
|||
this.channels = this.options.channels || []
|
||||
this.categories = this.options.categories || []
|
||||
this.policies = this.options.policies || []
|
||||
this.showObservedNames = this.options.show_observed_names
|
||||
|
||||
// Give each channel a 'name'
|
||||
this.channels.forEach((c) => {
|
||||
|
@ -172,6 +173,12 @@ export default class NotificationPreferences {
|
|||
channels: this.channels,
|
||||
eventGroups,
|
||||
buttonData: this.buttonData,
|
||||
showObservedNames: {
|
||||
available: this.showObservedNames != null,
|
||||
name: 'send_observed_names_in_notifications',
|
||||
on: this.showObservedNames,
|
||||
label: I18n.t('Show name of observed students in notifications.'),
|
||||
}
|
||||
}))
|
||||
|
||||
// Display Bootstrap-like popover tooltip on category names. Allow entire cell to trigger popup.
|
||||
|
@ -226,7 +233,7 @@ export default class NotificationPreferences {
|
|||
$notificationPrefs.find('.user-pref-check').on('change', (e) => {
|
||||
const check = $(e.currentTarget)
|
||||
const checkStatus = check.attr('checked') === 'checked'
|
||||
// Send user prefernce value to server
|
||||
// Send user preference value to server
|
||||
const data = {user: {}}
|
||||
data.user[check.attr('name')] = checkStatus
|
||||
this.$notificationSaveStatus.disableWhileLoading($.ajaxJSON(this.updateUrl, 'PUT', data, null, () =>
|
||||
|
|
|
@ -225,6 +225,7 @@ class ProfileController < ApplicationController
|
|||
@context = @user.profile
|
||||
@active_tab = 'notifications'
|
||||
|
||||
|
||||
# Get the list of Notification models (that are treated like categories) that make up the full list of Categories.
|
||||
full_category_list = Notification.dashboard_categories(@user)
|
||||
categories = full_category_list.map do |category|
|
||||
|
@ -242,6 +243,7 @@ class ProfileController < ApplicationController
|
|||
:policies => NotificationPolicy.setup_with_default_policies(@user, full_category_list).map { |p| notification_policy_json(p, @user, session).tap { |json| json[:communication_channel_id] = p.communication_channel_id } },
|
||||
:categories => categories,
|
||||
:update_url => communication_update_profile_path,
|
||||
:show_observed_names => @user.observer_enrollments.any? || @user.as_observer_observation_links.any? ? @user.send_observed_names_in_notifications? : nil
|
||||
},
|
||||
:READ_PRIVACY_INFO => @user.preferences[:read_notification_privacy_info],
|
||||
:ACCOUNT_PRIVACY_NOTICE => @domain_root_account.settings[:external_notification_warning]
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#
|
||||
# Copyright (C) 2018 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module Messages::SendStudentNamesHelper
|
||||
def send_student_names(asset, user)
|
||||
user != asset.user && user.try(:send_observed_names_in_notifications?)
|
||||
end
|
||||
end
|
|
@ -5,7 +5,7 @@
|
|||
<% define_content :subject do %>
|
||||
<%= t('assignment_due_date_changed', 'Assignment Due Date Changed: %{assignment_name}, %{course_name}', :assignment_name => asset.title, :course_name => asset.context.name) %>
|
||||
<% end %>
|
||||
|
||||
|
||||
<%= t('assignment_due_date_changed_sentence', 'The due date for the assignment, %{assignment_name}, for the course, %{course_name}, has changed to:', :assignment_name => asset.title, :course_name => asset.context.name) %>
|
||||
|
||||
<% if asset.due_at %>
|
||||
|
|
|
@ -8,7 +8,11 @@
|
|||
<%= t :subject, "Grade Changed: %{assignment}, %{context}", :assignment => asset.assignment.title, :context => asset.assignment.context.name %>
|
||||
<% end %>
|
||||
|
||||
<%= t :body, "The grade on your assignment, %{assignment_title} has been changed.", :assignment_title => asset.assignment.title %>
|
||||
<% if send_student_names(asset, user) %>
|
||||
<%= t "The grade on assignment %{assignment_title} has been changed for %{name}.", :assignment_title => asset.assignment.title, name: asset.user.name %>
|
||||
<% else %>
|
||||
<%= t :body, "The grade on your assignment %{assignment_title} has been changed.", :assignment_title => asset.assignment.title %>
|
||||
<% end %>
|
||||
|
||||
<%= t :regraded_date, "re-graded: %{date}", :date => (datetime_string(force_zone(asset.graded_at)) rescue t(:no_date_set, "No Date Set")) %>
|
||||
<% if user.try(:send_scores_in_emails?, asset.assignment.context.root_account) %>
|
||||
|
|
|
@ -12,7 +12,11 @@
|
|||
</a>
|
||||
<% end %>
|
||||
|
||||
<p><%= t :body, "The grade on your assignment, %{assignment_title} has been changed.", :assignment_title => asset.assignment.title %></p>
|
||||
<% if send_student_names(asset, user) %>
|
||||
<p><%= t "The grade on assignment %{assignment_title} has been changed for %{name}.", :assignment_title => asset.assignment.title, name: asset.user.name %></p>
|
||||
<% else %>
|
||||
<p><%= t :body, "The grade on your assignment %{assignment_title} has been changed.", :assignment_title => asset.assignment.title %></p>
|
||||
<% end %>
|
||||
|
||||
<p><%= t :regraded_date, "re-graded: %{date}", :date => (datetime_string(force_zone(asset.graded_at)) rescue t(:no_date_set, "No Date Set")) %></p>
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
<%= t :body_sms, "Your grade for %{title}, %{context} just changed.", :title => asset.assignment.title, :context => asset.assignment.context.name %>
|
||||
<% if send_student_names(asset, user) %>
|
||||
<%= t "The grade for %{title} in %{context} for %{name} just changed.", :title => asset.assignment.title, :context => asset.assignment.context.name, name: asset.user.name %>
|
||||
<% else %>
|
||||
<%= t :body_sms, "Your grade for %{title} in %{context} just changed.", :title => asset.assignment.title, :context => asset.assignment.context.name %>
|
||||
<% end %>
|
||||
|
||||
<%= t :regraded_date, "re-graded: %{date}", :date => (datetime_string(force_zone(asset.graded_at)) rescue t(:no_date_set, "No Date Set")) %>
|
||||
<% if asset.score && user.try(:send_scores_in_emails?, asset.assignment.context.root_account) %>
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
<%= t :subject, "Grade Changed: %{title}, %{context}", :title => asset.assignment.title, :context => asset.assignment.context.name %>
|
||||
<% end %>
|
||||
|
||||
<% if send_student_names(asset, user) %>
|
||||
<%= t "For %{name}", name: asset.user.name %>
|
||||
<% end %>
|
||||
<%= t :regraded_date, "re-graded: %{date}", :date => (datetime_string(force_zone(asset.graded_at)) rescue t(:no_date_set, "No Date Set")) %>
|
||||
<% if asset.score && user.try(:send_scores_in_emails?, asset.assignment.context.root_account) %>
|
||||
<%= t :score, "score: %{score} out of %{total}", :score => asset.score, :total => (asset.assignment.points_possible || t(:not_applicable, "N/A")) %>
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
<% define_content :link do -%>
|
||||
<%= polymorphic_url([asset.assignment.context, asset.assignment, :submission], id: asset.user) %>
|
||||
<% end -%>
|
||||
<%= t :tweet, "Canvas Alert - Grade Change: %{date}", :date => (datetime_string(force_zone(asset.graded_at)) rescue t(:no_date_set, "No Date Set")) %>
|
||||
<% if send_student_names(asset, user) %>
|
||||
<%= t "Canvas Alert - Grade Change: %{date} for %{name}", :date => (datetime_string(force_zone(asset.graded_at)) rescue t(:no_date_set, "No Date Set")), name: asset.user.name %>
|
||||
<% else %>
|
||||
<%= t :tweet, "Canvas Alert - Grade Change: %{date}", :date => (datetime_string(force_zone(asset.graded_at)) rescue t(:no_date_set, "No Date Set")) %>
|
||||
<% end %>
|
||||
|
||||
<% if asset.score -%>
|
||||
<%= t :score, "score: %{score} out of %{total}", :score => asset.score, :total => (asset.assignment.points_possible || t(:not_applicable, "N/A")) %>
|
||||
|
|
|
@ -8,7 +8,11 @@
|
|||
<%= t :subject, "Assignment Graded: %{assignment}, %{context}", :assignment => asset.assignment.title, :context => asset.assignment.context.name %>
|
||||
<% end %>
|
||||
|
||||
<%= t :body, "Your assignment, %{assignment}, has been graded.", :assignment => asset.assignment.title %>
|
||||
<% if send_student_names(asset, user) %>
|
||||
<%= t "%{assignment} has been graded for %{name}.", assignment: asset.assignment.title, name: asset.user.name %>
|
||||
<% else %>
|
||||
<%= t :body, "Your assignment %{assignment} has been graded.", :assignment => asset.assignment.title %>
|
||||
<% end %>
|
||||
|
||||
<%= t :graded_date, "graded: %{date}", :date => (datetime_string(force_zone(asset.graded_at)) rescue t(:no_date_set, "No Date Set")) %>
|
||||
<% if user.try(:send_scores_in_emails?, asset.assignment.context.root_account) %>
|
||||
|
|
|
@ -12,7 +12,11 @@
|
|||
</a>
|
||||
<% end %>
|
||||
|
||||
<p><%= t :body, "Your assignment, %{assignment}, has been graded.", :assignment => asset.assignment.title %></p>
|
||||
<% if send_student_names(asset, user) %>
|
||||
<p><%= t "%{assignment} has been graded for %{name}.", assignment: asset.assignment.title, name: asset.user.name %></p>
|
||||
<% else %>
|
||||
<p><%= t :body, "Your assignment %{assignment} has been graded.", :assignment => asset.assignment.title %></p>
|
||||
<% end %>
|
||||
|
||||
<p><%= t :graded_date, "graded: %{date}", :date => (datetime_string(force_zone(asset.graded_at)) rescue t(:no_date_set, "No Date Set")) %></p>
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
<% if send_student_names(asset, user) %>
|
||||
<%= t "%{assignment}, %{context} has been graded for %{name}.", :assignment => asset.assignment.title, :context => asset.assignment.context.name, name: asset.user.name %>
|
||||
<% else %>
|
||||
<%= t :sms_body, "%{assignment}, %{context} has been graded.", :assignment => asset.assignment.title, :context => asset.assignment.context.name %>
|
||||
<% end %>
|
||||
|
||||
<%= t :graded_date, "graded: %{date}", :date => (datetime_string(force_zone(asset.graded_at)) rescue t(:no_date_set, "No Date Set")) %>
|
||||
<% if asset.score && user.try(:send_scores_in_emails?, asset.assignment.context.root_account) %>
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
<%= t :subject, "Assignment Graded: %{assignment}, %{context}", :assignment => asset.assignment.title, :context => asset.assignment.context.name %>
|
||||
<% end %>
|
||||
|
||||
<% if send_student_names(asset, user) %>
|
||||
<%= t "For %{name}", name: asset.user.name %>
|
||||
<% end %>
|
||||
<%= t :graded_date, "graded: %{date}", :date => (datetime_string(force_zone(asset.graded_at)) rescue t(:no_date_set, "No Date Set")) %>
|
||||
<% if asset.score && user.try(:send_scores_in_emails?, asset.assignment.context.root_account) %>
|
||||
<%= t :score, "score: %{score} out of %{total}", :score => asset.score, :total => (asset.assignment.points_possible || t(:not_applicable, "N/A")) %>
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
<% define_content :link do -%>
|
||||
<%= polymorphic_url([asset.assignment.context, asset.assignment]) %>
|
||||
<% end -%>
|
||||
<%= t :tweet, "Canvas Alert - Graded: %{assignment}, %{context}", :assignment => asset.assignment.title, :context => asset.assignment.context.name %>
|
||||
<% if send_student_names(asset, user) %>
|
||||
<%= t "Canvas Alert - Graded: %{assignment}, %{context} for %{name}", :assignment => asset.assignment.title, :context => asset.assignment.context.name, name: user.asset.name %>
|
||||
<% else %>
|
||||
<%= t :tweet, "Canvas Alert - Graded: %{assignment}, %{context}", :assignment => asset.assignment.title, :context => asset.assignment.context.name %>
|
||||
<% end %>
|
||||
|
||||
<%= datetime_string(force_zone(asset.graded_at)) rescue t(:no_date_set, "No Date Set") %>
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ class Message < ActiveRecord::Base
|
|||
include HtmlTextHelper
|
||||
include Workflow
|
||||
include Messages::PeerReviewsHelper
|
||||
include Messages::SendStudentNamesHelper
|
||||
|
||||
extend TextHelper
|
||||
|
||||
|
|
|
@ -59,10 +59,10 @@ class NotificationPolicy < ActiveRecord::Base
|
|||
bool_val = (value == 'true')
|
||||
# save the preference as a symbol (convert from string)
|
||||
case key.to_sym
|
||||
when :send_scores_in_emails
|
||||
when :send_scores_in_emails, :send_observed_names_in_notifications
|
||||
# Only set if a root account and the root account allows the setting.
|
||||
if params[:root_account].settings[:allow_sending_scores_in_emails] != false
|
||||
user.preferences[:send_scores_in_emails] = bool_val
|
||||
user.preferences[key.to_sym] = bool_val
|
||||
end
|
||||
when :no_submission_comments_inbox
|
||||
user.preferences[:no_submission_comments_inbox] = bool_val
|
||||
|
|
|
@ -1460,6 +1460,10 @@ class User < ActiveRecord::Base
|
|||
preferences[:send_scores_in_emails] == true && root_account.settings[:allow_sending_scores_in_emails] != false
|
||||
end
|
||||
|
||||
def send_observed_names_in_notifications?
|
||||
preferences[:send_observed_names_in_notifications] == true
|
||||
end
|
||||
|
||||
def close_announcement(announcement)
|
||||
preferences[:closed_notifications] ||= []
|
||||
# serialize ids relative to the user
|
||||
|
|
|
@ -3,6 +3,17 @@
|
|||
<span><i class='{{icon}}' /> {{title}}</span>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{#if showObservedNames.available}}
|
||||
<div class="user-preference">
|
||||
<label class="checkbox" for="show-name-observers">
|
||||
{{checkbox showObservedNames.name
|
||||
id="show-name-observers"
|
||||
class="user-pref-check"
|
||||
checked=showObservedNames.on}}
|
||||
{{showObservedNames.label}}
|
||||
</label>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#each eventGroups}}
|
||||
<table cellspacing="0"
|
||||
|
|
|
@ -53,5 +53,16 @@ describe 'submission_grade_changed' do
|
|||
message = generate_message(:submission_grade_changed, :summary, asset, user: user)
|
||||
expect(message.body).not_to match(/score:/)
|
||||
end
|
||||
|
||||
it "should include the submission's submitter name if receiver is not the submitter and has the setting turned on" do
|
||||
observer = user_model
|
||||
message = generate_message(:submission_grade_changed, :summary, asset, user: observer)
|
||||
expect(message.body).not_to match("For #{@submission.user.name}")
|
||||
|
||||
observer.preferences[:send_observed_names_in_notifications] = true
|
||||
observer.save!
|
||||
message = generate_message(:submission_grade_changed, :summary, asset, user: observer)
|
||||
expect(message.body).to match("For #{@submission.user.name}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,4 +28,15 @@ describe "submission_graded" do
|
|||
let(:notification_name) { :submission_graded }
|
||||
|
||||
include_examples "a message"
|
||||
|
||||
it "should include the submission's submitter name if receiver is not the submitter and has the setting turned on" do
|
||||
observer = user_model
|
||||
message = generate_message(:submission_graded, :summary, asset, user: observer)
|
||||
expect(message.body).not_to match("For #{@submission.user.name}")
|
||||
|
||||
observer.preferences[:send_observed_names_in_notifications] = true
|
||||
observer.save!
|
||||
message = generate_message(:submission_graded, :summary, asset, user: observer)
|
||||
expect(message.body).to match("For #{@submission.user.name}")
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue