Team Management Upload A11y Improvements (#23502)

* Expose team management file input for better a11y
* Disable upload button when file not selected
This commit is contained in:
Nathan Sprenkle
2020-03-30 17:03:15 -04:00
committed by GitHub
parent 5edc8fd380
commit 02392879b7
4 changed files with 49 additions and 47 deletions

View File

@@ -11,7 +11,7 @@ define([
describe('Team Management Dashboard', function() {
var view;
var uploadFile = new File([], 'empty-test-file.csv');
var mockUploadClickEvent = {target: {files: [uploadFile]}};
var mockFileSelectEvent = {target: {files: [uploadFile]}};
beforeEach(function() {
setFixtures('<div class="teams-container"></div>');
@@ -24,13 +24,14 @@ define([
});
it('can render itself', function() {
expect(_.strip(view.$('.download-team-csv').text())).toEqual('Download Memberships');
expect(_.strip(view.$('.upload-team-csv').text())).toEqual('Upload Memberships');
expect(_.strip(view.$('#download-team-csv').text())).toEqual('Download Memberships');
expect(_.strip(view.$('#upload-team-csv').text())).toEqual('Upload Memberships');
});
it('can handle a successful file upload', function() {
var requests = AjaxHelpers.requests(this);
view.uploadCsv(mockUploadClickEvent);
view.setTeamMembershipCsv(mockFileSelectEvent);
view.uploadCsv();
AjaxHelpers.expectRequest(requests, 'POST', view.csvUploadUrl);
AjaxHelpers.respondWithJson(requests, {});
expect(view.handleCsvUploadSuccess).toHaveBeenCalled();
@@ -38,15 +39,11 @@ define([
it('can handle a failed file upload', function() {
var requests = AjaxHelpers.requests(this);
view.uploadCsv(mockUploadClickEvent);
view.setTeamMembershipCsv(mockFileSelectEvent);
view.uploadCsv();
AjaxHelpers.expectRequest(requests, 'POST', view.csvUploadUrl);
AjaxHelpers.respondWithError(requests);
expect(view.handleCsvUploadFailure).toHaveBeenCalled();
});
it('should clear input file after upload to allow reuploading', function() {
view.uploadCsv(mockUploadClickEvent);
expect(view.$('#upload-team-csv-input').prop('value')).toEqual('');
});
});
});

View File

@@ -17,8 +17,9 @@
},
events: {
'click #download-team-csv-input': 'downloadCsv',
'change #upload-team-csv-input': ViewUtils.withDisabledElement('uploadCsv')
'click #download-team-csv': 'downloadCsv',
'change #upload-team-csv-input': 'setTeamMembershipCsv',
'click #upload-team-csv': ViewUtils.withDisabledElement('uploadCsv')
},
initialize: function(options) {
@@ -39,33 +40,38 @@
window.location.href = this.csvDownloadUrl;
},
uploadCsv: function(event) {
var file = event.target.files[0];
var self = this;
setTeamMembershipCsv: function(event) {
this.membershipFile = event.target.files[0];
// enable the upload button when a file is selected
if (this.membershipFile) {
$('#upload-team-csv').removeClass('is-disabled').attr('aria-disabled', false);
} else {
$('#upload-team-csv').addClass('is-disabled').attr('aria-disabled', true);
}
},
uploadCsv: function() {
var formData = new FormData();
formData.append('csv', this.membershipFile); // xss-lint: disable=javascript-jquery-append
// clear selected file to allow re-uploading
$(event.target).prop('value', '');
formData.append('csv', file); // xss-lint: disable=javascript-jquery-append
return $.ajax({
type: 'POST',
url: self.csvUploadUrl,
url: this.csvUploadUrl,
data: formData,
processData: false, // tell jQuery not to process the data
contentType: false // tell jQuery not to set contentType
}).done(
self.handleCsvUploadSuccess
this.handleCsvUploadSuccess
).fail(
self.handleCsvUploadFailure
this.handleCsvUploadFailure
);
},
handleCsvUploadSuccess: function(data) {
TeamUtils.showInfoBanner(data.message, false);
// This handler is currently unimplemented (TODO MST-44)
this.teamEvents.trigger('teams:update', {});
// Implement a teams:update event (TODO MST-44)
},
handleCsvUploadFailure: function(jqXHR) {

View File

@@ -11,7 +11,7 @@
) %>
</p>
<button
id="download-team-csv-input"
id="download-team-csv"
class="download-team-csv action action-primary"
>
<%- gettext("Download Memberships") %>
@@ -27,13 +27,16 @@
"users to teams."
) %>
</p>
<button class="upload-team-csv btn action action-primary">
<input
id="upload-team-csv-input"
type="file"
accept="text/csv"
class="input-overlay-hack"
/>
<input
id="upload-team-csv-input"
type="file"
accept="text/csv"
/>
<button
id="upload-team-csv"
class="btn action action-primary is-disabled"
aria-disabled="true"
>
<%- gettext("Upload Memberships") %>
</button>
<!-- We need to describe the format of the CSV here (TODO MST-49) -->

View File

@@ -356,26 +356,21 @@
.team-management {
padding: 1%;
h3, p, .action, .team-management-section {
margin-bottom: 2%;
h3,
p,
.action,
.team-management-section,
input {
margin-bottom: 2%;
}
.input-overlay-hack {
position: absolute;
height: 100%;
width: 100%;
opacity: 0;
top: 0;
left: 0;
cursor: pointer;
}
.upload-team-csv {
position: relative;
#upload-team-csv {
display: block;
}
}
.team-profile, .team-management {
.team-profile,
.team-management {
.page-content-main {
display: inline-block;
width: flex-grid(8, 12);
@@ -554,6 +549,7 @@
border: inherit;
box-shadow: none;
}
display: inline-block;
text-shadow: none;
}