diff --git a/static/scripts/mvc/upload/upload-ftp.js b/static/scripts/mvc/upload/upload-ftp.js index 62bf8584238..7a1242d9d3b 100644 --- a/static/scripts/mvc/upload/upload-ftp.js +++ b/static/scripts/mvc/upload/upload-ftp.js @@ -35,6 +35,7 @@ return Backbone.View.extend({ // fill table _fill: function(ftp_files) { + var self = this; if (ftp_files && ftp_files.length > 0) { // add table this.$el.find('#upload-ftp-content').html($(this._templateTable())); @@ -49,11 +50,43 @@ return Backbone.View.extend({ // update stats this.$el.find('#upload-ftp-number').html(ftp_files.length + ' files'); this.$el.find('#upload-ftp-disk').html(Utils.bytesToString (size, true)); + + var selectAll = this.$el.find('#selectAll'); + + // call method to determine and set selectAll status on loading + this._updateSelectAll(selectAll); + + // selectAll checkbox has been clicked + selectAll.on('click', function() { + var checkboxes=$(this).parents().find('tr.upload-ftp-row>td>div'); + var len = checkboxes.length; + $this = $(this); + var allChecked = !($this.hasClass('fa-check-square-o')); + + // change state of the sub-checkboxes + for(i = 0; i < len; i++) { + if(allChecked) { + // all checkboxes should be checked + if(checkboxes.eq(i).hasClass('fa-square-o')) { + // if they are not checked, check them + checkboxes.eq(i).trigger('updateUpBox'); + } + } else { + // no checkboxes should be checked + if(checkboxes.eq(i).hasClass('fa-check-square-o')) { + // if they are checked, uncheck them + checkboxes.eq(i).trigger('updateUpBox'); + } + } + } + + self._updateSelectAll(selectAll); + }); } else { // add info this.$el.find('#upload-ftp-content').html($(this._templateInfo())); } - + // hide spinner this.$el.find('#upload-ftp-wait').hide(); }, @@ -79,18 +112,18 @@ return Backbone.View.extend({ } else { icon_class = this.options.class_add; } - + // add icon class $icon.addClass(icon_class); - - // click to add ftp files - $it.on('click', function() { + + // add files to the uploadbox + $it.on('updateUpBox', function() { // find model var model_index = self._find(ftp_file); - + // update icon $icon.removeClass(); - + // add model if (!model_index) { // add to uploadbox @@ -100,19 +133,55 @@ return Backbone.View.extend({ size : ftp_file.size, path : ftp_file.path }]); - + // add new icon class $icon.addClass(self.options.class_remove); } else { // remove self.app.collection.remove(model_index); - + // add new icon class $icon.addClass(self.options.class_add); } }); + + // click to add ftp files + $it.on('click', function() { + //trigger my new event + $icon.trigger('updateUpBox'); + + // click to add ftp files + // modify selectAll box based on number of checkboxes checked + var selectBox=$icon.parents().find('#selectAll'); + // determine and set state of selectAll after sub-checkbox clicked + self._updateSelectAll(selectBox); + }); }, - + + _updateSelectAll: function(selectBox) { + // array of all checkboxes + var checkboxes=selectBox.parents().find('tr.upload-ftp-row>td>div'); + // array of only checked checkboxes + var checkedCheckboxes=selectBox.parents().find('tr.upload-ftp-row>td>div.fa-check-square-o'); + var lenAll = checkboxes.length; + var lenChecked = checkedCheckboxes.length; + + // determine which state the selectAll checkbox needs to be and setting it + if(lenChecked > 0 && lenChecked !== lenAll) { + // indeterminate state + selectBox.removeClass('fa-square-o fa-check-square-o'); + selectBox.addClass('fa-minus-square-o'); + } else if(lenChecked === lenAll) { + // checked state + selectBox.removeClass('fa-square-o fa-minus-square-o'); + selectBox.addClass('fa-check-square-o'); + } else if(lenChecked === 0) { + // unchecked state + selectBox.removeClass('fa-check-square-o fa-minus-square-o'); + selectBox.addClass('fa-square-o'); + } + }, + // get model index _find: function(ftp_file) { // check if exists already @@ -149,7 +218,7 @@ return Backbone.View.extend({ '' + '' + '' + - '' + + '' + '' + '' + '' + diff --git a/static/scripts/mvc/upload/upload-model.js b/static/scripts/mvc/upload/upload-model.js index 0acf8a36c2e..6d1757e3582 100644 --- a/static/scripts/mvc/upload/upload-model.js +++ b/static/scripts/mvc/upload/upload-model.js @@ -14,6 +14,7 @@ var Model = Backbone.Model.extend({ file_type : null, file_path : '', percentage : 0, + row : null, // settings space_to_tabs : false, diff --git a/static/scripts/mvc/upload/upload-row.js b/static/scripts/mvc/upload/upload-row.js index d7f9c385e80..ce40eb8ac12 100644 --- a/static/scripts/mvc/upload/upload-row.js +++ b/static/scripts/mvc/upload/upload-row.js @@ -42,6 +42,9 @@ return Backbone.View.extend({ // link app this.app = app; + // default value for extension of files + var default_ext = 'Auto-detect'; + // link this var self = this; @@ -75,15 +78,28 @@ return Backbone.View.extend({ // initialize genome this.model.set('genome', self.select_genome.value()); + // ensure files added after an individual row has changed + // default to Auto-detect instead of --- + if(!(this.app.select_extension.value() === '---')){ + this.default_ext = this.app.select_extension.value(); + } + // select extension this.select_extension = new Select.View({ css: 'extension', onchange : function() { self.model.set('extension', self.select_extension.value()); + // if user has changed individual row type, then change "set all" + // type to '---' + if(!(self.select_extension.value() === app.select_extension.value())) + { + var newExte = '---'; + app.select_extension.value(newExte); + } }, data: self.app.list_extensions, container: it.find('#extension'), - value: self.model.get('extension') + value: self.default_ext }); // initialize extension @@ -139,6 +155,7 @@ return Backbone.View.extend({ this.app.collection.on('reset', function() { self.remove(); }); + self.model.set('row', self); }, // render diff --git a/static/scripts/mvc/upload/upload-view.js b/static/scripts/mvc/upload/upload-view.js index bbec3bdad75..3aead73b2aa 100644 --- a/static/scripts/mvc/upload/upload-view.js +++ b/static/scripts/mvc/upload/upload-view.js @@ -6,6 +6,7 @@ define(["utils/utils", "mvc/upload/upload-ftp", "mvc/ui/ui-popover", "mvc/ui/ui-modal", + "mvc/ui/ui-select", "utils/uploadbox"], function( Utils, @@ -14,7 +15,8 @@ define(["utils/utils", UploadItem, UploadFtp, Popover, - Modal + Modal, + Select ) { // galaxy upload @@ -35,6 +37,9 @@ return Backbone.View.extend({ // current history current_history: null, + + // extension selector + select_extension : null, // current upload size upload_size: 0, @@ -119,11 +124,19 @@ return Backbone.View.extend({ description_url : datatypes[key].description_url }); } - + // sort self.list_extensions.sort(function(a, b) { return a.id > b.id ? 1 : a.id < b.id ? -1 : 0; }); + + // add the '---' extension for use when the row types are changed individually + self.list_extensions.push({ + id : "---", + text : "---", + description : "", + description_url : "" + }); // add auto field if (!self.options.datatypes_disable_auto) { @@ -218,6 +231,29 @@ return Backbone.View.extend({ title : 'FTP files', container : button }); + + // select extension + this.select_extension = new Select.View({ + css: 'extension', + onchange : function() { + var newExten = self.select_extension.value() + var len = self.collection.models.length; + // Only trigger changing the rows if the "set all" isn't set to '---' + // Prevents recursively changing the rows after an individual row has been changed + if(!(newExten === '---')){ + for(i = 0; i < len; i++){ + self.collection.models[i].attributes['row'].select_extension.value(newExten); + } + } + }, + data: self.list_extensions, + container: self.$el.parents().find('#extension'), + value: self.list_extensions[0] + }); + + // handle extension info popover + self.$el.parents().find('#extension-info_out').on('click' , function(e) { self._showExtensionInfo(); }) + .on('mousedown', function(e) { e.preventDefault(); }); } // show modal @@ -230,6 +266,60 @@ return Backbone.View.extend({ this._updateScreen(); }, + _showExtensionInfo : function() { + // initialize + var self = this; + var $el = $(this.el).parents().find('#extension-info_out'); + var extension = self.select_extension.value(); + + var title = this.select_extension.text(); + + var description = _.findWhere(self.list_extensions, {'id': extension}); + + // create popup + if (!this.extension_popup) { + this.extension_popup = new Popover.View({ + placement: 'bottom', + container: $el + }); + } + + // show / hide popup + if (!this.extension_popup.visible) { + this.extension_popup.title(title); + this.extension_popup.empty(); + this.extension_popup.append(this._templateDescription(description)); + this.extension_popup.show(); + } else { + this.extension_popup.hide(); + } + }, + + _showSettings : function() { + // check if popover is visible + if (!this.settings.visible) { + // show popover + this.settings.empty(); + this.settings.append((new UploadSettings(this)).$el); + this.settings.show(); + } else { + // hide popover + this.settings.hide(); + } + }, + + _templateDescription: function(options) { + if (options.description) { + var tmpl = options.description; + if (options.description_url) { + tmpl += ' (read more)'; + } + return tmpl; + } else { + return 'There is no description available for this file extension.'; + } + }, + // // events triggered by collection // @@ -513,6 +603,9 @@ return Backbone.View.extend({ // remove from queue this.uploadbox.reset(); + + // reset value for universal type drop-down + this.select_extension.value(this.list_extensions[0]); // reset button this.ui_button.set('percentage', 0); @@ -606,7 +699,12 @@ return Backbone.View.extend({ // load html template _template: function(id, idInfo) { - return '
' + + return '
' + + '"Set All" Types:  ' + + '  ' + + ' ' + + '
' + + '
' + '
NameSizeCreated
' + '' + '' + @@ -622,7 +720,9 @@ return Backbone.View.extend({ '' + '' + '' + - '
'; + '
' + + '
' + + '
' ; } }); diff --git a/static/scripts/packed/mvc/upload/upload-ftp.js b/static/scripts/packed/mvc/upload/upload-ftp.js index 0d5d1c4e195..35cc837e891 100644 --- a/static/scripts/packed/mvc/upload/upload-ftp.js +++ b/static/scripts/packed/mvc/upload/upload-ftp.js @@ -1 +1 @@ -define(["utils/utils"],function(a){return Backbone.View.extend({options:{class_add:"upload-icon-button fa fa-square-o",class_remove:"upload-icon-button fa fa-check-square-o"},initialize:function(c){this.app=c;var b=this;this.setElement(this._template());a.get({url:galaxy_config.root+"api/ftp_files",success:function(d){b._fill(d)},error:function(){b._fill()}})},events:{mousedown:function(b){b.preventDefault()}},_fill:function(c){if(c&&c.length>0){this.$el.find("#upload-ftp-content").html($(this._templateTable()));var b=0;for(key in c){this.add(c[key]);b+=c[key].size}this.$el.find("#upload-ftp-number").html(c.length+" files");this.$el.find("#upload-ftp-disk").html(a.bytesToString(b,true))}else{this.$el.find("#upload-ftp-content").html($(this._templateInfo()))}this.$el.find("#upload-ftp-wait").hide()},add:function(f){var d=this;var e=$(this._templateRow(f));var b=e.find(".icon");$(this.el).find("tbody").append(e);var c="";if(this._find(f)){c=this.options.class_remove}else{c=this.options.class_add}b.addClass(c);e.on("click",function(){var g=d._find(f);b.removeClass();if(!g){d.app.uploadbox.add([{mode:"ftp",name:f.path,size:f.size,path:f.path}]);b.addClass(d.options.class_remove)}else{d.app.collection.remove(g);b.addClass(d.options.class_add)}})},_find:function(f){var c=this.app.collection.where({file_path:f.path});var b=null;for(var d in c){var e=c[d];if(e.get("status")=="init"&&e.get("file_mode")=="ftp"){b=e.get("id")}}return b},_templateRow:function(b){return'

'+b.path+'

'+a.bytesToString(b.size)+''+b.ctime+""},_templateTable:function(){return'Available files:   
NameSizeCreated
'},_templateInfo:function(){return'
Your FTP directory does not contain any files.
'},_template:function(){return'
This Galaxy server allows you to upload files via FTP. To upload some files, log in to the FTP server at '+this.app.options.ftp_upload_site+' using your Galaxy credentials (email address and password).
'}})}); \ No newline at end of file +define(["utils/utils"],function(e){return Backbone.View.extend({options:{class_add:"upload-icon-button fa fa-square-o",class_remove:"upload-icon-button fa fa-check-square-o"},initialize:function(t){this.app=t;var n=this;this.setElement(this._template()),e.get({url:galaxy_config.root+"api/ftp_files",success:function(e){n._fill(e)},error:function(){n._fill()}})},events:{mousedown:function(e){e.preventDefault()}},_fill:function(t){var n=this;if(t&&t.length>0){this.$el.find("#upload-ftp-content").html($(this._templateTable()));var r=0;for(key in t)this.add(t[key]),r+=t[key].size;this.$el.find("#upload-ftp-number").html(t.length+" files"),this.$el.find("#upload-ftp-disk").html(e.bytesToString(r,!0));var s=this.$el.find("#selectAll");this._updateSelectAll(s),s.on("click",function(){var e=$(this).parents().find("tr.upload-ftp-row>td>div"),t=e.length;$this=$(this);var r=!$this.hasClass("fa-check-square-o");for(i=0;itd>div"),n=e.parents().find("tr.upload-ftp-row>td>div.fa-check-square-o"),r=t.length,i=n.length;i>0&&i!==r?(e.removeClass("fa-square-o fa-check-square-o"),e.addClass("fa-minus-square-o")):i===r?(e.removeClass("fa-square-o fa-minus-square-o"),e.addClass("fa-check-square-o")):i===0&&(e.removeClass("fa-check-square-o fa-minus-square-o"),e.addClass("fa-square-o"))},_find:function(e){var t=this.app.collection.where({file_path:e.path}),n=null;for(var r in t){var i=t[r];i.get("status")=="init"&&i.get("file_mode")=="ftp"&&(n=i.get("id"))}return n},_templateRow:function(t){return'

'+t.path+"

"+''+e.bytesToString(t.size)+""+''+t.ctime+""+""},_templateTable:function(){return'Available files:   
NameSizeCreated
'},_templateInfo:function(){return'
Your FTP directory does not contain any files.
'},_template:function(){return'
This Galaxy server allows you to upload files via FTP. To upload some files, log in to the FTP server at '+this.app.options.ftp_upload_site+" using your Galaxy credentials (email address and password).
"+'
'+"
"}})}); \ No newline at end of file diff --git a/static/scripts/packed/mvc/upload/upload-model.js b/static/scripts/packed/mvc/upload/upload-model.js index d8fed66cbed..ebbc0df4f84 100644 --- a/static/scripts/packed/mvc/upload/upload-model.js +++ b/static/scripts/packed/mvc/upload/upload-model.js @@ -1 +1 @@ -define([],function(){var b=Backbone.Model.extend({defaults:{extension:"auto",genome:"?",url_paste:"",status:"init",info:null,file_mode:"local",file_size:0,file_type:null,file_path:"",percentage:0,space_to_tabs:false,to_posix_lines:true}});var a=Backbone.Collection.extend({model:b});return{Model:b,Collection:a}}); \ No newline at end of file +define([],function(){var e=Backbone.Model.extend({defaults:{extension:"auto",genome:"?",url_paste:"",status:"init",info:null,file_mode:"local",file_size:0,file_type:null,file_path:"",percentage:0,row:null,space_to_tabs:!1,to_posix_lines:!0}}),t=Backbone.Collection.extend({model:e});return{Model:e,Collection:t}}); \ No newline at end of file diff --git a/static/scripts/packed/mvc/upload/upload-row.js b/static/scripts/packed/mvc/upload/upload-row.js index d15cd9feea9..673b66ebc47 100644 --- a/static/scripts/packed/mvc/upload/upload-row.js +++ b/static/scripts/packed/mvc/upload/upload-row.js @@ -1 +1 @@ -define(["utils/utils","mvc/upload/upload-model","mvc/upload/upload-settings","mvc/ui/ui-popover","mvc/ui/ui-select"],function(d,b,a,c,e){return Backbone.View.extend({options:{padding:8},status_classes:{init:"upload-icon-button fa fa-trash-o",queued:"upload-icon fa fa-spinner fa-spin",running:"upload-icon fa fa-spinner fa-spin",success:"upload-icon-button fa fa-check",error:"upload-icon-button fa fa-exclamation-triangle"},settings:null,select_genome:null,select_extension:null,initialize:function(i,g){this.app=i;var f=this;this.model=new b.Model(g);this.setElement(this._template(g));var h=this.$el;this.settings=new c.View({title:"Upload configuration",container:h.find("#settings"),placement:"bottom"});this.select_genome=new e.View({css:"genome",onchange:function(){f.model.set("genome",f.select_genome.value())},data:f.app.list_genomes,container:h.find("#genome"),value:f.model.get("genome")});this.model.set("genome",f.select_genome.value());this.select_extension=new e.View({css:"extension",onchange:function(){f.model.set("extension",f.select_extension.value())},data:f.app.list_extensions,container:h.find("#extension"),value:f.model.get("extension")});this.model.set("extension",f.select_extension.value());h.find("#symbol").on("click",function(){f._removeRow()});h.find("#extension-info").on("click",function(j){f._showExtensionInfo()}).on("mousedown",function(j){j.preventDefault()});h.find("#settings").on("click",function(j){f._showSettings()}).on("mousedown",function(j){j.preventDefault()});h.find("#text-content").on("keyup",function(j){f.model.set("url_paste",$(j.target).val());f.model.set("file_size",$(j.target).val().length)});h.find("#space_to_tabs").on("change",function(j){f.model.set("space_to_tabs",$(j.target).prop("checked"))});this.model.on("change:percentage",function(){f._refreshPercentage()});this.model.on("change:status",function(){f._refreshStatus()});this.model.on("change:info",function(){f._refreshInfo()});this.model.on("change:genome",function(){f._refreshGenome()});this.model.on("change:file_size",function(){f._refreshFileSize()});this.model.on("remove",function(){f.remove()});this.app.collection.on("reset",function(){f.remove()})},render:function(){var m=this.model.get("file_name");var g=this.model.get("file_size");var j=this.model.get("file_mode");var i=this.$el;i.find("#title").html(m);i.find("#size").html(d.bytesToString(g));i.find("#mode").removeClass().addClass("mode");if(j=="new"){var l=i.find("#text");var k=this.options.padding;var h=i.width()-2*k;var f=i.height()-k;l.css("width",h+"px");l.css("top",f+"px");i.height(f+l.height()+2*k);l.show();i.find("#mode").addClass("fa fa-pencil")}if(j=="local"){i.find("#mode").addClass("fa fa-laptop")}if(j=="ftp"){i.find("#mode").addClass("fa fa-code-fork")}},remove:function(){this.select_genome.remove();this.select_extension.remove();Backbone.View.prototype.remove.apply(this)},_refreshGenome:function(){var f=this.model.get("genome");this.select_genome.value(f)},_refreshInfo:function(){var f=this.model.get("info");if(f){this.$el.find("#info").html("Failed: "+f).show()}else{this.$el.find("#info").hide()}},_refreshPercentage:function(){var f=parseInt(this.model.get("percentage"));this.$el.find(".progress-bar").css({width:f+"%"});if(f!=100){this.$el.find("#percentage").html(f+"%")}else{this.$el.find("#percentage").html("Adding to history...")}},_refreshStatus:function(){var g=this.$el;var f=this.model.get("status");var i=this.status_classes[f];var h=this.$el.find("#symbol");h.removeClass();h.addClass(i);if(f=="init"){this.select_genome.enable();this.select_extension.enable();g.find("#text-content").attr("disabled",false);g.find("#space_to_tabs").attr("disabled",false)}else{this.select_genome.disable();this.select_extension.disable();g.find("#text-content").attr("disabled",true);g.find("#space_to_tabs").attr("disabled",true)}if(f=="success"){g.addClass("success");g.find("#percentage").html("100%")}if(f=="error"){g.addClass("danger");g.find(".progress").remove()}},_refreshFileSize:function(){var f=this.model.get("file_size");this.$el.find("#size").html(d.bytesToString(f))},_removeRow:function(){var f=this.model.get("status");if(f=="init"||f=="success"||f=="error"){this.app.collection.remove(this.model)}},_showExtensionInfo:function(){var f=$(this.el).find("#extension-info");var i=this.model.get("extension");var h=this.select_extension.text();var g=_.findWhere(this.app.list_extensions,{id:i});if(!this.extension_popup){this.extension_popup=new c.View({placement:"bottom",container:f})}if(!this.extension_popup.visible){this.extension_popup.title(h);this.extension_popup.empty();this.extension_popup.append(this._templateDescription(g));this.extension_popup.show()}else{this.extension_popup.hide()}},_showSettings:function(){if(!this.settings.visible){this.settings.empty();this.settings.append((new a(this)).$el);this.settings.show()}else{this.settings.hide()}},_templateDescription:function(g){if(g.description){var f=g.description;if(g.description_url){f+=' (read more)'}return f}else{return"There is no description available for this file extension."}},_template:function(f){return'
You can tell Galaxy to download data from web by entering URL in this box (one per line). You can also directly paste the contents of a file.