Files
edx-platform/cms/static/js/views/assets.js
Eric Fischer 5bc6b31e29 eslint --fix
2017-12-08 14:38:41 -05:00

360 lines
16 KiB
JavaScript

define([
'jquery',
'underscore',
'gettext',
'edx-ui-toolkit/js/utils/html-utils',
'js/views/baseview',
'js/models/asset',
'js/views/paging',
'js/views/asset',
'js/views/paging_header',
'common/js/components/views/paging_footer',
'js/utils/modal',
'common/js/components/utils/view_utils',
'common/js/components/views/feedback_notification',
'text!templates/asset-library.underscore',
'jquery.fileupload-process',
'jquery.fileupload-validate'
],
function($, _, gettext, HtmlUtils, BaseView, AssetModel, PagingView, AssetView, PagingHeader, PagingFooter,
ModalUtils, ViewUtils, NotificationView, asset_library_template) {
var CONVERSION_FACTOR_MBS_TO_BYTES = 1000 * 1000;
var AssetsView = BaseView.extend({
// takes AssetCollection as model
events: {
'click .column-sort-link': 'onToggleColumn',
'click .upload-button': 'showUploadModal',
'click .filterable-column .nav-item': 'onFilterColumn',
'click .filterable-column .column-filter-link': 'toggleFilterColumn'
},
typeData: ['Images', 'Documents'],
allLabel: 'ALL',
initialize: function(options) {
options = options || {};
BaseView.prototype.initialize.call(this);
var collection = this.collection;
this.pagingView = this.createPagingView();
this.listenTo(collection, 'destroy', this.handleDestroy);
ViewUtils.showLoadingIndicator();
// set default file size for uploads via template var,
// and default to static old value if none exists
this.uploadChunkSizeInMBs = options.uploadChunkSizeInMBs || 10;
this.maxFileSizeInMBs = options.maxFileSizeInMBs || 10;
this.uploadChunkSizeInBytes = this.uploadChunkSizeInMBs * CONVERSION_FACTOR_MBS_TO_BYTES;
this.maxFileSizeInBytes = this.maxFileSizeInMBs * CONVERSION_FACTOR_MBS_TO_BYTES;
this.maxFileSizeRedirectUrl = options.maxFileSizeRedirectUrl || '';
// error message modal for large file uploads
this.largeFileErrorMsg = null;
},
PagingAssetView: PagingView.extend({
renderPageItems: function() {
var self = this,
assets = this.collection,
hasAssets = this.collection.assetType !== '' || assets.length > 0,
tableBody = this.getTableBody();
tableBody.empty();
if (hasAssets) {
assets.each(
function(asset) {
var view = new AssetView({model: asset});
tableBody.append(view.render().el);
}
);
}
self.$('.assets-library').toggle(hasAssets);
self.$('.no-asset-content').toggle(!hasAssets);
return this;
},
getTableBody: function() {
var tableBody = this.tableBody;
if (!tableBody) {
ViewUtils.hideLoadingIndicator();
// Create the table
HtmlUtils.setHtml(
this.$el,
HtmlUtils.template(asset_library_template)({typeData: this.typeData})
);
tableBody = this.$('#asset-table-body');
this.tableBody = tableBody;
this.pagingHeader = new PagingHeader({view: this, el: $('#asset-paging-header')});
this.pagingFooter = new PagingFooter({collection: this.collection, el: $('#asset-paging-footer')});
this.pagingHeader.render();
this.pagingFooter.render();
// Hide the contents until the collection has loaded the first time
this.$('.assets-library').hide();
this.$('.no-asset-content').hide();
}
return tableBody;
},
onError: function() {
ViewUtils.hideLoadingIndicator();
}
}),
createPagingView: function() {
var pagingView = new this.PagingAssetView({
el: this.$el,
collection: this.collection
});
pagingView.registerSortableColumn('js-asset-name-col', gettext('Name'), 'display_name', 'asc');
pagingView.registerSortableColumn('js-asset-date-col', gettext('Date Added'), 'date_added', 'desc');
pagingView.registerFilterableColumn('js-asset-type-col', gettext('Type'), 'asset_type');
pagingView.setInitialSortColumn('js-asset-date-col');
pagingView.setInitialFilterColumn('js-asset-type-col');
pagingView.setPage(1);
return pagingView;
},
render: function() {
this.pagingView.render();
return this;
},
afterRender: function() {
// Bind events with html elements
$('li a.upload-button').on('click', _.bind(this.showUploadModal, this));
$('.upload-modal .close-button').on('click', _.bind(this.hideModal, this));
$('.upload-modal .choose-file-button').on('click', _.bind(this.showFileSelectionMenu, this));
return this;
},
handleDestroy: function(model) {
this.collection.fetch({reset: true}); // reload the collection to get a fresh page full of items
analytics.track('Deleted Asset', {
course: course_location_analytics,
id: model.get('url')
});
},
addAsset: function(model) {
// Switch the sort column back to the default (most recent date added) and show the first page
// so that the new asset is shown at the top of the page.
this.pagingView.setInitialSortColumn('js-asset-date-col');
this.pagingView.setInitialFilterColumn('js-asset-type-col');
this.pagingView.setPage(1);
analytics.track('Uploaded a File', {
course: course_location_analytics,
asset_url: model.get('url')
});
},
onToggleColumn: function(event) {
var columnName = event.target.id;
this.pagingView.toggleSortOrder(columnName);
},
onFilterColumn: function(event) {
this.openFilterColumn($(event.currentTarget));
event.stopPropagation();
},
hideModal: function(event) {
if (event) {
event.preventDefault();
}
$('.file-input').unbind('change.startUpload');
ModalUtils.hideModal();
if (this.largeFileErrorMsg) {
this.largeFileErrorMsg.hide();
}
},
showUploadModal: function(event) {
var self = this;
event.preventDefault();
self.resetUploadModal();
ModalUtils.showModal();
$('.modal-cover').on('click', self.hideModal);
$('.file-input').bind('change', self.startUpload);
$('.upload-modal .file-chooser').fileupload({
dataType: 'json',
type: 'POST',
maxChunkSize: self.uploadChunkSizeInBytes,
autoUpload: true,
progressall: function(event, data) {
var percentComplete = parseInt((100 * data.loaded) / data.total, 10);
self.showUploadFeedback(event, percentComplete);
},
maxFileSize: self.maxFileSizeInBytes,
maxNumberofFiles: 100,
done: function(event, data) {
self.displayFinishedUpload(data.result);
},
processfail: function(event, data) {
var filename = data.files[data.index].name;
var error = gettext('File {filename} exceeds maximum size of {maxFileSizeInMBs} MB')
.replace('{filename}', filename)
.replace('{maxFileSizeInMBs}', self.maxFileSizeInMBs);
// disable second part of message for any falsy value,
// which can be null or an empty string
if (self.maxFileSizeRedirectUrl) {
var instructions = gettext('Please follow the instructions here to upload a file elsewhere and link to it: {maxFileSizeRedirectUrl}')
.replace('{maxFileSizeRedirectUrl}', self.maxFileSizeRedirectUrl);
error = error + ' ' + instructions;
}
self.largeFileErrorMsg = new NotificationView.Error({
title: gettext('Your file could not be uploaded'),
message: error
});
self.largeFileErrorMsg.show();
self.displayFailedUpload({
msg: gettext('Max file size exceeded')
});
},
processdone: function(event, data) {
self.largeFileErrorMsg = null;
}
});
},
showFileSelectionMenu: function(event) {
event.preventDefault();
if (this.largeFileErrorMsg) {
this.largeFileErrorMsg.hide();
}
$('.file-input').click();
},
startUpload: function(event) {
var file = event.target.value;
if (!this.largeFileErrorMsg) {
$('.upload-modal h1').text(gettext('Uploading'));
$('.upload-modal .file-name').text(file.substring(file.lastIndexOf('\\') + 1));
$('.upload-modal .choose-file-button').hide();
$('.upload-modal .progress-bar').removeClass('loaded').show();
}
},
resetUploadModal: function() {
// Reset modal so it no longer displays information about previously
// completed uploads.
var percentVal = '0%',
$progressFill = $('.upload-modal .progress-fill'),
$fileName = $('.upload-modal .file-name');
$progressFill.width(percentVal);
$progressFill.text(percentVal);
$('.upload-modal .progress-bar').hide();
$fileName.show();
$fileName.text('');
$('.upload-modal .choose-file-button').text(gettext('Choose File'));
$('.upload-modal .embeddable-xml-input').val('');
$('.upload-modal .embeddable').hide();
this.largeFileErrorMsg = null;
},
showUploadFeedback: function(event, percentComplete) {
var percentVal = percentComplete + '%',
$progressFill = $('.upload-modal .progress-fill');
$progressFill.width(percentVal);
$progressFill.text(percentVal);
},
openFilterColumn: function($this) {
this.toggleFilterColumnState($this);
},
toggleFilterColumnState: function(menu, selected) {
var $subnav = menu.find('.wrapper-nav-sub');
var $title = menu.find('.title');
var titleText = $title.find('.type-filter');
var assettype = selected ? selected.data('assetfilter') : false;
if (assettype) {
if (assettype === this.allLabel) {
titleText.text(titleText.data('alllabel'));
} else {
titleText.text(assettype);
}
}
if ($subnav.hasClass('is-shown')) {
$subnav.removeClass('is-shown');
$title.removeClass('is-selected');
} else {
$title.addClass('is-selected');
$subnav.addClass('is-shown');
}
},
toggleFilterColumn: function(event) {
event.preventDefault();
var $filterColumn = $(event.currentTarget);
this._toggleFilterColumn($filterColumn.data('assetfilter'), $filterColumn.text());
},
_toggleFilterColumn: function(assettype, assettypeLabel) {
var collection = this.collection;
var filterColumn = this.$el.find('.filterable-column');
var resetFilter = filterColumn.find('.reset-filter');
var title = filterColumn.find('.title');
if (assettype === this.allLabel) {
collection.assetType = '';
resetFilter.hide();
title.removeClass('column-selected-link');
} else {
collection.assetType = assettype;
resetFilter.show();
title.addClass('column-selected-link');
}
this.pagingView.filterableColumns['js-asset-type-col'].displayName = assettypeLabel;
this.pagingView.selectFilter('js-asset-type-col');
this.closeFilterPopup(this.$el.find(
'.column-filter-link[data-assetfilter="' + assettype + '"]'));
},
closeFilterPopup: function(element) {
var $menu = element.parents('.nav-dd > .nav-item');
this.toggleFilterColumnState($menu, element);
},
displayFinishedUpload: function(resp) {
var asset = resp.asset,
$progressFill = $('.upload-modal .progress-fill');
$('.upload-modal h1').text(gettext('Upload New File'));
$('.upload-modal .embeddable-xml-input').val(asset.portable_url).show();
$('.upload-modal .embeddable').show();
$('.upload-modal .file-name').hide();
$progressFill.text(resp.msg);
$('.upload-modal .choose-file-button').text(gettext('Load Another File')).show();
$progressFill.width('100%');
this.addAsset(new AssetModel(asset));
},
displayFailedUpload: function(resp) {
var $progressFill = $('.upload-modal .progress-fill');
$('.upload-modal h1').text(gettext('Upload New File'));
$('.upload-modal .embeddable-xml-input').hide();
$('.upload-modal .embeddable').hide();
$('.upload-modal .file-name').hide();
$progressFill.text(resp.msg);
$('.upload-modal .choose-file-button').text(gettext('Load Another File')).show();
$progressFill.width('0%');
}
});
return AssetsView;
});