461 lines
20 KiB
JavaScript
461 lines
20 KiB
JavaScript
/**
|
|
* Copyright (C) 2011 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/>.
|
|
*/
|
|
define([
|
|
'i18n!course_settings',
|
|
'jquery' /* $ */,
|
|
'underscore',
|
|
'jquery.ajaxJSON' /* ajaxJSON */,
|
|
'jquery.instructure_date_and_time' /* parseFromISO, date_field */,
|
|
'jquery.instructure_forms' /* formSubmit, fillFormData, getFormData, formErrors */,
|
|
'jqueryui/dialog',
|
|
'compiled/jquery/fixDialogButtons' /* fix dialog formatting */,
|
|
'jquery.instructure_misc_helpers' /* scrollSidebar */,
|
|
'jquery.instructure_misc_plugins' /* confirmDelete, fragmentChange, showIf */,
|
|
'jquery.keycodes' /* keycodes */,
|
|
'jquery.loadingImg' /* loadingImage */,
|
|
'compiled/jquery.rails_flash_notifications',
|
|
'jquery.templateData' /* fillTemplateData, getTemplateData */,
|
|
'link_enrollment' /* link_enrollment */,
|
|
'vendor/jquery.ba-tinypubsub' /* /\.publish/ */,
|
|
'vendor/jquery.scrollTo' /* /\.scrollTo/ */,
|
|
'jqueryui/autocomplete' /* /\.autocomplete/ */,
|
|
'jqueryui/sortable' /* /\.sortable/ */,
|
|
'jqueryui/tabs' /* /\.tabs/ */
|
|
], function(I18n, $, _) {
|
|
|
|
var GradePublishing = {
|
|
status: null,
|
|
checkup: function() {
|
|
$.ajaxJSON($("#publish_to_sis_form").attr('action'), 'GET', {}, function(data) {
|
|
if (!data.hasOwnProperty("sis_publish_overall_status")) return;
|
|
GradePublishing.status = data.sis_publish_overall_status;
|
|
GradePublishing.update(data.hasOwnProperty("sis_publish_statuses") ? data.sis_publish_statuses : {});
|
|
});
|
|
},
|
|
update: function(messages, requestInProgress) {
|
|
var $publish_grades_link = $("#publish_grades_link"),
|
|
$publish_grades_error = $("#publish_grades_error");
|
|
if (GradePublishing.status == 'published') {
|
|
$publish_grades_error.hide();
|
|
$publish_grades_link.html(I18n.t('links.republish', "Republish grades to SIS"));
|
|
$publish_grades_link.removeClass("disabled");
|
|
} else if (GradePublishing.status == 'publishing' || GradePublishing.status == 'pending') {
|
|
$publish_grades_error.hide();
|
|
$publish_grades_link.html(I18n.t('links.publishing', "Publishing grades to SIS..."));
|
|
if (!requestInProgress) {
|
|
setTimeout(GradePublishing.checkup, 5000);
|
|
}
|
|
$publish_grades_link.addClass("disabled");
|
|
} else if (GradePublishing.status == 'unpublished') {
|
|
$publish_grades_error.hide();
|
|
$publish_grades_link.html(I18n.t('links.publish', "Publish grades to SIS"));
|
|
$publish_grades_link.removeClass("disabled");
|
|
} else {
|
|
$publish_grades_error.show();
|
|
$publish_grades_link.html(I18n.t('links.republish', "Republish grades to SIS"));
|
|
$publish_grades_link.removeClass("disabled");
|
|
}
|
|
$messages = $("#publish_grades_messages");
|
|
$messages.empty();
|
|
$.each(messages, function(message, users) {
|
|
var $message = $("<span/>");
|
|
$message.text(message);
|
|
var $item = $("<li/>");
|
|
$item.append($message);
|
|
$item.append(" - <b>" + users.length + "</b>");
|
|
$messages.append($item);
|
|
});
|
|
},
|
|
publish: function() {
|
|
if (GradePublishing.status == 'publishing' || GradePublishing.status == 'pending' || GradePublishing.status == null) {
|
|
return;
|
|
}
|
|
if (GradePublishing.status == 'published') {
|
|
if (!confirm(I18n.t('confirm.re_publish_grades', "Are you sure you want to republish these grades to the student information system?")))
|
|
return;
|
|
} else {
|
|
if (!confirm(I18n.t('confirm.publish_grades', "Are you sure you want to publish these grades to the student information system? You should only do this if all your grades have been finalized.")))
|
|
return;
|
|
}
|
|
var $publish_to_sis_form = $("#publish_to_sis_form");
|
|
GradePublishing.status = "publishing";
|
|
GradePublishing.update({}, true);
|
|
var successful_statuses = { "published": 1, "publishing": 1, "pending": 1 };
|
|
var error = function(data, xhr, status, error) {
|
|
GradePublishing.status = "unknown";
|
|
$.flashError(I18n.t('errors.publish_grades', "Something went wrong when trying to publish grades to the student information system. Please try again later."));
|
|
GradePublishing.update({});
|
|
};
|
|
$.ajaxJSON($publish_to_sis_form.attr('action'), 'POST', $publish_to_sis_form.getFormData(), function(data) {
|
|
if (!data.hasOwnProperty("sis_publish_overall_status") || !successful_statuses.hasOwnProperty(data["sis_publish_overall_status"])) {
|
|
error(null, null, I18n.t('errors.invalid_sis_status', "Invalid SIS publish status"), null);
|
|
return;
|
|
}
|
|
GradePublishing.status = data.sis_publish_overall_status;
|
|
GradePublishing.update(data.hasOwnProperty("sis_publish_statuses") ? data.sis_publish_statuses : {});
|
|
}, error);
|
|
}
|
|
}
|
|
|
|
$(document).ready(function() {
|
|
var $add_section_form = $("#add_section_form"),
|
|
$edit_section_form = $("#edit_section_form"),
|
|
$course_form = $("#course_form"),
|
|
$enrollment_dialog = $("#enrollment_dialog"),
|
|
$tabBar = $("#course_details_tabs"),
|
|
// as of jqueryui 1.9, the cookie trumps the fragment :(. so we hack
|
|
// around that here
|
|
initialTab = _.indexOf(_.pluck($tabBar.find('> ul a'), 'hash'), location.hash);
|
|
|
|
$tabBar.tabs({cookie: {}, active: initialTab >= 0 ? initialTab : null}).show();
|
|
|
|
$add_section_form.formSubmit({
|
|
required: ['course_section[name]'],
|
|
beforeSubmit: function(data) {
|
|
$add_section_form.find("button").attr('disabled', true).text(I18n.t('buttons.adding_section', "Adding Section..."));
|
|
},
|
|
success: function(data) {
|
|
var section = data.course_section,
|
|
$section = $(".section_blank:first").clone(true).attr('class', 'section'),
|
|
$option = $("<option/>");
|
|
|
|
$add_section_form.find("button").attr('disabled', false).text(I18n.t('buttons.add_section', "Add Section"));
|
|
$section.fillTemplateData({
|
|
data: section,
|
|
hrefValues: ['id']
|
|
});
|
|
$("#course_section_id_holder").show();
|
|
$option.val(section.id).text(section.name).addClass('option_for_section_' + section.id);
|
|
$("#sections .section_blank").before($section);
|
|
$section.slideDown();
|
|
$("#course_section_name").val();
|
|
},
|
|
error: function(data) {
|
|
$add_section_form
|
|
.formErrors(data)
|
|
.find("button").attr('disabled', false).text(I18n.t('errors.section', "Add Section Failed, Please Try Again"));
|
|
}
|
|
});
|
|
$(".cant_delete_section_link").click(function(event) {
|
|
alert($(this).attr('title'));
|
|
return false;
|
|
});
|
|
$edit_section_form.formSubmit({
|
|
beforeSubmit: function(data) {
|
|
$edit_section_form.hide();
|
|
var $section = $edit_section_form.parents(".section");
|
|
$section.find(".name").text(data['course_section[name]']).show();
|
|
$section.loadingImage({image_size: "small"});
|
|
return $section;
|
|
},
|
|
success: function(data, $section) {
|
|
var section = data.course_section;
|
|
$section.loadingImage('remove');
|
|
$(".option_for_section_" + section.id).text(section.name);
|
|
},
|
|
error: function(data, $section) {
|
|
$section.loadingImage('remove').find(".edit_section_link").click();
|
|
$edit_section_form.formErrors(data);
|
|
}
|
|
})
|
|
.find(":text")
|
|
.bind('blur', function() {
|
|
$edit_section_form.submit();
|
|
})
|
|
.keycodes('return esc', function(event) {
|
|
if(event.keyString == 'return') {
|
|
$edit_section_form.submit();
|
|
} else {
|
|
$(this).parents(".section").find(".name").show();
|
|
$("body").append($edit_section_form.hide());
|
|
}
|
|
});
|
|
$(".edit_section_link").click(function() {
|
|
var $this = $(this),
|
|
$section = $this.parents(".section"),
|
|
data = $section.getTemplateData({textValues: ['name']});
|
|
$edit_section_form.fillFormData(data, {object_name: "course_section"});
|
|
$section.find(".name").hide().after($edit_section_form.show());
|
|
$edit_section_form.attr('action', $this.attr('href'));
|
|
$edit_section_form.find(":text:first").focus().select();
|
|
return false;
|
|
});
|
|
$(".delete_section_link").click(function() {
|
|
$(this).parents(".section").confirmDelete({
|
|
url: $(this).attr('href'),
|
|
message: I18n.t('confirm.delete_section', "Are you sure you want to delete this section?"),
|
|
success: function(data) {
|
|
$(this).slideUp(function() {
|
|
$(this).remove();
|
|
});
|
|
}
|
|
});
|
|
return false;
|
|
});
|
|
$("#nav_form").submit(function(){
|
|
tab_id_regex = /(\d+)$/;
|
|
function tab_id_from_el(el) {
|
|
var tab_id_str = $(el).attr("id");
|
|
if (tab_id_str) {
|
|
var tab_id = tab_id_str.replace(/^nav_edit_tab_id_/, '');
|
|
if (tab_id.length > 0) {
|
|
if(!tab_id.match(/context/)) {
|
|
tab_id = parseInt(tab_id, 10);
|
|
}
|
|
return tab_id;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
var tabs = [];
|
|
$("#nav_enabled_list li").each(function() {
|
|
var tab_id = tab_id_from_el(this);
|
|
if (tab_id !== null) { tabs.push({ id: tab_id }); }
|
|
});
|
|
$("#nav_disabled_list li").each(function() {
|
|
var tab_id = tab_id_from_el(this);
|
|
if (tab_id !== null) { tabs.push({ id: tab_id, hidden: true }); }
|
|
});
|
|
|
|
$("#tabs_json").val(JSON.stringify(tabs));
|
|
return true;
|
|
});
|
|
|
|
$(".edit_nav_link").click(function(event) {
|
|
event.preventDefault();
|
|
$("#nav_form").dialog({
|
|
modal: true,
|
|
resizable: false,
|
|
width: 400
|
|
});
|
|
});
|
|
|
|
$("#nav_enabled_list, #nav_disabled_list").sortable({
|
|
items: 'li.enabled',
|
|
connectWith: '.connectedSortable',
|
|
axis: 'y'
|
|
}).disableSelection();
|
|
|
|
$(document).fragmentChange(function(event, hash) {
|
|
function handleFragmentType(val){
|
|
$("#tab-users-link").click();
|
|
$(".add_users_link:visible").click();
|
|
$("#enroll_users_form select[name='enrollment_type']").val(val);
|
|
}
|
|
if(hash == "#add_students") {
|
|
handleFragmentType("StudentEnrollment");
|
|
} else if(hash == "#add_tas") {
|
|
handleFragmentType("TaEnrollment");
|
|
} else if(hash == "#add_teacher") {
|
|
handleFragmentType("TeacherEnrollment");
|
|
}
|
|
});
|
|
$(".edit_course_link").click(function(event) {
|
|
event.preventDefault();
|
|
$("#course_form").addClass('editing').find(":text:first").focus().select();
|
|
$("#course_account_id_lookup").autocomplete({
|
|
source: $("#course_account_id_url").attr('href'),
|
|
select: function(event, ui){
|
|
$("#course_account_id").val(ui.item.id);
|
|
}
|
|
});
|
|
});
|
|
$(".move_course_link").click(function(event) {
|
|
event.preventDefault();
|
|
$("#move_course_dialog").dialog({
|
|
title: I18n.t('titles.move_course', "Move Course"),
|
|
width: 500
|
|
}).fixDialogButtons();
|
|
});
|
|
$("#move_course_dialog").delegate('.cancel_button', 'click', function() {
|
|
$("#move_course_dialog").dialog('close');
|
|
});
|
|
$course_form.find(".grading_standard_checkbox").change(function() {
|
|
$course_form.find(".grading_standard_link").showIf($(this).attr('checked'));
|
|
}).change();
|
|
$course_form.formSubmit({
|
|
processData: function(data) {
|
|
if(data['course[start_at]']) {
|
|
data['course[start_at]'] += " 12:00am";
|
|
}
|
|
if(data['course[conclude_at]']) {
|
|
data['course[conclude_at]'] += " 11:55pm";
|
|
}
|
|
return data;
|
|
},
|
|
beforeSubmit: function(data) {
|
|
$(this).loadingImage().removeClass('editing');
|
|
$(this).find(".readable_license,.account_name,.term_name,.grading_scheme_set").text("...");
|
|
$(this).find(".storage_quota_mb").text(data['course[storage_quota_mb]']);
|
|
$(".course_form_more_options").hide();
|
|
},
|
|
success: function(data) {
|
|
var course = data.course;
|
|
course.start_at = $.parseFromISO(course.start_at).datetime_formatted;
|
|
course.conclude_at = $.parseFromISO(course.conclude_at).datetime_formatted;
|
|
course.is_public = course.is_public ? I18n.t('public_course', 'Public') : I18n.t('private_course', 'Private');
|
|
course.indexed = course.indexed ? I18n.t('indexed_course', "Included in public course index") : "";
|
|
course.grading_scheme_set = course.grading_standard_title || (course.grading_standard_id ? I18n.t('grading_standard_set', "Currently Set") : I18n.t('grading_standard_unset', "Not Set"));
|
|
course.restrict_dates = course.restrict_enrollments_to_course_dates ? I18n.t('course_dates_enforced', "Users can only participate in the course between these dates") : I18n.t('course_dates_unenforced', "These dates will not affect course availability");
|
|
course.locale = $("#course_locale option[value='" + (course.locale || '') + "']").text();
|
|
if (course.locale != $course_form.find('.locale').text()) {
|
|
location.reload();
|
|
return;
|
|
}
|
|
$(this).loadingImage('remove');
|
|
$("#course_form .public_options").showIf(course.is_public);
|
|
$("#course_form .self_enrollment_message").css('display', course.self_enrollment ? '' : 'none');
|
|
$("#course_form").fillTemplateData({data: course});
|
|
if (course.self_enrollment_code) {
|
|
$("#course_form .self_enrollment_message b").each(function() {
|
|
$(this).text($.replaceTags($(this).text(), 'self_enrollment_code', course.self_enrollment_code));
|
|
});
|
|
}
|
|
},
|
|
error: function(data) {
|
|
$(this).loadingImage('remove');
|
|
$(".edit_course_link").click();
|
|
$(this).formErrors(data);
|
|
}
|
|
})
|
|
.find(".cancel_button")
|
|
.click(function() {
|
|
$course_form.removeClass('editing');
|
|
$(".course_form_more_options").hide();
|
|
}).end()
|
|
.find(":text:not(.date_entry)").keycodes('esc', function() {
|
|
$course_form.find(".cancel_button:first").click();
|
|
});
|
|
$(".associated_user_link").click(function(event) {
|
|
event.preventDefault();
|
|
var $user = $(this).parents(".user");
|
|
var $enrollment = $(this).parents(".enrollment_link");
|
|
var user_data = $user.getTemplateData({textValues: ['name']});
|
|
var enrollment_data = $enrollment.getTemplateData({textValues: ['enrollment_id', 'associated_user_id']});
|
|
link_enrollment.choose(user_data.name, enrollment_data.enrollment_id, enrollment_data.associated_user_id, function(enrollment) {
|
|
if(enrollment) {
|
|
var $user = $(".observer_enrollments .user_" + enrollment.user_id)
|
|
var $enrollment_link = $user.find(".enrollment_link.enrollment_" + enrollment.id)
|
|
$enrollment_link.find(".associated_user.associated").showIf(enrollment.associated_user_id)
|
|
$enrollment_link.fillTemplateData({data: enrollment});
|
|
$enrollment_link.find(".associated_user.unassociated").showIf(!enrollment.associated_user_id);
|
|
}
|
|
});
|
|
});
|
|
$(".course_info").not('.uneditable').attr('title', I18n.t('titles.click_to_edit', 'Click to Edit')).click(function(event) {
|
|
if (event.target.nodeName == "INPUT") {
|
|
return;
|
|
}
|
|
$(".edit_course_link:first").click();
|
|
var $obj = $(this).parents("td").find(".course_form");
|
|
if($obj.length) {
|
|
$obj.focus().select();
|
|
}
|
|
});
|
|
$(".course_form_more_options_link").click(function(event) {
|
|
event.preventDefault();
|
|
var $moreOptions = $(".course_form_more_options");
|
|
var optionText = $moreOptions.is(':visible') ? I18n.t('links.more_options', 'more options') : I18n.t('links.less_options', 'less options');
|
|
$(this).text(optionText);
|
|
$moreOptions.slideToggle();
|
|
});
|
|
$enrollment_dialog.find(".cancel_button").click(function() {
|
|
$enrollment_dialog.dialog('close');
|
|
});
|
|
|
|
$enrollment_dialog.find(".re_send_invitation_link").click(function(event) {
|
|
event.preventDefault();
|
|
var $link = $(this);
|
|
$link.text(I18n.t('links.re_sending_invitation', "Re-Sending Invitation..."));
|
|
var url = $link.attr('href');
|
|
$.ajaxJSON(url, 'POST', {}, function(data) {
|
|
$enrollment_dialog.fillTemplateData({data: {invitation_sent_at: I18n.t('invitation_sent_now', "Just Now")}});
|
|
$link.text(I18n.t('invitation_sent', "Invitation Sent!"));
|
|
var $user = $enrollment_dialog.data('user');
|
|
if($user) {
|
|
$user.fillTemplateData({data: {invitation_sent_at: I18n.t('invitation_sent_now', "Just Now")}});
|
|
}
|
|
}, function(data) {
|
|
$link.text(I18n.t('errors.invitation', "Invitation Failed. Please try again."));
|
|
});
|
|
});
|
|
$(".date_entry").date_field();
|
|
|
|
$().data('current_default_wiki_editing_roles', $("#course_default_wiki_editing_roles").val());
|
|
$("#course_default_wiki_editing_roles").change(function() {
|
|
var $this = $(this);
|
|
$(".changed_default_wiki_editing_roles").showIf($this.val() != $().data('current_default_wiki_editing_roles'));
|
|
$(".default_wiki_editing_roles_change").text($this.find(":selected").text());
|
|
});
|
|
|
|
$(".re_send_invitations_link").click(function(event) {
|
|
event.preventDefault();
|
|
var $button = $(this),
|
|
oldText = I18n.t('links.re_send_all', "Re-Send All Unaccepted Invitations");
|
|
|
|
$button.text(I18n.t('buttons.re_sending_all', "Re-Sending Unaccepted Invitations...")).attr('disabled', true);
|
|
$.ajaxJSON($button.attr('href'), 'POST', {}, function(data) {
|
|
$button.text(I18n.t('buttons.re_sent_all', "Re-Sent All Unaccepted Invitations!")).attr('disabled', false);
|
|
$(".user_list .user.pending").each(function() {
|
|
var $user = $(this);
|
|
$user.fillTemplateData({data: {invitation_sent_at: I18n.t('invitation_sent_now', "Just Now")}});
|
|
});
|
|
setTimeout(function() {
|
|
$button.text(oldText);
|
|
}, 2500);
|
|
}, function() {
|
|
$button.text(I18n.t('errors.re_send_all', "Send Failed, Please Try Again")).attr('disabled', false);
|
|
});
|
|
});
|
|
$("#enrollment_type").change(function() {
|
|
$(".teacherless_invite_message").showIf($(this).find(":selected").hasClass('teacherless_invite'));
|
|
});
|
|
$(".is_public_checkbox").change(function() {
|
|
$(".public_options").showIf($(this).attr('checked'));
|
|
}).change();
|
|
|
|
$(".self_enrollment_checkbox").change(function() {
|
|
$(".open_enrollment_holder").showIf($(this).attr('checked'));
|
|
}).change();
|
|
|
|
$("#publish_grades_link").click(function(event) {
|
|
event.preventDefault();
|
|
GradePublishing.publish();
|
|
});
|
|
if (typeof(sisPublishEnabled) != 'undefined' && sisPublishEnabled) {
|
|
GradePublishing.checkup();
|
|
}
|
|
|
|
$(".reset_course_content_button").click(function(event) {
|
|
event.preventDefault();
|
|
$("#reset_course_content_dialog").dialog({
|
|
title: I18n.t('titles.reset_course_content_dialog_help', "Reset Course Content"),
|
|
width: 500
|
|
});
|
|
|
|
$(".ui-dialog").focus();
|
|
}).fixDialogButtons();
|
|
$("#reset_course_content_dialog .cancel_button").click(function() {
|
|
$("#reset_course_content_dialog").dialog('close');
|
|
});
|
|
|
|
$.scrollSidebar();
|
|
});
|
|
});
|