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:
@@ -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('');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) -->
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user