Commit dfd9b463 by asadiqbal

SOL-1455

parent 4f131fec
...@@ -737,7 +737,7 @@ class CertificatesTest(BaseInstructorDashboardTest): ...@@ -737,7 +737,7 @@ class CertificatesTest(BaseInstructorDashboardTest):
self.certificates_section.add_certificate_exception(self.user_name, '') self.certificates_section.add_certificate_exception(self.user_name, '')
self.assertIn( self.assertIn(
'User (username/email={user}) already in exception list.'.format(user=self.user_name), '{user} already in exception list.'.format(user=self.user_name),
self.certificates_section.message.text self.certificates_section.message.text
) )
...@@ -784,8 +784,7 @@ class CertificatesTest(BaseInstructorDashboardTest): ...@@ -784,8 +784,7 @@ class CertificatesTest(BaseInstructorDashboardTest):
self.certificates_section.wait_for_ajax() self.certificates_section.wait_for_ajax()
self.assertIn( self.assertIn(
"We can't find the user (username/email={user}) you've entered. " "{user} does not exist in the LMS. Please check your spelling and retry.".format(user=invalid_user),
"Make sure the username or email address is correct, then try again.".format(user=invalid_user),
self.certificates_section.message.text self.certificates_section.message.text
) )
...@@ -818,8 +817,7 @@ class CertificatesTest(BaseInstructorDashboardTest): ...@@ -818,8 +817,7 @@ class CertificatesTest(BaseInstructorDashboardTest):
self.certificates_section.wait_for_ajax() self.certificates_section.wait_for_ajax()
self.assertIn( self.assertIn(
"The user (username/email={user}) you have entered is not enrolled in this course. " "{user} is not enrolled in this course. Please check your spelling and retry.".format(user=new_user),
"Make sure the username or email address is correct, then try again.".format(user=new_user),
self.certificates_section.message.text self.certificates_section.message.text
) )
...@@ -840,6 +838,7 @@ class CertificatesTest(BaseInstructorDashboardTest): ...@@ -840,6 +838,7 @@ class CertificatesTest(BaseInstructorDashboardTest):
self.certificates_section.wait_for_ajax() self.certificates_section.wait_for_ajax()
self.assertIn( self.assertIn(
'Certificate generation started for white listed students.', self.user_name + ' has been successfully added to the exception list. Click Generate Exception Certificate'
' below to send the certificate.',
self.certificates_section.message.text self.certificates_section.message.text
) )
...@@ -474,8 +474,7 @@ class CertificateExceptionViewInstructorApiTest(SharedModuleStoreTestCase): ...@@ -474,8 +474,7 @@ class CertificateExceptionViewInstructorApiTest(SharedModuleStoreTestCase):
# Assert Error Message # Assert Error Message
self.assertEqual( self.assertEqual(
res_json['message'], res_json['message'],
u"We can't find the user (username/email={user}) you've entered. " u"{user} does not exist in the LMS. Please check your spelling and retry.".format(user=invalid_user)
u"Make sure the username or email address is correct, then try again.".format(user=invalid_user)
) )
def test_certificate_exception_missing_username_and_email_error(self): def test_certificate_exception_missing_username_and_email_error(self):
...@@ -501,7 +500,7 @@ class CertificateExceptionViewInstructorApiTest(SharedModuleStoreTestCase): ...@@ -501,7 +500,7 @@ class CertificateExceptionViewInstructorApiTest(SharedModuleStoreTestCase):
self.assertEqual( self.assertEqual(
res_json['message'], res_json['message'],
u'Student username/email field is required and can not be empty. ' u'Student username/email field is required and can not be empty. '
u'Kindly fill in username/email and then press "Add Exception" button.' u'Kindly fill in username/email and then press "Add to Exception List" button.'
) )
def test_certificate_exception_duplicate_user_error(self): def test_certificate_exception_duplicate_user_error(self):
...@@ -591,8 +590,7 @@ class CertificateExceptionViewInstructorApiTest(SharedModuleStoreTestCase): ...@@ -591,8 +590,7 @@ class CertificateExceptionViewInstructorApiTest(SharedModuleStoreTestCase):
# Assert Error Message # Assert Error Message
self.assertEqual( self.assertEqual(
res_json['message'], res_json['message'],
"The user (username/email={user}) you have entered is not enrolled in this course. " "{user} is not enrolled in this course. Please check your spelling and retry.".format(
"Make sure the username or email address is correct, then try again.".format(
user=self.certificate_exception['user_name'] user=self.certificate_exception['user_name']
) )
) )
...@@ -646,7 +644,7 @@ class CertificateExceptionViewInstructorApiTest(SharedModuleStoreTestCase): ...@@ -646,7 +644,7 @@ class CertificateExceptionViewInstructorApiTest(SharedModuleStoreTestCase):
# Assert Error Message # Assert Error Message
self.assertEqual( self.assertEqual(
res_json['message'], res_json['message'],
u"Invalid Json data, Please refresh the page and then try again." u"The record is not in the correct format. Please add a valid username or email address."
) )
def test_remove_certificate_exception_non_existing_error(self): def test_remove_certificate_exception_non_existing_error(self):
......
...@@ -2839,22 +2839,21 @@ def parse_request_data_and_get_user(request, course_key): ...@@ -2839,22 +2839,21 @@ def parse_request_data_and_get_user(request, course_key):
try: try:
certificate_exception = json.loads(request.body or '{}') certificate_exception = json.loads(request.body or '{}')
except ValueError: except ValueError:
raise ValueError(_('Invalid Json data, Please refresh the page and then try again.')) raise ValueError(_('The record is not in the correct format. Please add a valid username or email address.'))
user = certificate_exception.get('user_name', '') or certificate_exception.get('user_email', '') user = certificate_exception.get('user_name', '') or certificate_exception.get('user_email', '')
if not user: if not user:
raise ValueError(_('Student username/email field is required and can not be empty. ' raise ValueError(_('Student username/email field is required and can not be empty. '
'Kindly fill in username/email and then press "Add Exception" button.')) 'Kindly fill in username/email and then press "Add to Exception List" button.'))
try: try:
db_user = get_user_by_username_or_email(user) db_user = get_user_by_username_or_email(user)
except ObjectDoesNotExist: except ObjectDoesNotExist:
raise ValueError(_("We can't find the user (username/email={user}) you've entered. " raise ValueError(_("{user} does not exist in the LMS. Please check your spelling and retry.").format(user=user))
"Make sure the username or email address is correct, then try again.").format(user=user))
# Make Sure the given student is enrolled in the course # Make Sure the given student is enrolled in the course
if not CourseEnrollment.is_enrolled(db_user, course_key): if not CourseEnrollment.is_enrolled(db_user, course_key):
raise ValueError(_("The user (username/email={user}) you have entered is not enrolled in this course. " raise ValueError(_("{user} is not enrolled in this course. Please check your spelling and retry.")
"Make sure the username or email address is correct, then try again.").format(user=user)) .format(user=user))
return certificate_exception, db_user return certificate_exception, db_user
......
...@@ -32,7 +32,8 @@ ...@@ -32,7 +32,8 @@
el: DOM_SELECTORS.bulk_exception, el: DOM_SELECTORS.bulk_exception,
events: { events: {
'change #browseBtn': 'chooseFile', 'change #browseBtn': 'chooseFile',
'click .upload-csv-button': 'uploadCSV' 'click .upload-csv-button': 'uploadCSV',
'click a.arrow': 'toggleMessageDetails'
}, },
initialize: function(options){ initialize: function(options){
...@@ -72,19 +73,22 @@ ...@@ -72,19 +73,22 @@
}, },
display_response: function(data_from_server) { display_response: function(data_from_server) {
$(".results").empty(); $(".bulk-exception-results").removeClass('hidden').empty();
// Display general error messages // Display general error messages
if (data_from_server.general_errors.length) { if (data_from_server.general_errors.length) {
var errors = data_from_server.general_errors; var errors = data_from_server.general_errors;
generate_div('msg-error', MESSAGE_GROUP.general_errors, gettext('Errors!'), errors); generate_div(
MESSAGE_GROUP.general_errors,
gettext('Uploaded file issues. Click on "+" to view.'),
errors
);
} }
// Display success message // Display success message
if (data_from_server.success.length) { if (data_from_server.success.length) {
var success_data = data_from_server.success; var success_data = data_from_server.success;
generate_div( generate_div(
'msg-success',
MESSAGE_GROUP.successfully_added, MESSAGE_GROUP.successfully_added,
get_text(success_data.length, MESSAGE_GROUP.successfully_added), get_text(success_data.length, MESSAGE_GROUP.successfully_added),
success_data success_data
...@@ -98,7 +102,6 @@ ...@@ -98,7 +102,6 @@
if (row_errors.data_format_error.length) { if (row_errors.data_format_error.length) {
var format_errors = row_errors.data_format_error; var format_errors = row_errors.data_format_error;
generate_div( generate_div(
'msg-error',
MESSAGE_GROUP.data_format_error, MESSAGE_GROUP.data_format_error,
get_text(format_errors.length, MESSAGE_GROUP.data_format_error), get_text(format_errors.length, MESSAGE_GROUP.data_format_error),
format_errors format_errors
...@@ -107,7 +110,6 @@ ...@@ -107,7 +110,6 @@
if (row_errors.user_not_exist.length) { if (row_errors.user_not_exist.length) {
var user_not_exist = row_errors.user_not_exist; var user_not_exist = row_errors.user_not_exist;
generate_div( generate_div(
'msg-error',
MESSAGE_GROUP.user_not_exist, MESSAGE_GROUP.user_not_exist,
get_text(user_not_exist.length, MESSAGE_GROUP.user_not_exist), get_text(user_not_exist.length, MESSAGE_GROUP.user_not_exist),
user_not_exist user_not_exist
...@@ -116,7 +118,6 @@ ...@@ -116,7 +118,6 @@
if (row_errors.user_already_white_listed.length) { if (row_errors.user_already_white_listed.length) {
var user_already_white_listed = row_errors.user_already_white_listed; var user_already_white_listed = row_errors.user_already_white_listed;
generate_div( generate_div(
'msg-error',
MESSAGE_GROUP.user_already_white_listed, MESSAGE_GROUP.user_already_white_listed,
get_text(user_already_white_listed.length, MESSAGE_GROUP.user_already_white_listed), get_text(user_already_white_listed.length, MESSAGE_GROUP.user_already_white_listed),
user_already_white_listed user_already_white_listed
...@@ -125,7 +126,6 @@ ...@@ -125,7 +126,6 @@
if (row_errors.user_not_enrolled.length) { if (row_errors.user_not_enrolled.length) {
var user_not_enrolled = row_errors.user_not_enrolled; var user_not_enrolled = row_errors.user_not_enrolled;
generate_div( generate_div(
'msg-error',
MESSAGE_GROUP.user_not_enrolled, MESSAGE_GROUP.user_not_enrolled,
get_text(user_not_enrolled.length, MESSAGE_GROUP.user_not_enrolled), get_text(user_not_enrolled.length, MESSAGE_GROUP.user_not_enrolled),
user_not_enrolled user_not_enrolled
...@@ -133,17 +133,22 @@ ...@@ -133,17 +133,22 @@
} }
} }
function generate_div(div_class, group, heading, display_data) { function generate_div(group, heading, display_data) {
// inner function generate div and display response messages. // inner function generate div and display response messages.
$('<div/>', { $('<div/>', {
class: 'message ' + div_class + ' ' + group class: 'message ' + group
}).appendTo('.results').prepend( "<b>" + heading + "</b>" ); }).appendTo('.bulk-exception-results').prepend(
"<a id= '" + group + "' href='javascript:void(0);' class='arrow'> + </a>" + heading
).append($('<ul/>', {
class: group
}));
for(var i = 0; i < display_data.length; i++){ for(var i = 0; i < display_data.length; i++){
$('<div/>', { $('<li/>', {
text: display_data[i] text: display_data[i]
}).appendTo('.results > .' + div_class + '.' + group); }).appendTo('div.message > .' + group);
} }
$("div.message > ." + group).hide();
} }
function get_text(qty, group) { function get_text(qty, group) {
...@@ -179,10 +184,23 @@ ...@@ -179,10 +184,23 @@
} }
}, },
toggleMessageDetails: function(event) {
if (event && event.preventDefault) { event.preventDefault(); }
var group = event.target.id;
$("div.message > ." + group).slideToggle( "fast", function() {
if ($(this).is(':visible')) {
event.target.text = ' -- ';
} else {
event.target.text = ' + ';
}
});
},
chooseFile: function(event) { chooseFile: function(event) {
if (event && event.preventDefault) { event.preventDefault(); } if (event && event.preventDefault) { event.preventDefault(); }
if (event.currentTarget.files.length === 1) { if (event.currentTarget.files.length === 1) {
this.$el.find(DOM_SELECTORS.upload_csv_button).removeClass('is-disabled'); this.$el.find(DOM_SELECTORS.upload_csv_button).removeClass('is-disabled')
.addClass('button-blue');
this.$el.find(DOM_SELECTORS.browse_file).val( this.$el.find(DOM_SELECTORS.browse_file).val(
event.currentTarget.value.substring(event.currentTarget.value.lastIndexOf("\\") + 1)); event.currentTarget.value.substring(event.currentTarget.value.lastIndexOf("\\") + 1));
} }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
function($, _, gettext, Backbone){ function($, _, gettext, Backbone){
return Backbone.View.extend({ return Backbone.View.extend({
el: "#white-listed-students", el: "#white-listed-students",
message_div: '#certificate-white-list-editor .message', message_div: 'div.white-listed-students > div.message',
generate_exception_certificates_radio: generate_exception_certificates_radio:
'input:radio[name=generate-exception-certificates-radio]:checked', 'input:radio[name=generate-exception-certificates-radio]:checked',
...@@ -42,11 +42,27 @@ ...@@ -42,11 +42,27 @@
}, },
removeException: function(event){ removeException: function(event){
// Delegate remove exception event to certificate white-list editor view var certificate = $(event.target).data();
this.certificateWhiteListEditorView.trigger('removeException', $(event.target).data()); var model = this.collection.findWhere(certificate);
var self = this;
// avoid default click behavior of link by returning false. if(model){
return false; model.destroy(
{
success: function() {
self.showMessage('Student Removed from certificate white list successfully.');
},
error: this.showError(this),
wait: true,
data: JSON.stringify(model.attributes)
}
);
}
else{
this.showMessage(
'Could not find Certificate Exception in white list. ' +
'Please refresh the page and try again'
);
}
}, },
generateExceptionCertificates: function(){ generateExceptionCertificates: function(){
...@@ -56,17 +72,15 @@ ...@@ -56,17 +72,15 @@
); );
}, },
showMessage: function(message, messageClass){ showMessage: function(message){
$(this.message_div).text(message). $(this.message_div + ">p" ).remove();
removeClass('msg-error msg-success').addClass(messageClass).focus(); $(this.message_div).removeClass('hidden').append("<p>"+ gettext(message) + "</p>").focus();
$('html, body').animate({ $(this.message_div).fadeOut(6000, "linear");
scrollTop: $(this.message_div).offset().top - 20
}, 1000);
}, },
showSuccess: function(caller_object){ showSuccess: function(caller_object){
return function(xhr){ return function(xhr){
caller_object.showMessage(xhr.message, 'msg-success'); caller_object.showMessage(xhr.message);
}; };
}, },
...@@ -74,12 +88,11 @@ ...@@ -74,12 +88,11 @@
return function(xhr){ return function(xhr){
try{ try{
var response = JSON.parse(xhr.responseText); var response = JSON.parse(xhr.responseText);
caller_object.showMessage(response.message, 'msg-error'); caller_object.showMessage(response.message);
} }
catch(exception){ catch(exception){
caller_object.showMessage( caller_object.showMessage(
"Server Error, Please refresh the page and try again.", 'msg-error' "Server Error, Please refresh the page and try again.");
);
} }
}; };
} }
......
...@@ -19,11 +19,6 @@ ...@@ -19,11 +19,6 @@
'click #add-exception': 'addException' 'click #add-exception': 'addException'
}, },
initialize: function(){
this.on('removeException', this.removeException);
},
render: function(){ render: function(){
var template = this.loadTemplate('certificate-white-list-editor'); var template = this.loadTemplate('certificate-white-list-editor');
this.$el.html(template()); this.$el.html(template());
...@@ -59,8 +54,7 @@ ...@@ -59,8 +54,7 @@
if(this.collection.findWhere(model)){ if(this.collection.findWhere(model)){
this.showMessage( this.showMessage(
"User (username/email=" + (user_name || user_email) + ") already in exception list.", (user_name || user_email) + " already in exception list."
'msg-error'
); );
} }
else if(certificate_exception.isValid()){ else if(certificate_exception.isValid()){
...@@ -70,7 +64,8 @@ ...@@ -70,7 +64,8 @@
success: this.showSuccess( success: this.showSuccess(
this, this,
true, true,
'Student added to Certificate white list successfully.' (user_name || user_email) + ' has been successfully added to the exception list.' +
' Click Generate Exception Certificate below to send the certificate.'
), ),
error: this.showError(this) error: this.showError(this)
} }
...@@ -78,34 +73,7 @@ ...@@ -78,34 +73,7 @@
} }
else{ else{
this.showMessage(certificate_exception.validationError, 'msg-error'); this.showMessage(certificate_exception.validationError);
}
},
removeException: function(certificate){
var model = this.collection.findWhere(certificate);
if(model){
model.destroy(
{
success: this.showSuccess(
this,
false,
'Student Removed from certificate white list successfully.'
),
error: this.showError(this),
wait: true,
//emulateJSON: true,
data: JSON.stringify(model.attributes)
}
);
this.showMessage('Exception is being removed from server.', 'msg-success');
}
else{
this.showMessage(
'Could not find Certificate Exception in white list. ' +
'Please refresh the page and try again',
'msg-error'
);
} }
}, },
...@@ -114,12 +82,9 @@ ...@@ -114,12 +82,9 @@
return re.test(email); return re.test(email);
}, },
showMessage: function(message, messageClass){ showMessage: function(message){
this.$(this.message_div).text(message). $(this.message_div + ">p" ).remove();
removeClass('msg-error msg-success').addClass(messageClass).focus(); this.$(this.message_div).removeClass('hidden').append("<p>"+ gettext(message) + "</p>");
$('html, body').animate({
scrollTop: this.$el.offset().top - 20
}, 1000);
}, },
showSuccess: function(caller, add_model, message){ showSuccess: function(caller, add_model, message){
...@@ -127,7 +92,7 @@ ...@@ -127,7 +92,7 @@
if(add_model){ if(add_model){
caller.collection.add(model); caller.collection.add(model);
} }
caller.showMessage(message, 'msg-success'); caller.showMessage(message);
}; };
}, },
...@@ -135,11 +100,11 @@ ...@@ -135,11 +100,11 @@
return function(model, response){ return function(model, response){
try{ try{
var response_data = JSON.parse(response.responseText); var response_data = JSON.parse(response.responseText);
caller.showMessage(response_data.message, 'msg-error'); caller.showMessage(response_data.message);
} }
catch(exception){ catch(exception){
caller.showMessage("" + caller.showMessage("" +
"Server Error, Please refresh the page and try again.", 'msg-error' "Server Error, Please refresh the page and try again."
); );
} }
}; };
......
...@@ -330,16 +330,15 @@ define([ ...@@ -330,16 +330,15 @@ define([
it("verifies success and error messages", function() { it("verifies success and error messages", function() {
var message_selector='.message', var message_selector='.message',
error_class = 'msg-error', success_message = 'test_user has been successfully added to the exception list. Click Generate' +
success_class = 'msg-success', ' Exception Certificate below to send the certificate.',
success_message = 'Student added to Certificate white list successfully.',
requests = AjaxHelpers.requests(this), requests = AjaxHelpers.requests(this),
duplicate_user='test_user'; duplicate_user='test_user';
var error_messages = { var error_messages = {
empty_user_name_email: 'Student username/email field is required and can not be empty. ' + empty_user_name_email: 'Student username/email field is required and can not be empty. ' +
'Kindly fill in username/email and then press "Add Exception" button.', 'Kindly fill in username/email and then press "Add Exception" button.',
duplicate_user: "User (username/email=" + (duplicate_user) + ") already in exception list." duplicate_user: "<p>" + (duplicate_user) + " already in exception list.</p>"
}; };
// click 'Add Exception' button with empty username/email field // click 'Add Exception' button with empty username/email field
...@@ -347,7 +346,6 @@ define([ ...@@ -347,7 +346,6 @@ define([
view.$el.find('#add-exception').click(); view.$el.find('#add-exception').click();
// Verify error message for missing username/email // Verify error message for missing username/email
expect(view.$el.find(message_selector)).toHaveClass(error_class);
expect(view.$el.find(message_selector).html()).toMatch(error_messages.empty_user_name_email); expect(view.$el.find(message_selector).html()).toMatch(error_messages.empty_user_name_email);
// Add a new Exception to list // Add a new Exception to list
...@@ -369,7 +367,6 @@ define([ ...@@ -369,7 +367,6 @@ define([
); );
// Verify success message // Verify success message
expect(view.$el.find(message_selector)).toHaveClass(success_class);
expect(view.$el.find(message_selector).html()).toMatch(success_message); expect(view.$el.find(message_selector).html()).toMatch(success_message);
// Add a duplicate Certificate Exception // Add a duplicate Certificate Exception
...@@ -378,7 +375,6 @@ define([ ...@@ -378,7 +375,6 @@ define([
view.$el.find('#add-exception').click(); view.$el.find('#add-exception').click();
// Verify success message // Verify success message
expect(view.$el.find(message_selector)).toHaveClass(error_class);
expect(view.$el.find(message_selector).html()).toEqual(error_messages.duplicate_user); expect(view.$el.find(message_selector).html()).toEqual(error_messages.duplicate_user);
}); });
......
...@@ -1802,15 +1802,6 @@ input[name="subject"] { ...@@ -1802,15 +1802,6 @@ input[name="subject"] {
width: 75%; width: 75%;
} }
.certificate-exception-container {
h3 {
border-bottom: 1px groove black;
display: inline-block;
}
p.under-heading-text {
margin: 12px 0 12px 0;
}
}
} }
input[name="subject"] { input[name="subject"] {
...@@ -2110,103 +2101,174 @@ input[name="subject"] { ...@@ -2110,103 +2101,174 @@ input[name="subject"] {
@include right(auto); @include right(auto);
} }
#certificate-white-list-editor{ // view - certificates
.certificate-exception-inputs{ // --------------------
.student-username-or-email{ .instructor-dashboard-wrapper-2 section.idash-section#certificates {
width: 300px;
}
.notes-field{
width: 400px;
}
p+p{
margin-top: 5px;
}
.message{
margin-top: 10px;
}
}
}
.white-listed-students {
table {
width: 100%;
word-wrap: break-word;
th { %btn-blue {
@extend %t-copy-sub2; @extend %btn-primary-blue;
background-color: $gray-l5; padding: ($baseline/2.5) ($baseline/2);
padding: ($baseline*0.75) ($baseline/2) ($baseline*0.75) ($baseline/2); text-shadow: none;
vertical-align: middle; margin-bottom: 10px;
text-align: left; }
color: $gray;
&.date, &.email{ %exception-message {
width: 230px; margin-top: 15px;
background-color: $gray-l4;
border-top-style: groove;
color: $black;
} }
&.user-id{ #certificate-white-list-editor {
width: 60px; .certificate-exception-inputs {
.student-username-or-email {
width: 300px;
margin-bottom: 10px;
} }
.notes-field {
&.user-name{ width: 400px;
width: 150px;
} }
p + p {
&.action{ margin-top: 5px;
width: 150px; }
.message {
@extend %exception-message;
} }
.button-blue {
@extend %btn-blue;
}
} }
}
td { .white-listed-students {
padding: ($baseline/2); margin-top: 10px;
vertical-align: middle; table {
text-align: left; width: 100%;
} word-wrap: break-word;
tbody { th {
box-shadow: 0 2px 2px $shadow-l1; @extend %t-copy-sub2;
border: 1px solid $gray-l4; background-color: $gray-l5;
background: $white; padding: ($baseline*0.75) ($baseline/2) ($baseline*0.75) ($baseline/2);
vertical-align: middle;
text-align: left;
color: $gray;
tr { &.date, &.email {
@include transition(all $tmg-f2 ease-in-out 0s); width: 230px;
border-top: 1px solid $gray-l4; }
&:first-child { &.user-id {
border-top: none; width: 60px;
} }
&:nth-child(odd) { &.user-name {
background-color: $gray-l6; width: 150px;
} }
a { &.action {
color: $gray-d1; width: 150px;
}
}
td {
padding: ($baseline/2);
vertical-align: middle;
text-align: left;
}
tbody {
box-shadow: 0 2px 2px $shadow-l1;
border: 1px solid $gray-l4;
background: $white;
tr {
@include transition(all $tmg-f2 ease-in-out 0s);
border-top: 1px solid $gray-l4;
&:first-child {
border-top: none;
}
&:nth-child(odd) {
background-color: $gray-l6;
}
a {
color: $gray-d1;
&:hover {
color: $blue;
}
}
&:hover { &:hover {
color: $blue; background-color: $blue-l5;
} }
} }
}
}
.button-blue {
@extend %btn-blue;
}
.message {
@extend %exception-message;
}
}
&:hover { .certificate-exception-container {
background-color: $blue-l5; h3 {
border-bottom: 1px groove black;
display: inline-block;
}
p.under-heading {
margin: 12px 0 12px 0;
line-height: 23px;
}
}
.bulk-white-list-exception {
margin-top: 10px;
.white-list-csv {
.bulk-exception-results {
margin-top: 10px;
background-color: $gray-l4;
border-top-style: groove;
color: $black;
margin-bottom: 15px;
.message {
padding: 5px 10px;
margin: 2px;
} }
}
.arrow {
font-weight: bold;
}
.button-blue {
@extend %btn-blue;
} }
} }
} }
} }
// Custom File upload // Custom File upload
.customBrowseBtn { .customBrowseBtn {
margin: ($baseline/2) 0; margin: ($baseline/2) 0;
display: inline-block; display: inline-block;
.file-browse { .file-browse {
position:relative; position: relative;
overflow:hidden; overflow: hidden;
display: inline; display: inline;
@include margin-left(-5px); @include margin-left(-5px);
span.browse{ span.browse {
@include button(simple, $blue); @include button(simple, $blue);
@include margin-right($baseline); @include margin-right($baseline);
padding: 6px ($baseline/2); padding: 6px ($baseline/2);
...@@ -2214,17 +2276,17 @@ input[name="subject"] { ...@@ -2214,17 +2276,17 @@ input[name="subject"] {
border-radius: 0 3px 3px 0; border-radius: 0 3px 3px 0;
} }
input.file_field { input.file_field {
position:absolute; position: absolute;
@include right(0); @include right(0);
top:0; top: 0;
margin:0; margin: 0;
padding:0; padding: 0;
cursor:pointer; cursor: pointer;
opacity:0; opacity: 0;
filter:alpha(opacity=0); filter: alpha(opacity=0);
} }
} }
& > span, & input[disabled]{ & > span, & input[disabled] {
vertical-align: middle; vertical-align: middle;
} }
input[disabled] { input[disabled] {
...@@ -2233,4 +2295,4 @@ input[name="subject"] { ...@@ -2233,4 +2295,4 @@ input[name="subject"] {
border: 1px solid $lightGrey1; border: 1px solid $lightGrey1;
cursor: not-allowed; cursor: not-allowed;
} }
} }
\ No newline at end of file
<h3><%= gettext("Bulk Exceptions") %></h3> <h3><%= gettext("Bulk Exceptions") %></h3>
<div class="bulk_white_list_csv"> <div class="white-list-csv">
<p class="under-heading-text"> <p class="under-heading">
<%= gettext("You can upload a CSV file of usernames or email addresses to be added to the certificate exceptions white list.") %> <%= gettext("Upload a comma separated values (.csv) file that contains the usernames or email addresses of learners who have been given exceptions. Include the username or email address in the first comma separated field. You can include an optional note describing the reason for the exception in the second comma separated field.") %>
</p> </p>
<form id="bulk-white-list-exception-form" enctype="multipart/form-data"> <form id="bulk-white-list-exception-form" enctype="multipart/form-data">
<div class="customBrowseBtn"> <div class="customBrowseBtn">
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<input class="file_field" id="browseBtn" name="students_list" type="file" accept=".csv"/> <input class="file_field" id="browseBtn" name="students_list" type="file" accept=".csv"/>
</div> </div>
</div> </div>
<button class="is-disabled upload-csv-button" type="submit"><%= gettext("Upload CSV") %></button> <div><button class="is-disabled upload-csv-button" type="submit"><%= gettext('Add to Exception List') %></button></div>
</form> </form>
<div class="results"></div> <div class="bulk-exception-results hidden"></div>
</div> </div>
\ No newline at end of file
<h3><%= gettext("Individual Exceptions") %></h3> <h3><%= gettext("Individual Exceptions") %></h3>
<p class="under-heading-text"> <%= gettext("You can add a username or email address to be added to the certificate exceptions white list.") %></p> <p class="under-heading"> <%= gettext("Enter the username or email address of each learner that you want to add as an exception.") %></p>
<div class='certificate-exception-inputs'> <div class='certificate-exception-inputs'>
<div class="">
<input class='student-username-or-email' id="certificate-exception" type="text" placeholder="Student email or username" aria-describedby='student-user-name-or-email-tip'> <input class='student-username-or-email' id="certificate-exception" type="text" placeholder="Student email or username" aria-describedby='student-user-name-or-email-tip'>
<textarea class='notes-field' id="notes" rows="10" placeholder="Free text notes" aria-describedby='notes-field-tip'></textarea> <textarea class='notes-field' id="notes" rows="10" placeholder="Free text notes" aria-describedby='notes-field-tip'></textarea>
<input type="button" id="add-exception" value="Add Exception"> </div>
<div>
<div class='message'></div> <button type="button" class="button-blue" id="add-exception" ><%= gettext("Add to Exception List") %> </button>
</div>
<div class='message hidden'></div>
</div> </div>
<h3><%= gettext("Generate Exception Certificates") %></h3>
<p class="under-heading">
<label> <label>
<input type='radio' name='generate-exception-certificates-radio' checked="checked" value='new' aria-describedby='generate-exception-certificates-radio-new-tip'> <input type='radio' name='generate-exception-certificates-radio' checked="checked" value='new' aria-describedby='generate-exception-certificates-radio-new-tip'>
<span id='generate-exception-certificates-radio-new-tip'><%- gettext('Generate a Certificate for all ') %><strong><%- gettext('New') %></strong> <%- gettext('additions to the Exception list') %></span> <span id='generate-exception-certificates-radio-new-tip'><%- gettext('Generate a Certificate for all ') %><strong><%- gettext('New') %></strong> <%- gettext('additions to the Exception list') %></span>
...@@ -7,8 +9,8 @@ ...@@ -7,8 +9,8 @@
<input type='radio' name='generate-exception-certificates-radio' value='all' aria-describedby='generate-exception-certificates-radio-all-tip'> <input type='radio' name='generate-exception-certificates-radio' value='all' aria-describedby='generate-exception-certificates-radio-all-tip'>
<span id='generate-exception-certificates-radio-all-tip'><%- gettext('Generate a Certificate for all users on the Exception list') %></span> <span id='generate-exception-certificates-radio-all-tip'><%- gettext('Generate a Certificate for all users on the Exception list') %></span>
</label> </label>
<br/> </p>
<input type="button" id="generate-exception-certificates" value="<%- gettext('Generate Exception Certificates') %>" /> <button id="generate-exception-certificates" class="button-blue" type="button"><%= gettext('Generate Exception Certificates') %></button>
<br/> <br/>
<% if (certificates.length === 0) { %> <% if (certificates.length === 0) { %>
<p><%- gettext("No results") %></p> <p><%- gettext("No results") %></p>
...@@ -37,4 +39,5 @@ ...@@ -37,4 +39,5 @@
<% } %> <% } %>
</tbody> </tbody>
</table> </table>
<div class='message hidden'></div>
<% } %> <% } %>
...@@ -117,14 +117,15 @@ import json ...@@ -117,14 +117,15 @@ import json
<div class="certificate-exception-container"> <div class="certificate-exception-container">
<hr> <hr>
<h2> ${_("Certificate Exceptions")} </h2> <h2> ${_("SET CERTIFICATE EXCEPTIONS")} </h2>
<p class="under-heading-text"> <p class="under-heading info">
${_("Use this to generate certificates for users who did not pass the course but have been given an exception by the Course Team to earn a certificate.")} ${_("Set exceptions to generate certificates for learners who did not qualify for a certificate but have " \
"been given an exception by the course team. After you add learners to the exception list, click Generate " \
"Exception Certificates below.")}
</p> </p>
<div class="certificate-exception-section"> <div class="certificate-exception-section">
<div class="bulk-white-list-exception"></div>
<br />
<div id="certificate-white-list-editor"></div> <div id="certificate-white-list-editor"></div>
<div class="bulk-white-list-exception"></div>
<div class="white-listed-students" id="white-listed-students"></div> <div class="white-listed-students" id="white-listed-students"></div>
<br/> <br/>
</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