250 lines
8.0 KiB
JavaScript
250 lines
8.0 KiB
JavaScript
/*
|
|
* Copyright (C) 2011 - 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/>.
|
|
*/
|
|
|
|
import I18n from 'i18n!public_message_students'
|
|
import $ from 'jquery'
|
|
import natcompare from 'compiled/util/natcompare'
|
|
import numberHelper from 'jsx/shared/helpers/numberHelper'
|
|
import './jquery.instructure_forms' /* formSubmit */
|
|
import 'jqueryui/dialog'
|
|
import './jquery.instructure_misc_plugins' /* showIf */
|
|
|
|
let currentSettings = {}
|
|
|
|
function checkSendable() {
|
|
const $message_students_dialog = messageStudentsDialog()
|
|
disableSend(
|
|
$message_students_dialog.find('#body').val().length == 0 ||
|
|
$message_students_dialog.find('.student:not(.blank):visible').length == 0
|
|
)
|
|
}
|
|
|
|
/* global messageStudents */
|
|
window.messageStudents = function(settings) {
|
|
const $message_students_dialog = messageStudentsDialog()
|
|
currentSettings = settings
|
|
$message_students_dialog.find('.message_types').empty()
|
|
for (let idx = 0, l = settings.options.length; idx < l; idx++) {
|
|
const $option = $('<option/>')
|
|
const option = settings.options[idx]
|
|
$option.val(idx).text(option.text)
|
|
$message_students_dialog.find('.message_types').append($option)
|
|
}
|
|
|
|
const title = settings.title,
|
|
$li = $message_students_dialog.find('ul li.blank:first'),
|
|
$ul = $message_students_dialog.find('ul'),
|
|
students_hash = {}
|
|
|
|
$message_students_dialog.find('ul li:not(.blank)').remove()
|
|
|
|
const sortedStudents = settings.students.slice()
|
|
sortedStudents.sort(natcompare.byKey('sortableName'))
|
|
|
|
for (let i = 0; i < sortedStudents.length; i++) {
|
|
const student = sortedStudents[i]
|
|
const $student = $li.clone(true).removeClass('blank')
|
|
|
|
$student.find('.name').text(student.name)
|
|
$student.find('.score').text(student.score)
|
|
const remove_text = I18n.t('Remove %{student} from recipients', {
|
|
student: student.name
|
|
})
|
|
const $remove_button = $student.find('.remove-button')
|
|
$remove_button
|
|
.attr('title', remove_text)
|
|
.append($("<span class='screenreader-only'></span>").text(remove_text))
|
|
$remove_button.click(function(event) {
|
|
event.preventDefault()
|
|
// hide the selected student
|
|
const $s = $(this).closest('li')
|
|
$s.hide('fast', checkSendable)
|
|
// focus the next visible student, or the subject field if that was the last one in the list
|
|
const $next = $s.nextAll(':visible:first')
|
|
if ($next.length) {
|
|
$('button', $next).focus()
|
|
} else {
|
|
$('#message_assignment_recipients #subject').focus()
|
|
}
|
|
})
|
|
|
|
$student.data('id', student.id)
|
|
$student.user_data = student
|
|
|
|
$ul.append($student.show())
|
|
students_hash[student.id] = $student
|
|
}
|
|
|
|
$ul.show()
|
|
|
|
const dialogTitle = I18n.t('Message Students for %{course_name}', {
|
|
course_name: title
|
|
})
|
|
|
|
$message_students_dialog.data('students_hash', students_hash),
|
|
$message_students_dialog.find('.asset_title').text(title)
|
|
$message_students_dialog.find('.out_of').showIf(settings.points_possible != null)
|
|
$message_students_dialog.find('.send_button').text(I18n.t('send_message', 'Send Message'))
|
|
$message_students_dialog.find('.points_possible').text(I18n.n(settings.points_possible))
|
|
$message_students_dialog.find('[name=context_code]').val(settings.context_code)
|
|
|
|
$message_students_dialog.find('textarea').val('')
|
|
$message_students_dialog.find('select')[0].selectedIndex = 0
|
|
$message_students_dialog.find('select').change()
|
|
$message_students_dialog
|
|
.dialog({
|
|
width: 600,
|
|
modal: true,
|
|
open: (_event, _ui) => {
|
|
$message_students_dialog
|
|
.closest('.ui-dialog')
|
|
.attr('role', 'dialog')
|
|
.attr('aria-label', dialogTitle)
|
|
},
|
|
close: (_event, _ui) => {
|
|
$message_students_dialog
|
|
.closest('.ui-dialog')
|
|
.removeAttr('role')
|
|
.removeAttr('aria-label')
|
|
}
|
|
})
|
|
.dialog('open')
|
|
.dialog('option', 'title', dialogTitle)
|
|
.on('dialogclose', settings.onClose)
|
|
}
|
|
|
|
$(document).ready(() => {
|
|
const $message_students_dialog = messageStudentsDialog()
|
|
$message_students_dialog.find('button').click(e => {
|
|
const btn = $(e.target)
|
|
if (btn.hasClass('disabled')) {
|
|
e.preventDefault()
|
|
e.stopPropagation()
|
|
}
|
|
})
|
|
$('#message_assignment_recipients').formSubmit({
|
|
processData(data) {
|
|
const ids = []
|
|
$(this)
|
|
.find('.student:visible')
|
|
.each(function() {
|
|
ids.push($(this).data('id'))
|
|
})
|
|
if (ids.length == 0) {
|
|
return false
|
|
}
|
|
data.recipients = ids.join(',')
|
|
return data
|
|
},
|
|
beforeSubmit(data) {
|
|
disableButtons(true)
|
|
$(this)
|
|
.find('.send_button')
|
|
.text(I18n.t('Sending Message...'))
|
|
},
|
|
success(data) {
|
|
$.flashMessage(I18n.t('Message sent!'))
|
|
disableButtons(false)
|
|
$(this)
|
|
.find('.send_button')
|
|
.text(I18n.t('Send Message'))
|
|
$('#message_students_dialog').dialog('close')
|
|
},
|
|
error(data) {
|
|
disableButtons(false)
|
|
$(this)
|
|
.find('.send_button')
|
|
.text(I18n.t('Sending Message Failed, please try again'))
|
|
}
|
|
})
|
|
|
|
const showStudentsMessageSentTo = function() {
|
|
const optionIdx = parseInt($message_students_dialog.find('select').val(), 10) || 0
|
|
const option = currentSettings.options[optionIdx]
|
|
const studentsHash = $message_students_dialog.data('students_hash')
|
|
let cutoff = numberHelper.parse($message_students_dialog.find('.cutoff_score').val())
|
|
if (isNaN(cutoff)) {
|
|
cutoff = null
|
|
}
|
|
|
|
const studentElements = Object.values(studentsHash)
|
|
let selectedStudentIds = []
|
|
if (studentsHash) {
|
|
if (option && option.callback) {
|
|
selectedStudentIds = option.callback.call(window.messageStudents, cutoff, studentElements)
|
|
} else if (currentSettings.callback) {
|
|
selectedStudentIds = currentSettings.callback.call(
|
|
window.messageStudents,
|
|
option.text,
|
|
cutoff,
|
|
studentElements
|
|
)
|
|
}
|
|
}
|
|
|
|
if (currentSettings.subjectCallback) {
|
|
$message_students_dialog
|
|
.find('[name=subject]')
|
|
.val(currentSettings.subjectCallback(option.text, cutoff))
|
|
}
|
|
$message_students_dialog.find('.cutoff_holder').showIf(option.cutoff)
|
|
|
|
$message_students_dialog
|
|
.find('.student_list')
|
|
.toggleClass('show_score', !!(option.cutoff || option.score))
|
|
disableButtons(selectedStudentIds.length === 0)
|
|
|
|
const selectedIdSet = new Set(selectedStudentIds)
|
|
Object.entries(studentsHash).forEach(([studentId, studentElement]) => {
|
|
studentElement.showIf(selectedIdSet.has(studentId))
|
|
})
|
|
}
|
|
|
|
const closeDialog = function() {
|
|
$message_students_dialog.dialog('close')
|
|
}
|
|
|
|
$message_students_dialog.find('.cancel_button').click(closeDialog)
|
|
$message_students_dialog
|
|
.find('select')
|
|
.change(showStudentsMessageSentTo)
|
|
.change(checkSendable)
|
|
$message_students_dialog
|
|
.find('.cutoff_score')
|
|
.bind('change blur keyup', showStudentsMessageSentTo)
|
|
.bind('change blur keyup', checkSendable)
|
|
$message_students_dialog.find('#body').bind('change blur keyup', checkSendable)
|
|
})
|
|
|
|
function disableButtons(disabled, buttons) {
|
|
if (buttons == null) {
|
|
buttons = messageStudentsDialog().find('button')
|
|
}
|
|
buttons.toggleClass('disabled', disabled).attr('aria-disabled', disabled)
|
|
}
|
|
|
|
function disableSend(disabled) {
|
|
disableButtons(disabled, messageStudentsDialog().find('.send_button'))
|
|
}
|
|
|
|
function messageStudentsDialog() {
|
|
return $('#message_students_dialog')
|
|
}
|
|
|
|
export default messageStudents
|