Commit 3302b26e by Chris Committed by GitHub

Merge pull request #12926 from edx/clrux/ac-524

AC-524 fixes `label` ignores
parents bae7cfee b97d0631
...@@ -17,7 +17,7 @@ def go_to_updates(_step): ...@@ -17,7 +17,7 @@ def go_to_updates(_step):
@step(u'I add a new update with the text "([^"]*)"$') @step(u'I add a new update with the text "([^"]*)"$')
def add_update(_step, text): def add_update(_step, text):
update_css = 'a.new-update-button' update_css = '.new-update-button'
world.css_click(update_css) world.css_click(update_css)
world.wait_for_visible('.CodeMirror') world.wait_for_visible('.CodeMirror')
change_text(text) change_text(text)
......
...@@ -748,8 +748,8 @@ class MembershipPageAutoEnrollSection(PageObject): ...@@ -748,8 +748,8 @@ class MembershipPageAutoEnrollSection(PageObject):
""" """
url = None url = None
auto_enroll_browse_button_selector = '.auto_enroll_csv .file-browse input.file_field#browseBtn-auto_enroll_csv' auto_enroll_browse_button_selector = '.auto_enroll_csv .file-browse input.file_field#browseBtn-auto-enroll'
auto_enroll_upload_button_selector = '.auto_enroll_csv #submitBtn-auto_enroll_csv' auto_enroll_upload_button_selector = '.auto_enroll_csv button[name="enrollment_signup_button"]'
batch_enrollment_selector = '.batch-enrollment' batch_enrollment_selector = '.batch-enrollment'
NOTIFICATION_ERROR = 'error' NOTIFICATION_ERROR = 'error'
NOTIFICATION_WARNING = 'warning' NOTIFICATION_WARNING = 'warning'
......
...@@ -1051,8 +1051,7 @@ class CertificatesTest(BaseInstructorDashboardTest): ...@@ -1051,8 +1051,7 @@ class CertificatesTest(BaseInstructorDashboardTest):
self.certificates_section.a11y_audit.config.set_rules({ self.certificates_section.a11y_audit.config.set_rules({
"ignore": [ "ignore": [
'checkboxgroup', # TODO: AC-491 'checkboxgroup', # TODO: AC-491
'duplicate-id', # TODO: AC-523 'duplicate-id', # TODO: AC-491
'label', # TODO: AC-524
'radiogroup', # TODO: AC-491 'radiogroup', # TODO: AC-491
] ]
}) })
...@@ -1269,7 +1268,6 @@ class CertificateInvalidationTest(BaseInstructorDashboardTest): ...@@ -1269,7 +1268,6 @@ class CertificateInvalidationTest(BaseInstructorDashboardTest):
"ignore": [ "ignore": [
'checkboxgroup', # TODO: AC-491 'checkboxgroup', # TODO: AC-491
'duplicate-id', # TODO: AC-491 'duplicate-id', # TODO: AC-491
'label', # TODO: AC-491
'radiogroup', # TODO: AC-491 'radiogroup', # TODO: AC-491
] ]
}) })
......
...@@ -7,14 +7,14 @@ ...@@ -7,14 +7,14 @@
<form id="student-auto-enroll-form"> <form id="student-auto-enroll-form">
<div class="customBrowseBtn"> <div class="customBrowseBtn">
<input disabled="disabled" id="browseFile" placeholder="choose file"/> <label for="browseBtn-auto-enroll">Upload a CSV for bulk enrollment</label>
<span id="browseFile" class="enhanced-input-file"></span>
<div class="file-browse btn btn-primary"> <div class="file-browse btn btn-primary" aria-hidden="true">
<label for="browseBtn-auto_enroll_csv" class="browse">Browse</label> <span class="browse">Browse</span>
<input class="file_field" id="browseBtn-auto_enroll_csv" name="students_list" type="file" accept=".csv"/> <input class="file_field" id="browseBtn-auto-enroll" name="students_list" type="file" accept=".csv"/>
</div> </div>
</div> </div>
<button type="submit" id="submitBtn-auto_enroll_csv" name="enrollment_signup_button">Upload CSV</button> <button type="submit" class="btn-blue" id="submitBtn-auto_enroll_csv" name="enrollment_signup_button">Upload CSV</button>
</form> </form>
<div class="results"></div> <div class="results"></div>
</div> </div>
...@@ -186,7 +186,7 @@ class @AutoEnrollmentViaCsv ...@@ -186,7 +186,7 @@ class @AutoEnrollmentViaCsv
@$students_list_file = @$container.find("input[name='students_list']") @$students_list_file = @$container.find("input[name='students_list']")
@$csrf_token = @$container.find("input[name='csrfmiddlewaretoken']") @$csrf_token = @$container.find("input[name='csrfmiddlewaretoken']")
@$results = @$container.find("div.results") @$results = @$container.find("div.results")
@$browse_button = @$container.find("#browseBtn-auto_enroll_csv") @$browse_button = @$container.find("#browseBtn-auto-enroll")
@$browse_file = @$container.find("#browseFile") @$browse_file = @$container.find("#browseFile")
@processing = false @processing = false
......
...@@ -31,9 +31,9 @@ ...@@ -31,9 +31,9 @@
return Backbone.View.extend({ return Backbone.View.extend({
el: DOM_SELECTORS.bulk_exception, el: DOM_SELECTORS.bulk_exception,
events: { events: {
'change #browseBtn': 'chooseFile', 'change #browseBtn-bulk-csv': 'chooseFile',
'click .upload-csv-button': 'uploadCSV', 'click .upload-csv-button': 'uploadCSV',
'click a.arrow': 'toggleMessageDetails' 'click .arrow': 'toggleMessageDetails'
}, },
initialize: function(options){ initialize: function(options){
...@@ -138,7 +138,7 @@ ...@@ -138,7 +138,7 @@
$('<div/>', { $('<div/>', {
class: 'message ' + group class: 'message ' + group
}).appendTo('.bulk-exception-results').prepend( }).appendTo('.bulk-exception-results').prepend(
"<a id= '" + group + "' href='javascript:void(0);' class='arrow'> + </a>" + heading "<button type='button' id= '" + group + "' class='arrow'> + </button>" + heading
).append($('<ul/>', { ).append($('<ul/>', {
class: group class: group
})); }));
...@@ -206,7 +206,7 @@ ...@@ -206,7 +206,7 @@
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).attr('disabled', 'false'); this.$el.find(DOM_SELECTORS.upload_csv_button).removeAttr('disabled');
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));
} }
......
...@@ -136,7 +136,7 @@ define([ ...@@ -136,7 +136,7 @@ define([
this.view.$el.find(SELECTORS.bulk_white_list_exception_form).submit(submitCallback); this.view.$el.find(SELECTORS.bulk_white_list_exception_form).submit(submitCallback);
this.view.$el.find(SELECTORS.upload_csv_button).click(); this.view.$el.find(SELECTORS.upload_csv_button).click();
expect(this.view.$el.find("div.message > .successfully-added")).toBeHidden(); expect(this.view.$el.find("div.message > .successfully-added")).toBeHidden();
this.view.$el.find("a.arrow#successfully-added").trigger( "click" ); this.view.$el.find(".arrow#successfully-added").trigger( "click" );
expect(this.view.$el.find("div.message > .successfully-added")).toBeVisible(); expect(this.view.$el.find("div.message > .successfully-added")).toBeVisible();
}); });
......
...@@ -134,6 +134,70 @@ ...@@ -134,6 +134,70 @@
} }
} }
} }
.btn-blue {
@extend %btn-primary-blue;
margin-bottom: 0;
padding: ($baseline/2.5) ($baseline/2);
text-shadow: none;
}
// Custom File upload
.customBrowseBtn {
display: inline-block;
position: relative;
margin: ($baseline/2) 0 0;
width: 350px;
overflow: hidden;
vertical-align: bottom;
.enhanced-input-file {
@include border-radius(4px 0 0 4px);
@include padding(23px 6px 5px);
position: relative;
display: inline-block;
width: 250px;
vertical-align: middle;
border: 1px solid $lightGrey1;
background: $white;
cursor: not-allowed;
z-index: 2;
}
.file-browse {
@include margin-left(-4px);
display: inline-block;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
overflow: hidden;
.browse {
@include button(simple, $uxpl-blue-base);
@include margin-left(268px);
border-radius: 0 3px 3px 0;
padding: 6px ($baseline/2);
font-size: 12px;
}
.file_field {
@include left(-27%);
position: absolute;
z-index: 3;
height: 24px; // To match bull browse button
width: 124%;
margin: 0;
padding: 4px 0 0 0;
cursor: pointer;
// for visual sync, need to make button similar to firefox
&::-webkit-file-upload-button {
width: 100px;
}
}
}
}
} }
// instructor dashboard 2 // instructor dashboard 2
...@@ -2167,13 +2231,6 @@ input[name="subject"] { ...@@ -2167,13 +2231,6 @@ input[name="subject"] {
// -------------------- // --------------------
.instructor-dashboard-wrapper-2 section.idash-section#certificates { .instructor-dashboard-wrapper-2 section.idash-section#certificates {
.btn-blue {
@extend %btn-primary-blue;
padding: ($baseline/2.5) ($baseline/2);
text-shadow: none;
margin-bottom: 10px;
}
%exception-message { %exception-message {
margin-top: 15px; margin-top: 15px;
background-color: $gray-l4; background-color: $gray-l4;
...@@ -2343,47 +2400,14 @@ input[name="subject"] { ...@@ -2343,47 +2400,14 @@ input[name="subject"] {
} }
} }
.arrow { .arrow {
font-weight: bold; @include margin-right($baseline/2);
} border: none;
} background: transparent;
} box-shadow: none;
color: $uxpl-blue-base;
} font-weight: bold;
}
// Custom File upload
.customBrowseBtn {
margin: ($baseline/2) 0;
display: inline-block;
.file-browse {
position: relative;
overflow: hidden;
display: inline;
@include margin-left(-5px);
span.browse {
@include button(simple, $uxpl-blue-base);
@include margin-right($baseline);
padding: 6px ($baseline/2);
font-size: 12px;
border-radius: 0 3px 3px 0;
}
input.file_field {
@extend %cont-text-sr;
position: absolute;
@include right(0);
top: 0;
margin: 0;
padding: 0;
cursor: pointer;
} }
} }
& > span, & input[disabled] {
vertical-align: middle;
}
input[disabled] {
@include border-radius(4px 0 0 4px);
@include padding(6px 6px 5px);
border: 1px solid $lightGrey1;
cursor: not-allowed;
}
} }
...@@ -4,14 +4,15 @@ ...@@ -4,14 +4,15 @@
<%- 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.") %> <%- 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">
<input disabled="disabled" class="browse-file" placeholder="<%- gettext("Choose File") %>" /> <label for="browseBtn-bulk-csv"><%- gettext("Upload a CSV file") %></label>
<div class="file-browse btn btn-primary"> <span class="browse-file enhanced-input-file" id="bulk-exception-upload"></span>
<label for="browseBtn-bulk-exc-students" class="browse"><%- gettext("Browse") %></label> <div class="file-browse btn btn-primary" aria-hidden="true">
<input class="file_field" id="browseBtn-bulk-exc-students" name="students_list" type="file" accept=".csv"/> <span class="browse"><%- gettext("Browse") %></span>
<input class="file_field" id="browseBtn-bulk-csv" name="students_list" type="file" accept=".csv"/>
</div>
</div> </div>
</div> <button type="submit" class="btn-blue upload-csv-button"><%- gettext("Add to Exception List") %></button>
<div><button class="btn-blue upload-csv-button" type="submit"><%- gettext('Add to Exception List') %></button></div>
</form> </form>
<div class="bulk-exception-results hidden"></div> <div class="bulk-exception-results hidden"></div>
</div> </div>
...@@ -3,9 +3,16 @@ ...@@ -3,9 +3,16 @@
</p> </p>
<div class="add-certificate-invalidation"> <div class="add-certificate-invalidation">
<input class='student-username-or-email' id="certificate-invalidation-user" type="text" placeholder="<%- gettext('Username or email address') %>"> <div>
<textarea class='notes-field' id="certificate-invalidation-notes" rows="10" placeholder="<%- gettext('Add notes about this learner') %>"></textarea> <label for="certificate-invalidation-user"><%- gettext('Username or email address') %></label>
<input class="student-username-or-email" id="certificate-invalidation-user" type="text">
</div>
<div>
<label for="certificate-invalidation-notes"><%- gettext('Add notes about this learner') %></label>
<textarea class="notes-field" id="certificate-invalidation-notes" rows="10"></textarea>
</div>
<br/> <br/>
<button type="button" class="btn-blue" id="invalidate-certificate"><%- gettext('Invalidate Certificate') %></button> <button type="button" class="btn-blue" id="invalidate-certificate"><%- gettext('Invalidate Certificate') %></button>
</div> </div>
......
...@@ -2,11 +2,14 @@ ...@@ -2,11 +2,14 @@
<p class="under-heading"> <%- gettext("Enter the username or email address of each learner that you want to add as an exception.") %></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=""> <div class="">
<input class='student-username-or-email' id="certificate-exception" type="text" placeholder="Student email or username"> <label for="certificate-exception" class="sr"><%- gettext("Student email or username") %></label>
<textarea class='notes-field' id="notes" rows="10" placeholder="Free text notes"></textarea> <input class="student-username-or-email" id="certificate-exception" type="text" placeholder="<%- gettext('Student email or username') %>">
<label for="notes" class="sr"><%- gettext('Free text notes') %></label>
<textarea class="notes-field" id="notes" rows="10" placeholder="<%- gettext('Free text notes') %>"></textarea>
</div> </div>
<div> <div>
<button type="button" class="btn-blue" id="add-exception" ><%- gettext("Add to Exception List") %> </button> <button type="button" class="btn-blue" id="add-exception"><%- gettext("Add to Exception List") %></button>
</div> </div>
<div class='message hidden'></div> <div class='message hidden'></div>
</div> </div>
...@@ -51,59 +51,59 @@ from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_str ...@@ -51,59 +51,59 @@ from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_str
</div> </div>
% if not section_data['is_self_paced']: % if not section_data['is_self_paced']:
<hr /> <hr />
<div class="enable-certificates"> <div class="enable-certificates">
<h3 class="hd hd-3">${_("Student-Generated Certificates")}</h3> <h3 class="hd hd-3">${_("Student-Generated Certificates")}</h3>
% if section_data['enabled_for_course']: % if section_data['enabled_for_course']:
<form id="enable-certificates-form" method="post" action="${section_data['urls']['enable_certificate_generation']}"> <form id="enable-certificates-form" method="post" action="${section_data['urls']['enable_certificate_generation']}">
<input type="hidden" name="csrfmiddlewaretoken" value="${csrf_token}"> <input type="hidden" name="csrfmiddlewaretoken" value="${csrf_token}">
<input type="hidden" id="certificates-enabled" name="certificates-enabled" value="false" /> <input type="hidden" id="certificates-enabled" name="certificates-enabled" value="false" />
<input type="submit" class="btn-blue" id="disable-certificates-submit" value="${_('Disable Student-Generated Certificates')}"/> <input type="submit" class="btn-blue" id="disable-certificates-submit" value="${_('Disable Student-Generated Certificates')}"/>
</form> </form>
% elif section_data['can_enable_for_course']: % elif section_data['can_enable_for_course']:
<form id="enable-certificates-form" method="post" action="${section_data['urls']['enable_certificate_generation']}"> <form id="enable-certificates-form" method="post" action="${section_data['urls']['enable_certificate_generation']}">
<input type="hidden" name="csrfmiddlewaretoken" value="${csrf_token}"> <input type="hidden" name="csrfmiddlewaretoken" value="${csrf_token}">
<input type="hidden" id="certificates-enabled" name="certificates-enabled" value="true" /> <input type="hidden" id="certificates-enabled" name="certificates-enabled" value="true" />
<input type="submit" class="btn-blue" id="enable-certificates-submit" value="${_('Enable Student-Generated Certificates')}"/> <input type="submit" class="btn-blue" id="enable-certificates-submit" value="${_('Enable Student-Generated Certificates')}"/>
</form> </form>
% else: % else:
<p>${_("You must successfully generate example certificates before you enable student-generated certificates.")}</p> <p>${_("You must successfully generate example certificates before you enable student-generated certificates.")}</p>
<button class="is-disabled" disabled>${_('Enable Student-Generated Certificates')}</button> <button class="is-disabled" disabled>${_('Enable Student-Generated Certificates')}</button>
% endif % endif
</div> </div>
% endif % endif
% if section_data['instructor_generation_enabled'] and not (section_data['enabled_for_course'] and section_data['html_cert_enabled']): % if section_data['instructor_generation_enabled'] and not (section_data['enabled_for_course'] and section_data['html_cert_enabled']):
<hr class="section-divider" /> <hr class="section-divider" />
<div class="start-certificate-generation"> <div class="start-certificate-generation">
<h3 class="hd hd-3">${_("Generate Certificates")}</h3> <h3 class="hd hd-3">${_("Generate Certificates")}</h3>
<form id="certificates-generating-form" method="post" action="${section_data['urls']['start_certificate_generation']}"> <form id="certificates-generating-form" method="post" action="${section_data['urls']['start_certificate_generation']}">
% if section_data['html_cert_enabled'] and section_data['active_certificate'] is None: % if section_data['html_cert_enabled'] and section_data['active_certificate'] is None:
<p>${_("Course certificate generation requires an activated web certificate configuration.")}</p> <p>${_("Course certificate generation requires an activated web certificate configuration.")}</p>
<input type="button" id="disabled-btn-start-generating-certificates" class="is-disabled" aria-disabled="true" value="${_('Generate Certificates')}"/> <input type="button" id="disabled-btn-start-generating-certificates" class="is-disabled" aria-disabled="true" value="${_('Generate Certificates')}"/>
% else: % else:
<p class="under-heading"> <p class="under-heading">
${_("When you are ready to generate certificates for your course, click Generate Certificates. You do not need to do this if you have set the certificate mode to on-demand generation.")} ${_("When you are ready to generate certificates for your course, click Generate Certificates. You do not need to do this if you have set the certificate mode to on-demand generation.")}
</p> </p>
<input type="button" class="btn-blue" id="btn-start-generating-certificates" value="${_('Generate Certificates')}" data-endpoint="${section_data['urls']['start_certificate_generation']}"/> <input type="button" class="btn-blue" id="btn-start-generating-certificates" value="${_('Generate Certificates')}" data-endpoint="${section_data['urls']['start_certificate_generation']}"/>
%endif %endif
</form> </form>
<div class="certificate-generation-status"></div> <div class="certificate-generation-status"></div>
</div> </div>
%if settings.FEATURES.get('ENABLE_INSTRUCTOR_BACKGROUND_TASKS'): %if settings.FEATURES.get('ENABLE_INSTRUCTOR_BACKGROUND_TASKS'):
<div class="running-tasks-container action-type-container"> <div class="running-tasks-container action-type-container">
<hr> <hr>
<h3 class="hd hd-3"> ${_("Pending Tasks")} </h3> <h3 class="hd hd-3"> ${_("Pending Tasks")} </h3>
<div class="running-tasks-section"> <div class="running-tasks-section">
<p>${_("The status for any active tasks appears in a table below.")} </p> <p>${_("The status for any active tasks appears in a table below.")} </p>
<br /> <br />
<div class="running-tasks-table" data-endpoint="${ section_data['urls']['list_instructor_tasks_url'] }"></div> <div class="running-tasks-table" data-endpoint="${ section_data['urls']['list_instructor_tasks_url'] }"></div>
</div>
<div class="no-pending-tasks-message"></div>
</div> </div>
<div class="no-pending-tasks-message"></div>
</div>
%endif %endif
% endif % endif
...@@ -135,6 +135,7 @@ from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_str ...@@ -135,6 +135,7 @@ from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_str
<input type="button" class="btn-blue" id="btn-start-regenerating-certificates" value="${_('Regenerate Certificates')}" data-endpoint="${section_data['urls']['start_certificate_regeneration']}"/> <input type="button" class="btn-blue" id="btn-start-regenerating-certificates" value="${_('Regenerate Certificates')}" data-endpoint="${section_data['urls']['start_certificate_regeneration']}"/>
</form> </form>
<div class="certificate-regeneration-status"></div> <div class="certificate-regeneration-status"></div>
</div>
<hr> <hr>
<div class="certificate-generation-history"> <div class="certificate-generation-history">
......
...@@ -92,15 +92,14 @@ from openedx.core.djangoapps.course_groups.partition_scheme import get_cohorted_ ...@@ -92,15 +92,14 @@ from openedx.core.djangoapps.course_groups.partition_scheme import get_cohorted_
<p>${_("To register and enroll a list of users in this course, choose a CSV file that contains the following columns in this exact order: email, username, name, and country. Please include one student per row and do not include any headers, footers, or blank lines.")}</p> <p>${_("To register and enroll a list of users in this course, choose a CSV file that contains the following columns in this exact order: email, username, name, and country. Please include one student per row and do not include any headers, footers, or blank lines.")}</p>
<form id="student-auto-enroll-form" method="post" action="${ section_data['upload_student_csv_button_url'] }" enctype="multipart/form-data"> <form id="student-auto-enroll-form" method="post" action="${ section_data['upload_student_csv_button_url'] }" enctype="multipart/form-data">
<div class="customBrowseBtn"> <div class="customBrowseBtn">
<label for="browseFile" class="sr">${_("Upload a CSV for bulk enrollment")}</label> <label for="browseBtn-auto-enroll">${_("Upload a CSV for bulk enrollment")}</label>
<input disabled="disabled" id="browseFile" placeholder="choose file" /> <span id="browseFile" class="enhanced-input-file"></span>
<div class="file-browse btn btn-primary"> <div class="file-browse btn btn-primary" aria-hidden="true">
<span class="browse"> Browse </span> <span class="browse">${('Browse')}</span>
<label for="browseBtn-auto_enroll_csv" class="sr">${_("Upload a CSV for bulk enrollment")}</label> <input class="file_field" id="browseBtn-auto-enroll" name="students_list" type="file" accept=".csv"/>
<input class="file_field" id="browseBtn-auto_enroll_csv" name="students_list" type="file" accept=".csv"/>
</div> </div>
</div> </div>
<button type="submit" id="submitBtn-auto_enroll_csv" name="enrollment_signup_button">${_("Upload CSV")}</button> <button type="submit" class="btn-blue" id="submitBtn-auto_enroll_csv" name="enrollment_signup_button">${_("Upload CSV")}</button>
<input type="hidden" name="csrfmiddlewaretoken" value="${ csrf_token }"> <input type="hidden" name="csrfmiddlewaretoken" value="${ csrf_token }">
</form> </form>
<div class="results"></div> <div class="results"></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