galaxy-commits
Threads by month
- ----- 2026 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 15302 discussions
commit/galaxy-central: jmchilton: Merged in martenson/galaxy-stable-pr/stable (pull request #503)
by commits-noreply@bitbucket.org 23 Sep '14
by commits-noreply@bitbucket.org 23 Sep '14
23 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/548ab24667d6/
Changeset: 548ab24667d6
Branch: stable
User: jmchilton
Date: 2014-09-23 14:06:38+00:00
Summary: Merged in martenson/galaxy-stable-pr/stable (pull request #503)
[STABLE] fix for select2 bug with minimal width
Affected #: 4 files
diff -r 721a68434e8df24e7fd58d51b734ac7e0caac0a0 -r 548ab24667d6206780237bd807f7d857a484c461 static/scripts/galaxy.base.js
--- a/static/scripts/galaxy.base.js
+++ b/static/scripts/galaxy.base.js
@@ -236,8 +236,10 @@
$.fn.refresh_select2 = function() {
var select_elt = $(this);
- var options = { width: "resolve",
- closeOnSelect: !select_elt.is("[MULTIPLE]")
+ var options = { placeholder:'Click to select',
+ closeOnSelect: !select_elt.is("[MULTIPLE]"),
+ dropdownAutoWidth : true,
+ containerCssClass: 'select2-minwidth'
};
return select_elt.select2( options );
}
diff -r 721a68434e8df24e7fd58d51b734ac7e0caac0a0 -r 548ab24667d6206780237bd807f7d857a484c461 static/scripts/packed/galaxy.base.js
--- a/static/scripts/packed/galaxy.base.js
+++ b/static/scripts/packed/galaxy.base.js
@@ -1,1 +1,1 @@
-(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelRequestAnimationFrame=window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());if(!Array.indexOf){Array.prototype.indexOf=function(c){for(var b=0,a=this.length;b<a;b++){if(this[b]==c){return b}}return -1}}function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function make_popupmenu(b,c){var a=(b.data("menu_options"));b.data("menu_options",c);if(a){return}b.bind("click.show_popup",function(d){$(".popmenu-wrapper").remove();setTimeout(function(){var g=$("<ul class='dropdown-menu' id='"+b.attr("id")+"-menu'></ul>");var f=b.data("menu_options");if(obj_length(f)<=0){$("<li>No Options.</li>").appendTo(g)}$.each(f,function(j,i){if(i){var l=i.action||i;g.append($("<li></li>").append($("<a>").attr("href",i.url).html(j).click(l)))}else{g.append($("<li></li>").addClass("head").append($("<a href='#'></a>").html(j)))}});var h=$("<div class='popmenu-wrapper' style='position: absolute;left: 0; top: -1000;'></div>").append(g).appendTo("body");var e=d.pageX-h.width()/2;e=Math.min(e,$(document).scrollLeft()+$(window).width()-$(h).width()-5);e=Math.max(e,$(document).scrollLeft()+5);h.css({top:d.pageY,left:e})},10);setTimeout(function(){var f=function(h){$(h).bind("click.close_popup",function(){$(".popmenu-wrapper").remove();h.unbind("click.close_popup")})};f($(window.document));f($(window.top.document));for(var e=window.top.frames.length;e--;){var g=$(window.top.frames[e].document);f(g)}},50);return false})}function make_popup_menus(a){a=a||document;$(a).find("div[popupmenu]").each(function(){var b={};var d=$(this);d.find("a").each(function(){var g=$(this),i=g.get(0),e=i.getAttribute("confirm"),f=i.getAttribute("href"),h=i.getAttribute("target");if(!f){b[g.text()]=null}else{b[g.text()]={url:f,action:function(){if(!e||confirm(e)){if(h){window.open(f,h);return false}else{g.click()}}}}}});var c=$(a).find("#"+d.attr("popupmenu"));c.find("a").bind("click",function(f){f.stopPropagation();return true});make_popupmenu(c,b);c.addClass("popup");d.remove()})}function naturalSort(j,h){var p=/(-?[0-9\.]+)/g,k=j.toString().toLowerCase()||"",g=h.toString().toLowerCase()||"",l=String.fromCharCode(0),n=k.replace(p,l+"$1"+l).split(l),e=g.replace(p,l+"$1"+l).split(l),d=(new Date(k)).getTime(),o=d?(new Date(g)).getTime():null;if(o){if(d<o){return -1}else{if(d>o){return 1}}}var m,f;for(var i=0,c=Math.max(n.length,e.length);i<c;i++){m=parseFloat(n[i])||n[i];f=parseFloat(e[i])||e[i];if(m<f){return -1}else{if(m>f){return 1}}}return 0}$.fn.refresh_select2=function(){var b=$(this);var a={width:"resolve",closeOnSelect:!b.is("[MULTIPLE]")};return b.select2(a)};function replace_big_select_inputs(a,c,b){if(!jQuery.fn.select2){return}if(a===undefined){a=20}if(c===undefined){c=3000}b=b||$("select");b.each(function(){var e=$(this).not("[multiple]");var d=e.find("option").length;if((d<a)||(d>c)){return}if(e.hasClass("no-autocomplete")){return}e.refresh_select2()})}$.fn.make_text_editable=function(g){var d=("num_cols" in g?g.num_cols:30),c=("num_rows" in g?g.num_rows:4),e=("use_textarea" in g?g.use_textarea:false),b=("on_finish" in g?g.on_finish:null),f=("help_text" in g?g.help_text:null);var a=$(this);a.addClass("editable-text").click(function(l){if($(this).children(":input").length>0){return}a.removeClass("editable-text");var i=function(m){a.find(":input").remove();if(m!==""){a.text(m)}else{a.html("<br>")}a.addClass("editable-text");if(b){b(m)}};var h=("cur_text" in g?g.cur_text:a.text()),k,j;if(e){k=$("<textarea/>").attr({rows:c,cols:d}).text($.trim(h)).keyup(function(m){if(m.keyCode===27){i(h)}});j=$("<button/>").text("Done").click(function(){i(k.val());return false})}else{k=$("<input type='text'/>").attr({value:$.trim(h),size:d}).blur(function(){i(h)}).keyup(function(m){if(m.keyCode===27){$(this).trigger("blur")}else{if(m.keyCode===13){i($(this).val())}}m.stopPropagation()})}a.text("");a.append(k);if(j){a.append(j)}k.focus();k.select();l.stopPropagation()});if(f){a.attr("title",f).tooltip()}return a};function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).click(function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!==""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStorage.get("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStorage.deleteKey("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id,h=$(this).children("div.historyItemBody"),i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){var k;if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){k=$.jStorage.get("history_expand_state");if(k){delete k[j];$.jStorage.set("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){k=$.jStorage.get("history_expand_state");if(!k){k={}}k[j]=true;$.jStorage.set("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStorage.get("history_expand_state");if(!h){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStorage.set("history_expand_state",h)}).show()};b()}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length===0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!=="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};function init_refresh_on_change(){$("select[refresh_on_change='true']").off("change").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");$(document).trigger("convert_to_values");a.get(0).form.submit()});$(":checkbox[refresh_on_change='true']").off("click").click(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").off("click").click(function(){return confirm($(this).attr("confirm"))})}$(document).ready(function(){init_refresh_on_change();if($.fn.tooltip){$(".unified-panel-header [title]").tooltip({placement:"bottom"});$("[title]").tooltip()}make_popup_menus();replace_big_select_inputs(20,1500);$("a").click(function(){var b=$(this);var c=(parent.frames&&parent.frames.galaxy_main);if((b.attr("target")=="galaxy_main")&&(!c)){var a=b.attr("href");if(a.indexOf("?")==-1){a+="?"}else{a+="&"}a+="use_panels=True";b.attr("href",a);b.attr("target","_self")}return b})});
\ No newline at end of file
+(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelRequestAnimationFrame=window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());if(!Array.indexOf){Array.prototype.indexOf=function(c){for(var b=0,a=this.length;b<a;b++){if(this[b]==c){return b}}return -1}}function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function make_popupmenu(b,c){var a=(b.data("menu_options"));b.data("menu_options",c);if(a){return}b.bind("click.show_popup",function(d){$(".popmenu-wrapper").remove();setTimeout(function(){var g=$("<ul class='dropdown-menu' id='"+b.attr("id")+"-menu'></ul>");var f=b.data("menu_options");if(obj_length(f)<=0){$("<li>No Options.</li>").appendTo(g)}$.each(f,function(j,i){if(i){var l=i.action||i;g.append($("<li></li>").append($("<a>").attr("href",i.url).html(j).click(l)))}else{g.append($("<li></li>").addClass("head").append($("<a href='#'></a>").html(j)))}});var h=$("<div class='popmenu-wrapper' style='position: absolute;left: 0; top: -1000;'></div>").append(g).appendTo("body");var e=d.pageX-h.width()/2;e=Math.min(e,$(document).scrollLeft()+$(window).width()-$(h).width()-5);e=Math.max(e,$(document).scrollLeft()+5);h.css({top:d.pageY,left:e})},10);setTimeout(function(){var f=function(h){$(h).bind("click.close_popup",function(){$(".popmenu-wrapper").remove();h.unbind("click.close_popup")})};f($(window.document));f($(window.top.document));for(var e=window.top.frames.length;e--;){var g=$(window.top.frames[e].document);f(g)}},50);return false})}function make_popup_menus(a){a=a||document;$(a).find("div[popupmenu]").each(function(){var b={};var d=$(this);d.find("a").each(function(){var g=$(this),i=g.get(0),e=i.getAttribute("confirm"),f=i.getAttribute("href"),h=i.getAttribute("target");if(!f){b[g.text()]=null}else{b[g.text()]={url:f,action:function(){if(!e||confirm(e)){if(h){window.open(f,h);return false}else{g.click()}}}}}});var c=$(a).find("#"+d.attr("popupmenu"));c.find("a").bind("click",function(f){f.stopPropagation();return true});make_popupmenu(c,b);c.addClass("popup");d.remove()})}function naturalSort(j,h){var p=/(-?[0-9\.]+)/g,k=j.toString().toLowerCase()||"",g=h.toString().toLowerCase()||"",l=String.fromCharCode(0),n=k.replace(p,l+"$1"+l).split(l),e=g.replace(p,l+"$1"+l).split(l),d=(new Date(k)).getTime(),o=d?(new Date(g)).getTime():null;if(o){if(d<o){return -1}else{if(d>o){return 1}}}var m,f;for(var i=0,c=Math.max(n.length,e.length);i<c;i++){m=parseFloat(n[i])||n[i];f=parseFloat(e[i])||e[i];if(m<f){return -1}else{if(m>f){return 1}}}return 0}$.fn.refresh_select2=function(){var b=$(this);var a={placeholder:"Click to select",closeOnSelect:!b.is("[MULTIPLE]"),dropdownAutoWidth:true,containerCssClass:"select2-minwidth"};return b.select2(a)};function replace_big_select_inputs(a,c,b){if(!jQuery.fn.select2){return}if(a===undefined){a=20}if(c===undefined){c=3000}b=b||$("select");b.each(function(){var e=$(this).not("[multiple]");var d=e.find("option").length;if((d<a)||(d>c)){return}if(e.hasClass("no-autocomplete")){return}e.refresh_select2()})}$.fn.make_text_editable=function(g){var d=("num_cols" in g?g.num_cols:30),c=("num_rows" in g?g.num_rows:4),e=("use_textarea" in g?g.use_textarea:false),b=("on_finish" in g?g.on_finish:null),f=("help_text" in g?g.help_text:null);var a=$(this);a.addClass("editable-text").click(function(l){if($(this).children(":input").length>0){return}a.removeClass("editable-text");var i=function(m){a.find(":input").remove();if(m!==""){a.text(m)}else{a.html("<br>")}a.addClass("editable-text");if(b){b(m)}};var h=("cur_text" in g?g.cur_text:a.text()),k,j;if(e){k=$("<textarea/>").attr({rows:c,cols:d}).text($.trim(h)).keyup(function(m){if(m.keyCode===27){i(h)}});j=$("<button/>").text("Done").click(function(){i(k.val());return false})}else{k=$("<input type='text'/>").attr({value:$.trim(h),size:d}).blur(function(){i(h)}).keyup(function(m){if(m.keyCode===27){$(this).trigger("blur")}else{if(m.keyCode===13){i($(this).val())}}m.stopPropagation()})}a.text("");a.append(k);if(j){a.append(j)}k.focus();k.select();l.stopPropagation()});if(f){a.attr("title",f).tooltip()}return a};function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).click(function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!==""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStorage.get("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStorage.deleteKey("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id,h=$(this).children("div.historyItemBody"),i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){var k;if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){k=$.jStorage.get("history_expand_state");if(k){delete k[j];$.jStorage.set("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){k=$.jStorage.get("history_expand_state");if(!k){k={}}k[j]=true;$.jStorage.set("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStorage.get("history_expand_state");if(!h){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStorage.set("history_expand_state",h)}).show()};b()}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length===0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!=="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};function init_refresh_on_change(){$("select[refresh_on_change='true']").off("change").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");$(document).trigger("convert_to_values");a.get(0).form.submit()});$(":checkbox[refresh_on_change='true']").off("click").click(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").off("click").click(function(){return confirm($(this).attr("confirm"))})}$(document).ready(function(){init_refresh_on_change();if($.fn.tooltip){$(".unified-panel-header [title]").tooltip({placement:"bottom"});$("[title]").tooltip()}make_popup_menus();replace_big_select_inputs(20,1500);$("a").click(function(){var b=$(this);var c=(parent.frames&&parent.frames.galaxy_main);if((b.attr("target")=="galaxy_main")&&(!c)){var a=b.attr("href");if(a.indexOf("?")==-1){a+="?"}else{a+="&"}a+="use_panels=True";b.attr("href",a);b.attr("target","_self")}return b})});
\ No newline at end of file
diff -r 721a68434e8df24e7fd58d51b734ac7e0caac0a0 -r 548ab24667d6206780237bd807f7d857a484c461 static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1232,7 +1232,7 @@
.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0) !important;width:1px !important;height:1px !important;border:0 !important;margin:0 !important;padding:0 !important;overflow:hidden !important;position:absolute !important;outline:0 !important;left:0px !important;top:0px !important}
.select2-display-none{display:none}
.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}
-@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:144dpi){.select2-search input,.select2-search-choice-close,.select2-container .select2-choice abbr,.select2-container .select2-choice .select2-arrow b{background-image:url('../images/select2x2.png') !important;background-repeat:no-repeat !important;background-size:60px 40px !important} .select2-search input{background-position:100% -21px !important}}.select2-container{min-width:256px}
+@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:144dpi){.select2-search input,.select2-search-choice-close,.select2-container .select2-choice abbr,.select2-container .select2-choice .select2-arrow b{background-image:url('../images/select2x2.png') !important;background-repeat:no-repeat !important;background-size:60px 40px !important} .select2-search input{background-position:100% -21px !important}}.select2-minwidth{min-width:256px}
.galaxy-frame{}.galaxy-frame .corner{-moz-border-radius:5px;border-radius:5px}
.galaxy-frame .toggle{color:gold}
.galaxy-frame .frame-background{z-index:1000;position:absolute;display:none;top:0px;left:0px;height:100%;width:100%;opacity:0.6;background:#000;overflow:auto}
diff -r 721a68434e8df24e7fd58d51b734ac7e0caac0a0 -r 548ab24667d6206780237bd807f7d857a484c461 static/style/src/less/base.less
--- a/static/style/src/less/base.less
+++ b/static/style/src/less/base.less
@@ -16,7 +16,7 @@
@import "select2.less";
/* fix for zero width select2 - remove when fixed there */
-.select2-container {
+.select2-minwidth {
min-width: 256px;
}
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/4eb74e9e16ac/
Changeset: 4eb74e9e16ac
Branch: stable
User: martenson
Date: 2014-09-22 22:09:45+00:00
Summary: the removed select2 class overrule for edit hda attributes is needed afterall, I at least did rename it to specific to its usage so other select2 items can work normally
Affected #: 4 files
diff -r 9f15bf53a11b8a91301381d836271a0ac3b23e71 -r 4eb74e9e16ace20ca81d8d1ca6947cb0e9be7a04 static/scripts/galaxy.base.js
--- a/static/scripts/galaxy.base.js
+++ b/static/scripts/galaxy.base.js
@@ -236,8 +236,10 @@
$.fn.refresh_select2 = function() {
var select_elt = $(this);
- var options = { width: "resolve",
- closeOnSelect: !select_elt.is("[MULTIPLE]")
+ var options = { placeholder:'Click to select',
+ closeOnSelect: !select_elt.is("[MULTIPLE]"),
+ dropdownAutoWidth : true,
+ containerCssClass: 'select2-minwidth'
};
return select_elt.select2( options );
}
diff -r 9f15bf53a11b8a91301381d836271a0ac3b23e71 -r 4eb74e9e16ace20ca81d8d1ca6947cb0e9be7a04 static/scripts/packed/galaxy.base.js
--- a/static/scripts/packed/galaxy.base.js
+++ b/static/scripts/packed/galaxy.base.js
@@ -1,1 +1,1 @@
-(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelRequestAnimationFrame=window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());if(!Array.indexOf){Array.prototype.indexOf=function(c){for(var b=0,a=this.length;b<a;b++){if(this[b]==c){return b}}return -1}}function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function make_popupmenu(b,c){var a=(b.data("menu_options"));b.data("menu_options",c);if(a){return}b.bind("click.show_popup",function(d){$(".popmenu-wrapper").remove();setTimeout(function(){var g=$("<ul class='dropdown-menu' id='"+b.attr("id")+"-menu'></ul>");var f=b.data("menu_options");if(obj_length(f)<=0){$("<li>No Options.</li>").appendTo(g)}$.each(f,function(j,i){if(i){var l=i.action||i;g.append($("<li></li>").append($("<a>").attr("href",i.url).html(j).click(l)))}else{g.append($("<li></li>").addClass("head").append($("<a href='#'></a>").html(j)))}});var h=$("<div class='popmenu-wrapper' style='position: absolute;left: 0; top: -1000;'></div>").append(g).appendTo("body");var e=d.pageX-h.width()/2;e=Math.min(e,$(document).scrollLeft()+$(window).width()-$(h).width()-5);e=Math.max(e,$(document).scrollLeft()+5);h.css({top:d.pageY,left:e})},10);setTimeout(function(){var f=function(h){$(h).bind("click.close_popup",function(){$(".popmenu-wrapper").remove();h.unbind("click.close_popup")})};f($(window.document));f($(window.top.document));for(var e=window.top.frames.length;e--;){var g=$(window.top.frames[e].document);f(g)}},50);return false})}function make_popup_menus(a){a=a||document;$(a).find("div[popupmenu]").each(function(){var b={};var d=$(this);d.find("a").each(function(){var g=$(this),i=g.get(0),e=i.getAttribute("confirm"),f=i.getAttribute("href"),h=i.getAttribute("target");if(!f){b[g.text()]=null}else{b[g.text()]={url:f,action:function(){if(!e||confirm(e)){if(h){window.open(f,h);return false}else{g.click()}}}}}});var c=$(a).find("#"+d.attr("popupmenu"));c.find("a").bind("click",function(f){f.stopPropagation();return true});make_popupmenu(c,b);c.addClass("popup");d.remove()})}function naturalSort(j,h){var p=/(-?[0-9\.]+)/g,k=j.toString().toLowerCase()||"",g=h.toString().toLowerCase()||"",l=String.fromCharCode(0),n=k.replace(p,l+"$1"+l).split(l),e=g.replace(p,l+"$1"+l).split(l),d=(new Date(k)).getTime(),o=d?(new Date(g)).getTime():null;if(o){if(d<o){return -1}else{if(d>o){return 1}}}var m,f;for(var i=0,c=Math.max(n.length,e.length);i<c;i++){m=parseFloat(n[i])||n[i];f=parseFloat(e[i])||e[i];if(m<f){return -1}else{if(m>f){return 1}}}return 0}$.fn.refresh_select2=function(){var b=$(this);var a={width:"resolve",closeOnSelect:!b.is("[MULTIPLE]")};return b.select2(a)};function replace_big_select_inputs(a,c,b){if(!jQuery.fn.select2){return}if(a===undefined){a=20}if(c===undefined){c=3000}b=b||$("select");b.each(function(){var e=$(this).not("[multiple]");var d=e.find("option").length;if((d<a)||(d>c)){return}if(e.hasClass("no-autocomplete")){return}e.refresh_select2()})}$.fn.make_text_editable=function(g){var d=("num_cols" in g?g.num_cols:30),c=("num_rows" in g?g.num_rows:4),e=("use_textarea" in g?g.use_textarea:false),b=("on_finish" in g?g.on_finish:null),f=("help_text" in g?g.help_text:null);var a=$(this);a.addClass("editable-text").click(function(l){if($(this).children(":input").length>0){return}a.removeClass("editable-text");var i=function(m){a.find(":input").remove();if(m!==""){a.text(m)}else{a.html("<br>")}a.addClass("editable-text");if(b){b(m)}};var h=("cur_text" in g?g.cur_text:a.text()),k,j;if(e){k=$("<textarea/>").attr({rows:c,cols:d}).text($.trim(h)).keyup(function(m){if(m.keyCode===27){i(h)}});j=$("<button/>").text("Done").click(function(){i(k.val());return false})}else{k=$("<input type='text'/>").attr({value:$.trim(h),size:d}).blur(function(){i(h)}).keyup(function(m){if(m.keyCode===27){$(this).trigger("blur")}else{if(m.keyCode===13){i($(this).val())}}m.stopPropagation()})}a.text("");a.append(k);if(j){a.append(j)}k.focus();k.select();l.stopPropagation()});if(f){a.attr("title",f).tooltip()}return a};function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).click(function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!==""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStorage.get("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStorage.deleteKey("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id,h=$(this).children("div.historyItemBody"),i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){var k;if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){k=$.jStorage.get("history_expand_state");if(k){delete k[j];$.jStorage.set("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){k=$.jStorage.get("history_expand_state");if(!k){k={}}k[j]=true;$.jStorage.set("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStorage.get("history_expand_state");if(!h){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStorage.set("history_expand_state",h)}).show()};b()}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length===0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!=="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};function init_refresh_on_change(){$("select[refresh_on_change='true']").off("change").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");$(document).trigger("convert_to_values");a.get(0).form.submit()});$(":checkbox[refresh_on_change='true']").off("click").click(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").off("click").click(function(){return confirm($(this).attr("confirm"))})}$(document).ready(function(){init_refresh_on_change();if($.fn.tooltip){$(".unified-panel-header [title]").tooltip({placement:"bottom"});$("[title]").tooltip()}make_popup_menus();replace_big_select_inputs(20,1500);$("a").click(function(){var b=$(this);var c=(parent.frames&&parent.frames.galaxy_main);if((b.attr("target")=="galaxy_main")&&(!c)){var a=b.attr("href");if(a.indexOf("?")==-1){a+="?"}else{a+="&"}a+="use_panels=True";b.attr("href",a);b.attr("target","_self")}return b})});
\ No newline at end of file
+(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelRequestAnimationFrame=window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());if(!Array.indexOf){Array.prototype.indexOf=function(c){for(var b=0,a=this.length;b<a;b++){if(this[b]==c){return b}}return -1}}function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function make_popupmenu(b,c){var a=(b.data("menu_options"));b.data("menu_options",c);if(a){return}b.bind("click.show_popup",function(d){$(".popmenu-wrapper").remove();setTimeout(function(){var g=$("<ul class='dropdown-menu' id='"+b.attr("id")+"-menu'></ul>");var f=b.data("menu_options");if(obj_length(f)<=0){$("<li>No Options.</li>").appendTo(g)}$.each(f,function(j,i){if(i){var l=i.action||i;g.append($("<li></li>").append($("<a>").attr("href",i.url).html(j).click(l)))}else{g.append($("<li></li>").addClass("head").append($("<a href='#'></a>").html(j)))}});var h=$("<div class='popmenu-wrapper' style='position: absolute;left: 0; top: -1000;'></div>").append(g).appendTo("body");var e=d.pageX-h.width()/2;e=Math.min(e,$(document).scrollLeft()+$(window).width()-$(h).width()-5);e=Math.max(e,$(document).scrollLeft()+5);h.css({top:d.pageY,left:e})},10);setTimeout(function(){var f=function(h){$(h).bind("click.close_popup",function(){$(".popmenu-wrapper").remove();h.unbind("click.close_popup")})};f($(window.document));f($(window.top.document));for(var e=window.top.frames.length;e--;){var g=$(window.top.frames[e].document);f(g)}},50);return false})}function make_popup_menus(a){a=a||document;$(a).find("div[popupmenu]").each(function(){var b={};var d=$(this);d.find("a").each(function(){var g=$(this),i=g.get(0),e=i.getAttribute("confirm"),f=i.getAttribute("href"),h=i.getAttribute("target");if(!f){b[g.text()]=null}else{b[g.text()]={url:f,action:function(){if(!e||confirm(e)){if(h){window.open(f,h);return false}else{g.click()}}}}}});var c=$(a).find("#"+d.attr("popupmenu"));c.find("a").bind("click",function(f){f.stopPropagation();return true});make_popupmenu(c,b);c.addClass("popup");d.remove()})}function naturalSort(j,h){var p=/(-?[0-9\.]+)/g,k=j.toString().toLowerCase()||"",g=h.toString().toLowerCase()||"",l=String.fromCharCode(0),n=k.replace(p,l+"$1"+l).split(l),e=g.replace(p,l+"$1"+l).split(l),d=(new Date(k)).getTime(),o=d?(new Date(g)).getTime():null;if(o){if(d<o){return -1}else{if(d>o){return 1}}}var m,f;for(var i=0,c=Math.max(n.length,e.length);i<c;i++){m=parseFloat(n[i])||n[i];f=parseFloat(e[i])||e[i];if(m<f){return -1}else{if(m>f){return 1}}}return 0}$.fn.refresh_select2=function(){var b=$(this);var a={placeholder:"Click to select",closeOnSelect:!b.is("[MULTIPLE]"),dropdownAutoWidth:true,containerCssClass:"select2-minwidth"};return b.select2(a)};function replace_big_select_inputs(a,c,b){if(!jQuery.fn.select2){return}if(a===undefined){a=20}if(c===undefined){c=3000}b=b||$("select");b.each(function(){var e=$(this).not("[multiple]");var d=e.find("option").length;if((d<a)||(d>c)){return}if(e.hasClass("no-autocomplete")){return}e.refresh_select2()})}$.fn.make_text_editable=function(g){var d=("num_cols" in g?g.num_cols:30),c=("num_rows" in g?g.num_rows:4),e=("use_textarea" in g?g.use_textarea:false),b=("on_finish" in g?g.on_finish:null),f=("help_text" in g?g.help_text:null);var a=$(this);a.addClass("editable-text").click(function(l){if($(this).children(":input").length>0){return}a.removeClass("editable-text");var i=function(m){a.find(":input").remove();if(m!==""){a.text(m)}else{a.html("<br>")}a.addClass("editable-text");if(b){b(m)}};var h=("cur_text" in g?g.cur_text:a.text()),k,j;if(e){k=$("<textarea/>").attr({rows:c,cols:d}).text($.trim(h)).keyup(function(m){if(m.keyCode===27){i(h)}});j=$("<button/>").text("Done").click(function(){i(k.val());return false})}else{k=$("<input type='text'/>").attr({value:$.trim(h),size:d}).blur(function(){i(h)}).keyup(function(m){if(m.keyCode===27){$(this).trigger("blur")}else{if(m.keyCode===13){i($(this).val())}}m.stopPropagation()})}a.text("");a.append(k);if(j){a.append(j)}k.focus();k.select();l.stopPropagation()});if(f){a.attr("title",f).tooltip()}return a};function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).click(function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!==""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStorage.get("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStorage.deleteKey("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id,h=$(this).children("div.historyItemBody"),i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){var k;if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){k=$.jStorage.get("history_expand_state");if(k){delete k[j];$.jStorage.set("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){k=$.jStorage.get("history_expand_state");if(!k){k={}}k[j]=true;$.jStorage.set("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStorage.get("history_expand_state");if(!h){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStorage.set("history_expand_state",h)}).show()};b()}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length===0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!=="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};function init_refresh_on_change(){$("select[refresh_on_change='true']").off("change").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");$(document).trigger("convert_to_values");a.get(0).form.submit()});$(":checkbox[refresh_on_change='true']").off("click").click(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").off("click").click(function(){return confirm($(this).attr("confirm"))})}$(document).ready(function(){init_refresh_on_change();if($.fn.tooltip){$(".unified-panel-header [title]").tooltip({placement:"bottom"});$("[title]").tooltip()}make_popup_menus();replace_big_select_inputs(20,1500);$("a").click(function(){var b=$(this);var c=(parent.frames&&parent.frames.galaxy_main);if((b.attr("target")=="galaxy_main")&&(!c)){var a=b.attr("href");if(a.indexOf("?")==-1){a+="?"}else{a+="&"}a+="use_panels=True";b.attr("href",a);b.attr("target","_self")}return b})});
\ No newline at end of file
diff -r 9f15bf53a11b8a91301381d836271a0ac3b23e71 -r 4eb74e9e16ace20ca81d8d1ca6947cb0e9be7a04 static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1232,7 +1232,7 @@
.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0) !important;width:1px !important;height:1px !important;border:0 !important;margin:0 !important;padding:0 !important;overflow:hidden !important;position:absolute !important;outline:0 !important;left:0px !important;top:0px !important}
.select2-display-none{display:none}
.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}
-@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:144dpi){.select2-search input,.select2-search-choice-close,.select2-container .select2-choice abbr,.select2-container .select2-choice .select2-arrow b{background-image:url('../images/select2x2.png') !important;background-repeat:no-repeat !important;background-size:60px 40px !important} .select2-search input{background-position:100% -21px !important}}.select2-container{min-width:256px}
+@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:144dpi){.select2-search input,.select2-search-choice-close,.select2-container .select2-choice abbr,.select2-container .select2-choice .select2-arrow b{background-image:url('../images/select2x2.png') !important;background-repeat:no-repeat !important;background-size:60px 40px !important} .select2-search input{background-position:100% -21px !important}}.select2-minwidth{min-width:256px}
.galaxy-frame{}.galaxy-frame .corner{-moz-border-radius:5px;border-radius:5px}
.galaxy-frame .toggle{color:gold}
.galaxy-frame .frame-background{z-index:1000;position:absolute;display:none;top:0px;left:0px;height:100%;width:100%;opacity:0.6;background:#000;overflow:auto}
diff -r 9f15bf53a11b8a91301381d836271a0ac3b23e71 -r 4eb74e9e16ace20ca81d8d1ca6947cb0e9be7a04 static/style/src/less/base.less
--- a/static/style/src/less/base.less
+++ b/static/style/src/less/base.less
@@ -16,7 +16,7 @@
@import "select2.less";
/* fix for zero width select2 - remove when fixed there */
-.select2-container {
+.select2-minwidth {
min-width: 256px;
}
https://bitbucket.org/galaxy/galaxy-central/commits/548ab24667d6/
Changeset: 548ab24667d6
Branch: stable
User: jmchilton
Date: 2014-09-23 14:06:38+00:00
Summary: Merged in martenson/galaxy-stable-pr/stable (pull request #503)
[STABLE] fix for select2 bug with minimal width
Affected #: 4 files
diff -r 721a68434e8df24e7fd58d51b734ac7e0caac0a0 -r 548ab24667d6206780237bd807f7d857a484c461 static/scripts/galaxy.base.js
--- a/static/scripts/galaxy.base.js
+++ b/static/scripts/galaxy.base.js
@@ -236,8 +236,10 @@
$.fn.refresh_select2 = function() {
var select_elt = $(this);
- var options = { width: "resolve",
- closeOnSelect: !select_elt.is("[MULTIPLE]")
+ var options = { placeholder:'Click to select',
+ closeOnSelect: !select_elt.is("[MULTIPLE]"),
+ dropdownAutoWidth : true,
+ containerCssClass: 'select2-minwidth'
};
return select_elt.select2( options );
}
diff -r 721a68434e8df24e7fd58d51b734ac7e0caac0a0 -r 548ab24667d6206780237bd807f7d857a484c461 static/scripts/packed/galaxy.base.js
--- a/static/scripts/packed/galaxy.base.js
+++ b/static/scripts/packed/galaxy.base.js
@@ -1,1 +1,1 @@
-(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelRequestAnimationFrame=window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());if(!Array.indexOf){Array.prototype.indexOf=function(c){for(var b=0,a=this.length;b<a;b++){if(this[b]==c){return b}}return -1}}function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function make_popupmenu(b,c){var a=(b.data("menu_options"));b.data("menu_options",c);if(a){return}b.bind("click.show_popup",function(d){$(".popmenu-wrapper").remove();setTimeout(function(){var g=$("<ul class='dropdown-menu' id='"+b.attr("id")+"-menu'></ul>");var f=b.data("menu_options");if(obj_length(f)<=0){$("<li>No Options.</li>").appendTo(g)}$.each(f,function(j,i){if(i){var l=i.action||i;g.append($("<li></li>").append($("<a>").attr("href",i.url).html(j).click(l)))}else{g.append($("<li></li>").addClass("head").append($("<a href='#'></a>").html(j)))}});var h=$("<div class='popmenu-wrapper' style='position: absolute;left: 0; top: -1000;'></div>").append(g).appendTo("body");var e=d.pageX-h.width()/2;e=Math.min(e,$(document).scrollLeft()+$(window).width()-$(h).width()-5);e=Math.max(e,$(document).scrollLeft()+5);h.css({top:d.pageY,left:e})},10);setTimeout(function(){var f=function(h){$(h).bind("click.close_popup",function(){$(".popmenu-wrapper").remove();h.unbind("click.close_popup")})};f($(window.document));f($(window.top.document));for(var e=window.top.frames.length;e--;){var g=$(window.top.frames[e].document);f(g)}},50);return false})}function make_popup_menus(a){a=a||document;$(a).find("div[popupmenu]").each(function(){var b={};var d=$(this);d.find("a").each(function(){var g=$(this),i=g.get(0),e=i.getAttribute("confirm"),f=i.getAttribute("href"),h=i.getAttribute("target");if(!f){b[g.text()]=null}else{b[g.text()]={url:f,action:function(){if(!e||confirm(e)){if(h){window.open(f,h);return false}else{g.click()}}}}}});var c=$(a).find("#"+d.attr("popupmenu"));c.find("a").bind("click",function(f){f.stopPropagation();return true});make_popupmenu(c,b);c.addClass("popup");d.remove()})}function naturalSort(j,h){var p=/(-?[0-9\.]+)/g,k=j.toString().toLowerCase()||"",g=h.toString().toLowerCase()||"",l=String.fromCharCode(0),n=k.replace(p,l+"$1"+l).split(l),e=g.replace(p,l+"$1"+l).split(l),d=(new Date(k)).getTime(),o=d?(new Date(g)).getTime():null;if(o){if(d<o){return -1}else{if(d>o){return 1}}}var m,f;for(var i=0,c=Math.max(n.length,e.length);i<c;i++){m=parseFloat(n[i])||n[i];f=parseFloat(e[i])||e[i];if(m<f){return -1}else{if(m>f){return 1}}}return 0}$.fn.refresh_select2=function(){var b=$(this);var a={width:"resolve",closeOnSelect:!b.is("[MULTIPLE]")};return b.select2(a)};function replace_big_select_inputs(a,c,b){if(!jQuery.fn.select2){return}if(a===undefined){a=20}if(c===undefined){c=3000}b=b||$("select");b.each(function(){var e=$(this).not("[multiple]");var d=e.find("option").length;if((d<a)||(d>c)){return}if(e.hasClass("no-autocomplete")){return}e.refresh_select2()})}$.fn.make_text_editable=function(g){var d=("num_cols" in g?g.num_cols:30),c=("num_rows" in g?g.num_rows:4),e=("use_textarea" in g?g.use_textarea:false),b=("on_finish" in g?g.on_finish:null),f=("help_text" in g?g.help_text:null);var a=$(this);a.addClass("editable-text").click(function(l){if($(this).children(":input").length>0){return}a.removeClass("editable-text");var i=function(m){a.find(":input").remove();if(m!==""){a.text(m)}else{a.html("<br>")}a.addClass("editable-text");if(b){b(m)}};var h=("cur_text" in g?g.cur_text:a.text()),k,j;if(e){k=$("<textarea/>").attr({rows:c,cols:d}).text($.trim(h)).keyup(function(m){if(m.keyCode===27){i(h)}});j=$("<button/>").text("Done").click(function(){i(k.val());return false})}else{k=$("<input type='text'/>").attr({value:$.trim(h),size:d}).blur(function(){i(h)}).keyup(function(m){if(m.keyCode===27){$(this).trigger("blur")}else{if(m.keyCode===13){i($(this).val())}}m.stopPropagation()})}a.text("");a.append(k);if(j){a.append(j)}k.focus();k.select();l.stopPropagation()});if(f){a.attr("title",f).tooltip()}return a};function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).click(function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!==""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStorage.get("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStorage.deleteKey("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id,h=$(this).children("div.historyItemBody"),i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){var k;if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){k=$.jStorage.get("history_expand_state");if(k){delete k[j];$.jStorage.set("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){k=$.jStorage.get("history_expand_state");if(!k){k={}}k[j]=true;$.jStorage.set("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStorage.get("history_expand_state");if(!h){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStorage.set("history_expand_state",h)}).show()};b()}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length===0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!=="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};function init_refresh_on_change(){$("select[refresh_on_change='true']").off("change").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");$(document).trigger("convert_to_values");a.get(0).form.submit()});$(":checkbox[refresh_on_change='true']").off("click").click(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").off("click").click(function(){return confirm($(this).attr("confirm"))})}$(document).ready(function(){init_refresh_on_change();if($.fn.tooltip){$(".unified-panel-header [title]").tooltip({placement:"bottom"});$("[title]").tooltip()}make_popup_menus();replace_big_select_inputs(20,1500);$("a").click(function(){var b=$(this);var c=(parent.frames&&parent.frames.galaxy_main);if((b.attr("target")=="galaxy_main")&&(!c)){var a=b.attr("href");if(a.indexOf("?")==-1){a+="?"}else{a+="&"}a+="use_panels=True";b.attr("href",a);b.attr("target","_self")}return b})});
\ No newline at end of file
+(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelRequestAnimationFrame=window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());if(!Array.indexOf){Array.prototype.indexOf=function(c){for(var b=0,a=this.length;b<a;b++){if(this[b]==c){return b}}return -1}}function obj_length(c){if(c.length!==undefined){return c.length}var b=0;for(var a in c){b++}return b}$.fn.makeAbsolute=function(a){return this.each(function(){var b=$(this);var c=b.position();b.css({position:"absolute",marginLeft:0,marginTop:0,top:c.top,left:c.left,right:$(window).width()-(c.left+b.width())});if(a){b.remove().appendTo("body")}})};function make_popupmenu(b,c){var a=(b.data("menu_options"));b.data("menu_options",c);if(a){return}b.bind("click.show_popup",function(d){$(".popmenu-wrapper").remove();setTimeout(function(){var g=$("<ul class='dropdown-menu' id='"+b.attr("id")+"-menu'></ul>");var f=b.data("menu_options");if(obj_length(f)<=0){$("<li>No Options.</li>").appendTo(g)}$.each(f,function(j,i){if(i){var l=i.action||i;g.append($("<li></li>").append($("<a>").attr("href",i.url).html(j).click(l)))}else{g.append($("<li></li>").addClass("head").append($("<a href='#'></a>").html(j)))}});var h=$("<div class='popmenu-wrapper' style='position: absolute;left: 0; top: -1000;'></div>").append(g).appendTo("body");var e=d.pageX-h.width()/2;e=Math.min(e,$(document).scrollLeft()+$(window).width()-$(h).width()-5);e=Math.max(e,$(document).scrollLeft()+5);h.css({top:d.pageY,left:e})},10);setTimeout(function(){var f=function(h){$(h).bind("click.close_popup",function(){$(".popmenu-wrapper").remove();h.unbind("click.close_popup")})};f($(window.document));f($(window.top.document));for(var e=window.top.frames.length;e--;){var g=$(window.top.frames[e].document);f(g)}},50);return false})}function make_popup_menus(a){a=a||document;$(a).find("div[popupmenu]").each(function(){var b={};var d=$(this);d.find("a").each(function(){var g=$(this),i=g.get(0),e=i.getAttribute("confirm"),f=i.getAttribute("href"),h=i.getAttribute("target");if(!f){b[g.text()]=null}else{b[g.text()]={url:f,action:function(){if(!e||confirm(e)){if(h){window.open(f,h);return false}else{g.click()}}}}}});var c=$(a).find("#"+d.attr("popupmenu"));c.find("a").bind("click",function(f){f.stopPropagation();return true});make_popupmenu(c,b);c.addClass("popup");d.remove()})}function naturalSort(j,h){var p=/(-?[0-9\.]+)/g,k=j.toString().toLowerCase()||"",g=h.toString().toLowerCase()||"",l=String.fromCharCode(0),n=k.replace(p,l+"$1"+l).split(l),e=g.replace(p,l+"$1"+l).split(l),d=(new Date(k)).getTime(),o=d?(new Date(g)).getTime():null;if(o){if(d<o){return -1}else{if(d>o){return 1}}}var m,f;for(var i=0,c=Math.max(n.length,e.length);i<c;i++){m=parseFloat(n[i])||n[i];f=parseFloat(e[i])||e[i];if(m<f){return -1}else{if(m>f){return 1}}}return 0}$.fn.refresh_select2=function(){var b=$(this);var a={placeholder:"Click to select",closeOnSelect:!b.is("[MULTIPLE]"),dropdownAutoWidth:true,containerCssClass:"select2-minwidth"};return b.select2(a)};function replace_big_select_inputs(a,c,b){if(!jQuery.fn.select2){return}if(a===undefined){a=20}if(c===undefined){c=3000}b=b||$("select");b.each(function(){var e=$(this).not("[multiple]");var d=e.find("option").length;if((d<a)||(d>c)){return}if(e.hasClass("no-autocomplete")){return}e.refresh_select2()})}$.fn.make_text_editable=function(g){var d=("num_cols" in g?g.num_cols:30),c=("num_rows" in g?g.num_rows:4),e=("use_textarea" in g?g.use_textarea:false),b=("on_finish" in g?g.on_finish:null),f=("help_text" in g?g.help_text:null);var a=$(this);a.addClass("editable-text").click(function(l){if($(this).children(":input").length>0){return}a.removeClass("editable-text");var i=function(m){a.find(":input").remove();if(m!==""){a.text(m)}else{a.html("<br>")}a.addClass("editable-text");if(b){b(m)}};var h=("cur_text" in g?g.cur_text:a.text()),k,j;if(e){k=$("<textarea/>").attr({rows:c,cols:d}).text($.trim(h)).keyup(function(m){if(m.keyCode===27){i(h)}});j=$("<button/>").text("Done").click(function(){i(k.val());return false})}else{k=$("<input type='text'/>").attr({value:$.trim(h),size:d}).blur(function(){i(h)}).keyup(function(m){if(m.keyCode===27){$(this).trigger("blur")}else{if(m.keyCode===13){i($(this).val())}}m.stopPropagation()})}a.text("");a.append(k);if(j){a.append(j)}k.focus();k.select();l.stopPropagation()});if(f){a.attr("title",f).tooltip()}return a};function async_save_text(d,f,e,a,c,h,i,g,b){if(c===undefined){c=30}if(i===undefined){i=4}$("#"+d).click(function(){if($("#renaming-active").length>0){return}var l=$("#"+f),k=l.text(),j;if(h){j=$("<textarea></textarea>").attr({rows:i,cols:c}).text($.trim(k))}else{j=$("<input type='text'></input>").attr({value:$.trim(k),size:c})}j.attr("id","renaming-active");j.blur(function(){$(this).remove();l.show();if(b){b(j)}});j.keyup(function(n){if(n.keyCode===27){$(this).trigger("blur")}else{if(n.keyCode===13){var m={};m[a]=$(this).val();$(this).trigger("blur");$.ajax({url:e,data:m,error:function(){alert("Text editing for elt "+f+" failed")},success:function(o){if(o!==""){l.text(o)}else{l.html("<em>None</em>")}if(b){b(j)}}})}}});if(g){g(j)}l.hide();j.insertAfter(l);j.focus();j.select();return})}function init_history_items(d,a,c){var b=function(){try{var e=$.jStorage.get("history_expand_state");if(e){for(var g in e){$("#"+g+" div.historyItemBody").show()}}}catch(f){$.jStorage.deleteKey("history_expand_state")}if($.browser.mozilla){$("div.historyItemBody").each(function(){if(!$(this).is(":visible")){$(this).find("pre.peek").css("overflow","hidden")}})}d.each(function(){var j=this.id,h=$(this).children("div.historyItemBody"),i=h.find("pre.peek");$(this).find(".historyItemTitleBar > .historyItemTitle").wrap("<a href='javascript:void(0);'></a>").click(function(){var k;if(h.is(":visible")){if($.browser.mozilla){i.css("overflow","hidden")}h.slideUp("fast");if(!c){k=$.jStorage.get("history_expand_state");if(k){delete k[j];$.jStorage.set("history_expand_state",k)}}}else{h.slideDown("fast",function(){if($.browser.mozilla){i.css("overflow","auto")}});if(!c){k=$.jStorage.get("history_expand_state");if(!k){k={}}k[j]=true;$.jStorage.set("history_expand_state",k)}}return false})});$("#top-links > a.toggle").click(function(){var h=$.jStorage.get("history_expand_state");if(!h){h={}}$("div.historyItemBody:visible").each(function(){if($.browser.mozilla){$(this).find("pre.peek").css("overflow","hidden")}$(this).slideUp("fast");if(h){delete h[$(this).parent().attr("id")]}});$.jStorage.set("history_expand_state",h)}).show()};b()}function commatize(b){b+="";var a=/(\d+)(\d{3})/;while(a.test(b)){b=b.replace(a,"$1,$2")}return b}function reset_tool_search(a){var c=$("#galaxy_tools").contents();if(c.length===0){c=$(document)}$(this).removeClass("search_active");c.find(".toolTitle").removeClass("search_match");c.find(".toolSectionBody").hide();c.find(".toolTitle").show();c.find(".toolPanelLabel").show();c.find(".toolSectionWrapper").each(function(){if($(this).attr("id")!=="recently_used_wrapper"){$(this).show()}else{if($(this).hasClass("user_pref_visible")){$(this).show()}}});c.find("#search-no-results").hide();c.find("#search-spinner").hide();if(a){var b=c.find("#tool-search-query");b.val("search tools")}}var GalaxyAsync=function(a){this.url_dict={};this.log_action=(a===undefined?false:a)};GalaxyAsync.prototype.set_func_url=function(a,b){this.url_dict[a]=b};GalaxyAsync.prototype.set_user_pref=function(a,b){var c=this.url_dict[arguments.callee];if(c===undefined){return false}$.ajax({url:c,data:{pref_name:a,pref_value:b},error:function(){return false},success:function(){return true}})};GalaxyAsync.prototype.log_user_action=function(c,b,d){if(!this.log_action){return}var a=this.url_dict[arguments.callee];if(a===undefined){return false}$.ajax({url:a,data:{action:c,context:b,params:d},error:function(){return false},success:function(){return true}})};function init_refresh_on_change(){$("select[refresh_on_change='true']").off("change").change(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");$(document).trigger("convert_to_values");a.get(0).form.submit()});$(":checkbox[refresh_on_change='true']").off("click").click(function(){var a=$(this),e=a.val(),d=false,c=a.attr("refresh_on_change_values");if(c){c=c.split(",");var b=a.attr("last_selected_value");if($.inArray(e,c)===-1&&$.inArray(b,c)===-1){return}}$(window).trigger("refresh_on_change");a.get(0).form.submit()});$("a[confirm]").off("click").click(function(){return confirm($(this).attr("confirm"))})}$(document).ready(function(){init_refresh_on_change();if($.fn.tooltip){$(".unified-panel-header [title]").tooltip({placement:"bottom"});$("[title]").tooltip()}make_popup_menus();replace_big_select_inputs(20,1500);$("a").click(function(){var b=$(this);var c=(parent.frames&&parent.frames.galaxy_main);if((b.attr("target")=="galaxy_main")&&(!c)){var a=b.attr("href");if(a.indexOf("?")==-1){a+="?"}else{a+="&"}a+="use_panels=True";b.attr("href",a);b.attr("target","_self")}return b})});
\ No newline at end of file
diff -r 721a68434e8df24e7fd58d51b734ac7e0caac0a0 -r 548ab24667d6206780237bd807f7d857a484c461 static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1232,7 +1232,7 @@
.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0) !important;width:1px !important;height:1px !important;border:0 !important;margin:0 !important;padding:0 !important;overflow:hidden !important;position:absolute !important;outline:0 !important;left:0px !important;top:0px !important}
.select2-display-none{display:none}
.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}
-@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:144dpi){.select2-search input,.select2-search-choice-close,.select2-container .select2-choice abbr,.select2-container .select2-choice .select2-arrow b{background-image:url('../images/select2x2.png') !important;background-repeat:no-repeat !important;background-size:60px 40px !important} .select2-search input{background-position:100% -21px !important}}.select2-container{min-width:256px}
+@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:144dpi){.select2-search input,.select2-search-choice-close,.select2-container .select2-choice abbr,.select2-container .select2-choice .select2-arrow b{background-image:url('../images/select2x2.png') !important;background-repeat:no-repeat !important;background-size:60px 40px !important} .select2-search input{background-position:100% -21px !important}}.select2-minwidth{min-width:256px}
.galaxy-frame{}.galaxy-frame .corner{-moz-border-radius:5px;border-radius:5px}
.galaxy-frame .toggle{color:gold}
.galaxy-frame .frame-background{z-index:1000;position:absolute;display:none;top:0px;left:0px;height:100%;width:100%;opacity:0.6;background:#000;overflow:auto}
diff -r 721a68434e8df24e7fd58d51b734ac7e0caac0a0 -r 548ab24667d6206780237bd807f7d857a484c461 static/style/src/less/base.less
--- a/static/style/src/less/base.less
+++ b/static/style/src/less/base.less
@@ -16,7 +16,7 @@
@import "select2.less";
/* fix for zero width select2 - remove when fixed there */
-.select2-container {
+.select2-minwidth {
min-width: 256px;
}
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
[galaxyproject/usegalaxy-playbook] d55ec9: Configure and install ucsc_build_sites.txt.
by GitHub 23 Sep '14
by GitHub 23 Sep '14
23 Sep '14
Branch: refs/heads/master
Home: https://github.com/galaxyproject/usegalaxy-playbook
Commit: d55ec9fe78081be632dd18d87770e624e9e0fc91
https://github.com/galaxyproject/usegalaxy-playbook/commit/d55ec9fe78081be6…
Author: Nate Coraor <nate(a)bx.psu.edu>
Date: 2014-09-23 (Tue, 23 Sep 2014)
Changed paths:
A files/galaxy/test.galaxyproject.org/config/ucsc_build_sites.txt
A files/galaxy/usegalaxy.org/config/ucsc_build_sites.txt
M production/group_vars/galaxyservers.yml
M stage/group_vars/galaxyservers.yml
Log Message:
-----------
Configure and install ucsc_build_sites.txt.
1
0
commit/galaxy-central: natefoo: Update tag latest_2014.08.11 for changeset 9f15bf53a11b
by commits-noreply@bitbucket.org 23 Sep '14
by commits-noreply@bitbucket.org 23 Sep '14
23 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/721a68434e8d/
Changeset: 721a68434e8d
Branch: stable
User: natefoo
Date: 2014-09-23 13:00:19+00:00
Summary: Update tag latest_2014.08.11 for changeset 9f15bf53a11b
Affected #: 1 file
diff -r 9f15bf53a11b8a91301381d836271a0ac3b23e71 -r 721a68434e8df24e7fd58d51b734ac7e0caac0a0 .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -18,4 +18,4 @@
81fbe25bd02edcd53065e8e4476dd1dfb5a72cf2 latest_2013.11.04
2a756ca2cb1826db7796018e77d12e2dd7b67603 latest_2014.02.10
ca45b78adb4152fc6e7395514d46eba6b7d0b838 release_2014.08.11
-9f495158c5ba45fcf61fc37d82aa8545eaba0bd5 latest_2014.08.11
+9f15bf53a11b8a91301381d836271a0ac3b23e71 latest_2014.08.11
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jmchilton: Continue flailing on environment variable configuraiton of Galaxy.
by commits-noreply@bitbucket.org 23 Sep '14
by commits-noreply@bitbucket.org 23 Sep '14
23 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/f721ff18d976/
Changeset: f721ff18d976
Branch: next-stable
User: jmchilton
Date: 2014-09-23 00:01:05+00:00
Summary: Continue flailing on environment variable configuraiton of Galaxy.
Expand variables earlier right in app_factory so middleware, etc... pick up defaults/overrrides.
In particular GALAXY_CONFIG_OVERRIDE_DEBUG should now work properly. GALAXY_CONFIG_DEBUG cannot be used because the sample config template overrides debug's default.
Thanks to Bjoern for the bug report.
Affected #: 2 files
diff -r d8fc0bf14dfeb6f59cef39e92984a46f2fafc4dc -r f721ff18d976e2876648310d59cb6b8c4f6f258b lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -13,7 +13,6 @@
import ConfigParser
from datetime import timedelta
from galaxy.web.formatting import expand_pretty_datetime_format
-from galaxy.util.properties import load_app_properties
from galaxy.util import string_as_bool
from galaxy.util import listify
from galaxy.util.dbkeys import GenomeBuilds
@@ -37,9 +36,6 @@
deprecated_options = ( 'database_file', )
def __init__( self, **kwargs ):
- kwargs = load_app_properties(
- kwds=kwargs
- )
self.config_dict = kwargs
self.root = kwargs.get( 'root_dir', '.' )
diff -r d8fc0bf14dfeb6f59cef39e92984a46f2fafc4dc -r f721ff18d976e2876648310d59cb6b8c4f6f258b lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -19,6 +19,7 @@
import galaxy.web.framework.webapp
from galaxy import util
from galaxy.util import asbool
+from galaxy.util.properties import load_app_properties
import logging
log = logging.getLogger( __name__ )
@@ -31,6 +32,9 @@
"""
Return a wsgi application serving the root object
"""
+ kwargs = load_app_properties(
+ kwds=kwargs
+ )
# Create the Galaxy application unless passed in
if 'app' in kwargs:
app = kwargs.pop( 'app' )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jmchilton: Merge latest next-stable.
by commits-noreply@bitbucket.org 22 Sep '14
by commits-noreply@bitbucket.org 22 Sep '14
22 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/5cda4ac27e0a/
Changeset: 5cda4ac27e0a
User: jmchilton
Date: 2014-09-22 23:33:42+00:00
Summary: Merge latest next-stable.
Affected #: 5 files
diff -r f89efbcfd102b4aab4ffe29285348e3ee6a02cca -r 5cda4ac27e0a3c7b688e479a593698bfb3f0deb8 .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -18,4 +18,4 @@
81fbe25bd02edcd53065e8e4476dd1dfb5a72cf2 latest_2013.11.04
2a756ca2cb1826db7796018e77d12e2dd7b67603 latest_2014.02.10
ca45b78adb4152fc6e7395514d46eba6b7d0b838 release_2014.08.11
-21f2a42a06d7d2b8c408aed22c691f5e8b209311 latest_2014.08.11
+9f495158c5ba45fcf61fc37d82aa8545eaba0bd5 latest_2014.08.11
diff -r f89efbcfd102b4aab4ffe29285348e3ee6a02cca -r 5cda4ac27e0a3c7b688e479a593698bfb3f0deb8 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -13,6 +13,7 @@
import ConfigParser
from datetime import timedelta
from galaxy.web.formatting import expand_pretty_datetime_format
+from galaxy.util.properties import load_app_properties
from galaxy.util import string_as_bool
from galaxy.util import listify
from galaxy.util.dbkeys import GenomeBuilds
@@ -20,9 +21,6 @@
log = logging.getLogger( __name__ )
-CONFIG_DEFAULT_PREFIX = "GALAXY_CONFIG_"
-CONFIG_OVERRIDE_PREFIX = "GALAXY_CONFIG_OVERRIDE_"
-
def resolve_path( path, root ):
"""If 'path' is relative make absolute by prepending 'root'"""
@@ -39,15 +37,9 @@
deprecated_options = ( 'database_file', )
def __init__( self, **kwargs ):
- for key in os.environ:
- if key.startswith( CONFIG_OVERRIDE_PREFIX ):
- config_key = key[ len( CONFIG_OVERRIDE_PREFIX ): ].lower()
- kwargs[ config_key ] = os.environ[ key ]
- elif key.startswith( CONFIG_DEFAULT_PREFIX ):
- config_key = key[ len( CONFIG_DEFAULT_PREFIX ): ].lower()
- if config_key not in kwargs:
- kwargs[ config_key ] = os.environ[ key ]
-
+ kwargs = load_app_properties(
+ kwds=kwargs
+ )
self.config_dict = kwargs
self.root = kwargs.get( 'root_dir', '.' )
diff -r f89efbcfd102b4aab4ffe29285348e3ee6a02cca -r 5cda4ac27e0a3c7b688e479a593698bfb3f0deb8 lib/galaxy/model/orm/scripts.py
--- a/lib/galaxy/model/orm/scripts.py
+++ b/lib/galaxy/model/orm/scripts.py
@@ -3,7 +3,6 @@
"""
import logging
import os.path
-from ConfigParser import SafeConfigParser
from galaxy import eggs
@@ -12,6 +11,7 @@
eggs.require( "SQLAlchemy" )
eggs.require( "sqlalchemy_migrate" )
+from galaxy.util.properties import load_app_properties
from galaxy.model.orm import dialect_to_egg
import pkg_resources
@@ -112,13 +112,13 @@
if cwd:
config_file = os.path.join( cwd, config_file )
- cp = SafeConfigParser()
- cp.read( config_file )
+ properties = load_app_properties( ini_file=config_file )
- if cp.has_option( "app:main", "%sdatabase_connection" % config_prefix):
- db_url = cp.get( "app:main", "%sdatabase_connection" % config_prefix )
- elif cp.has_option( "app:main", "%sdatabase_file" % config_prefix ):
- db_url = "sqlite:///%s?isolation_level=IMMEDIATE" % cp.get( "app:main", "database_file" )
+ if ("%sdatabase_connection" % config_prefix) in properties:
+ db_url = properties[ "%sdatabase_connection" % config_prefix ]
+ elif ("%sdatabase_file" % config_prefix) in properties:
+ database_file = properties[ "%sdatabase_file" % config_prefix ]
+ db_url = "sqlite:///%s?isolation_level=IMMEDIATE" % database_file
else:
db_url = "sqlite:///%s?isolation_level=IMMEDIATE" % default_sqlite_file
diff -r f89efbcfd102b4aab4ffe29285348e3ee6a02cca -r 5cda4ac27e0a3c7b688e479a593698bfb3f0deb8 lib/galaxy/util/properties.py
--- /dev/null
+++ b/lib/galaxy/util/properties.py
@@ -0,0 +1,41 @@
+""" Module used to blend ini, environment, and explicit dictionary properties
+to determine application configuration. Some hard coded defaults for Galaxy but
+this should be reusable by tool shed and pulsar as well.
+"""
+import os
+import os.path
+
+
+def load_app_properties(
+ kwds={},
+ ini_file=None,
+ ini_section="app:main",
+ config_prefix="GALAXY_CONFIG_"
+):
+ properties = kwds.copy() if kwds else {}
+ if ini_file:
+ defaults = {
+ 'here': os.path.dirname(os.path.abspath(ini_file)),
+ '__file__': os.path.abspath(ini_file)
+ }
+ # Mimic the way loadwsgi loads configuration files - needed for
+ # correctness given the very specific ways interpolation is handled.
+ from galaxy.util.pastescript.loadwsgi import NicerConfigParser
+ parser = NicerConfigParser(ini_file, defaults=defaults)
+ parser.optionxform = str # Don't lower-case keys
+ with open(ini_file) as f:
+ parser.read_file(f)
+
+ properties.update( dict( parser.items( ini_section ) ) )
+
+ override_prefix = "%sOVERRIDE_" % config_prefix
+ for key in os.environ:
+ if key.startswith( override_prefix ):
+ config_key = key[ len( override_prefix ): ].lower()
+ properties[ config_key ] = os.environ[ key ]
+ elif key.startswith( config_prefix ):
+ config_key = key[ len( config_prefix ): ].lower()
+ if config_key not in properties:
+ properties[ config_key ] = os.environ[ key ]
+
+ return properties
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jmchilton: Fix ORM scripts for 42f677bab2e4880b62758614fcb2c7dc27013788.
by commits-noreply@bitbucket.org 22 Sep '14
by commits-noreply@bitbucket.org 22 Sep '14
22 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d8fc0bf14dfe/
Changeset: d8fc0bf14dfe
Branch: next-stable
User: jmchilton
Date: 2014-09-22 23:14:12+00:00
Summary: Fix ORM scripts for 42f677bab2e4880b62758614fcb2c7dc27013788.
Updating common Python module used by ORM scripts (create_db.sh/migrate_db.sh/db_shell.py) to allow the same configuration via enviornment variables as well. Thanks to Bjoern for the bug report/feature request.
Affected #: 3 files
diff -r fa3bb4ad3b09d41cddc20cf0158f228c97866c0e -r d8fc0bf14dfeb6f59cef39e92984a46f2fafc4dc lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -13,6 +13,7 @@
import ConfigParser
from datetime import timedelta
from galaxy.web.formatting import expand_pretty_datetime_format
+from galaxy.util.properties import load_app_properties
from galaxy.util import string_as_bool
from galaxy.util import listify
from galaxy.util.dbkeys import GenomeBuilds
@@ -20,9 +21,6 @@
log = logging.getLogger( __name__ )
-CONFIG_DEFAULT_PREFIX = "GALAXY_CONFIG_"
-CONFIG_OVERRIDE_PREFIX = "GALAXY_CONFIG_OVERRIDE_"
-
def resolve_path( path, root ):
"""If 'path' is relative make absolute by prepending 'root'"""
@@ -39,15 +37,9 @@
deprecated_options = ( 'database_file', )
def __init__( self, **kwargs ):
- for key in os.environ:
- if key.startswith( CONFIG_OVERRIDE_PREFIX ):
- config_key = key[ len( CONFIG_OVERRIDE_PREFIX ): ].lower()
- kwargs[ config_key ] = os.environ[ key ]
- elif key.startswith( CONFIG_DEFAULT_PREFIX ):
- config_key = key[ len( CONFIG_DEFAULT_PREFIX ): ].lower()
- if config_key not in kwargs:
- kwargs[ config_key ] = os.environ[ key ]
-
+ kwargs = load_app_properties(
+ kwds=kwargs
+ )
self.config_dict = kwargs
self.root = kwargs.get( 'root_dir', '.' )
diff -r fa3bb4ad3b09d41cddc20cf0158f228c97866c0e -r d8fc0bf14dfeb6f59cef39e92984a46f2fafc4dc lib/galaxy/model/orm/scripts.py
--- a/lib/galaxy/model/orm/scripts.py
+++ b/lib/galaxy/model/orm/scripts.py
@@ -3,7 +3,6 @@
"""
import logging
import os.path
-from ConfigParser import SafeConfigParser
from galaxy import eggs
@@ -12,6 +11,7 @@
eggs.require( "SQLAlchemy" )
eggs.require( "sqlalchemy_migrate" )
+from galaxy.util.properties import load_app_properties
from galaxy.model.orm import dialect_to_egg
import pkg_resources
@@ -112,13 +112,13 @@
if cwd:
config_file = os.path.join( cwd, config_file )
- cp = SafeConfigParser()
- cp.read( config_file )
+ properties = load_app_properties( ini_file=config_file )
- if cp.has_option( "app:main", "%sdatabase_connection" % config_prefix):
- db_url = cp.get( "app:main", "%sdatabase_connection" % config_prefix )
- elif cp.has_option( "app:main", "%sdatabase_file" % config_prefix ):
- db_url = "sqlite:///%s?isolation_level=IMMEDIATE" % cp.get( "app:main", "database_file" )
+ if ("%sdatabase_connection" % config_prefix) in properties:
+ db_url = properties[ "%sdatabase_connection" % config_prefix ]
+ elif ("%sdatabase_file" % config_prefix) in properties:
+ database_file = properties[ "%sdatabase_file" % config_prefix ]
+ db_url = "sqlite:///%s?isolation_level=IMMEDIATE" % database_file
else:
db_url = "sqlite:///%s?isolation_level=IMMEDIATE" % default_sqlite_file
diff -r fa3bb4ad3b09d41cddc20cf0158f228c97866c0e -r d8fc0bf14dfeb6f59cef39e92984a46f2fafc4dc lib/galaxy/util/properties.py
--- /dev/null
+++ b/lib/galaxy/util/properties.py
@@ -0,0 +1,41 @@
+""" Module used to blend ini, environment, and explicit dictionary properties
+to determine application configuration. Some hard coded defaults for Galaxy but
+this should be reusable by tool shed and pulsar as well.
+"""
+import os
+import os.path
+
+
+def load_app_properties(
+ kwds={},
+ ini_file=None,
+ ini_section="app:main",
+ config_prefix="GALAXY_CONFIG_"
+):
+ properties = kwds.copy() if kwds else {}
+ if ini_file:
+ defaults = {
+ 'here': os.path.dirname(os.path.abspath(ini_file)),
+ '__file__': os.path.abspath(ini_file)
+ }
+ # Mimic the way loadwsgi loads configuration files - needed for
+ # correctness given the very specific ways interpolation is handled.
+ from galaxy.util.pastescript.loadwsgi import NicerConfigParser
+ parser = NicerConfigParser(ini_file, defaults=defaults)
+ parser.optionxform = str # Don't lower-case keys
+ with open(ini_file) as f:
+ parser.read_file(f)
+
+ properties.update( dict( parser.items( ini_section ) ) )
+
+ override_prefix = "%sOVERRIDE_" % config_prefix
+ for key in os.environ:
+ if key.startswith( override_prefix ):
+ config_key = key[ len( override_prefix ): ].lower()
+ properties[ config_key ] = os.environ[ key ]
+ elif key.startswith( config_prefix ):
+ config_key = key[ len( config_prefix ): ].lower()
+ if config_key not in properties:
+ properties[ config_key ] = os.environ[ key ]
+
+ return properties
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Ui: Fix slider and option styles
by commits-noreply@bitbucket.org 22 Sep '14
by commits-noreply@bitbucket.org 22 Sep '14
22 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/f89efbcfd102/
Changeset: f89efbcfd102
User: guerler
Date: 2014-09-22 21:11:09+00:00
Summary: Ui: Fix slider and option styles
Affected #: 2 files
diff -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c -r f89efbcfd102b4aab4ffe29285348e3ee6a02cca static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -148,7 +148,7 @@
.form-control::-moz-placeholder{color:#999}
.form-control:-ms-input-placeholder{color:#999}
.form-control::-webkit-input-placeholder{color:#999}
-.form-control,.ui-options,.ui-form-slider .ui-form-slider-text,.ui-input,.ui-textarea{display:block;width:100%;height:27px;padding:4px 10px;font-size:12px;line-height:1.428571429;color:#555;vertical-align:middle;background-color:#fff;border:1px solid #aaa;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}
+.form-control,.ui-input,.ui-textarea,.ui-options,.ui-form-slider .ui-form-slider-text,.ui-select-multiple{display:block;width:100%;height:27px;padding:4px 10px;font-size:12px;line-height:1.428571429;color:#555;vertical-align:middle;background-color:#fff;border:1px solid #aaa;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}
.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee}
textarea.form-control{height:auto}
.form-group{margin-bottom:15px}
@@ -1279,12 +1279,7 @@
.upload-settings .upload-settings-cover{position:absolute;width:100%;height:100%;top:0px;left:0px;background:#fff;opacity:0.4;cursor:no-drop}
.no-highlight,.ui-button-icon,.ui-portlet,.ui-portlet-repeat{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none;}
.ui-error{-moz-border-radius:3px;border-radius:3px;background:#f9c7c5;padding:5px}
-.ui-options{height:100% !important}
.ui-table-form-error{display:none}.ui-table-form-error .ui-table-form-error-text{padding-left:5px}
-.ui-form-slider .ui-form-slider-text{width:100px;float:left}
-.ui-form-slider .ui-form-slider-element{width:calc(100% - 110px);float:left;top:8px;left:10px}
-.ui-radiobutton{width:100%}.ui-radiobutton label{height:23px;line-height:1em}
-.ui-radiobutton i{padding-right:5px}
.ui-table tbody{cursor:pointer}
.ui-table-plain tbody td{padding:5px 0px 5px 0px !important;border:none !important}
.ui-table-plain tbody{cursor:auto !important}
@@ -1299,7 +1294,6 @@
.ui-button-icon .button{margin-right:5px;margin-left:5px}.ui-button-icon .button .title{position:relative;font-size:0.8em;font-weight:normal;top:-1px}
.ui-button-icon .button.disabled{filter:alpha(opacity=65);opacity:.65;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=65);filter:alpha(opacity=65)}
.ui-button-icon-plain{border:none !important;background:none !important}
-.ui-textarea{height:100px !important}
.ui-tabs .ui-tabs-add{font-size:0.8em;margin-right:5px}
.ui-tabs .ui-tabs-delete{font-size:0.8em;margin-left:5px;cursor:pointer}
.ui-portlet,.ui-portlet-repeat,.ui-portlet-repeat{border:solid #d6b161 1px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;position:relative;clear:both;width:auto;height:100%}.ui-portlet .portlet-header{background:#ebd9b2;border-bottom:solid #d6b161 1px;padding:2px 8px;overflow:visible;float:right;width:100%}.ui-portlet .portlet-header h1,.ui-portlet .portlet-header h2,.ui-portlet .portlet-header h3,.ui-portlet .portlet-header h4,.ui-portlet .portlet-header h5,.ui-portlet .portlet-header h6{float:left;font-weight:normal;display:inline-block;vertical-align:middle;font-size:1em;margin:3px}.ui-portlet .portlet-header h1 .icon,.ui-portlet .portlet-header h2 .icon,.ui-portlet .portlet-header h3 .icon,.ui-portlet .portlet-header h4 .icon,.ui-portlet .portlet-header h5 .icon,.ui-portlet .portlet-header h6 .icon{font-size:1.2em}
@@ -1311,7 +1305,14 @@
.ui-portlet-repeat .portlet-content{padding:0px}.ui-portlet-repeat .portlet-content .content{padding:0px;padding-left:10px}
.ui-popover{max-width:700px;display:none}.ui-popover .popover-close{position:absolute;right:10px;top:7px;font-size:1.2em;cursor:pointer}
.ui-popover .popover-title{padding:4px 10px}
-.ui-select,.ui-select-multiple{position:relative;height:27px;overflow:hidden;border:1px solid #bfbfbf;-moz-border-radius:3px;border-radius:3px}.ui-select .button{position:relative;width:25px;height:100%;float:right;border-left:1px solid #bfbfbf;padding-left:9px;padding-top:4px;background:#f2f2f2}
+.ui-input,.ui-textarea,.ui-options,.ui-form-slider .ui-form-slider-text,.ui-select-multiple,.ui-textarea,.ui-options,.ui-form-slider .ui-form-slider-text,.ui-select-multiple{background:transparent}
+.ui-textarea{height:100px !important}
+.ui-options{height:100% !important}
+.ui-form-slider{display:inline-block;width:100%}.ui-form-slider .ui-form-slider-text{width:100px;float:left}
+.ui-form-slider .ui-form-slider-element{width:calc(100% - 110px);float:left;top:8px;left:10px}
+.ui-radiobutton{width:100%}.ui-radiobutton label{height:23px;line-height:1em}
+.ui-radiobutton i{padding-right:5px}
+.ui-select{position:relative;height:27px;overflow:hidden;border:1px solid #bfbfbf;-moz-border-radius:3px;border-radius:3px}.ui-select .button{position:relative;width:25px;height:100%;float:right;border-left:1px solid #bfbfbf;padding-left:9px;padding-top:4px;background:#f2f2f2}
.ui-select select{position:absolute;top:0px;height:100%;width:100%;padding-left:5px;cursor:pointer;background:transparent;border:0;border-radius:0;-webkit-appearance:none}
.ui-select-multiple{height:100% !important;width:100% !important}
.libraryRow{background-color:#ebd9b2}
diff -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c -r f89efbcfd102b4aab4ffe29285348e3ee6a02cca static/style/src/less/ui.less
--- a/static/style/src/less/ui.less
+++ b/static/style/src/less/ui.less
@@ -12,11 +12,6 @@
padding: 5px;
}
-.ui-options {
- &:extend(.form-control);
- height: 100% !important;
-}
-
.ui-table-form-error {
display: none;
.ui-table-form-error-text {
@@ -24,33 +19,6 @@
}
}
-.ui-form-slider {
- .ui-form-slider-text {
- &:extend(.form-control);
- width: 100px;
- float: left;
- }
-
- .ui-form-slider-element {
- width: ~'calc(100% - 110px)';
- float: left;
- top: 8px;
- left: 10px;
- }
-}
-
-.ui-radiobutton {
- width: 100%;
- label {
- height: 23px;
- line-height: 1em;
- }
-
- i {
- padding-right: 5px;
- }
-}
-
.ui-table {
&:extend(.grid);
@@ -143,15 +111,6 @@
background: none !important;
}
-.ui-input {
- &:extend(.form-control);
-}
-
-.ui-textarea {
- &:extend(.form-control);
- height: 100px !important;
-}
-
.ui-tabs {
.ui-tabs-add {
font-size : 0.8em;
@@ -266,6 +225,51 @@
}
}
+.ui-input {
+ &:extend(.form-control);
+ background: transparent;
+}
+
+.ui-textarea {
+ &:extend(.ui-input);
+ height: 100px !important;
+}
+
+.ui-options {
+ &:extend(.ui-input);
+ height: 100% !important;
+}
+
+
+.ui-form-slider {
+ display: inline-block;
+ width: 100%;
+ .ui-form-slider-text {
+ &:extend(.ui-input);
+ width: 100px;
+ float: left;
+ }
+
+ .ui-form-slider-element {
+ width: ~'calc(100% - 110px)';
+ float: left;
+ top: 8px;
+ left: 10px;
+ }
+}
+
+.ui-radiobutton {
+ width: 100%;
+ label {
+ height: 23px;
+ line-height: 1em;
+ }
+
+ i {
+ padding-right: 5px;
+ }
+}
+
.ui-select {
position: relative;
height: 27px;
@@ -300,7 +304,7 @@
}
.ui-select-multiple {
- &:extend(.ui-select);
+ &:extend(.ui-input);
height: 100% !important;
width: 100% !important;
}
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: ToolForm: Ensure correct order of repeat blocks, adjust to api changes, add validation, fix minor issues
by commits-noreply@bitbucket.org 22 Sep '14
by commits-noreply@bitbucket.org 22 Sep '14
22 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/5636e8ac71d5/
Changeset: 5636e8ac71d5
User: guerler
Date: 2014-09-22 20:41:51+00:00
Summary: ToolForm: Ensure correct order of repeat blocks, adjust to api changes, add validation, fix minor issues
Affected #: 28 files
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c client/galaxy/scripts/mvc/tools/tools-datasets.js
--- a/client/galaxy/scripts/mvc/tools/tools-datasets.js
+++ b/client/galaxy/scripts/mvc/tools/tools-datasets.js
@@ -24,7 +24,8 @@
});
},
- // filter datasets by data type
+ /** Filters datasets by data type.
+ */
filterType: function(options) {
options = options || {};
return this.currHistoryContents.filter(function(content){
@@ -43,7 +44,8 @@
});
},
- // filter datasets by id
+ /** Filter datasets by id.
+ */
filter: function(filter_id) {
return _.first( this.currHistoryContents.filter( function( content ){ return content.get( 'id' ) === filter_id; }) );
}
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c client/galaxy/scripts/mvc/tools/tools-form.js
--- a/client/galaxy/scripts/mvc/tools/tools-form.js
+++ b/client/galaxy/scripts/mvc/tools/tools-form.js
@@ -1,4 +1,4 @@
-/*
+/**
This is the main class of the tool form plugin. It is referenced as 'app' in all lower level modules.
*/
define(['mvc/ui/ui-portlet', 'mvc/ui/ui-misc',
@@ -37,14 +37,14 @@
// creates the job handler
this.job_handler = new ToolJobs(this);
-
- // reset field list
+
+ // reset field list, which contains the input field elements
this.field_list = {};
- // reset sequential input definition list
+ // reset sequential input definition list, which contains the input definitions as provided from the api
this.input_list = {};
- // reset input element definition list
+ // reset input element list, which contains the dom elements of each input element (includes also the input field)
this.element_list = {};
// initialize datasets
@@ -190,8 +190,6 @@
// trigger refresh
self.refresh();
- //self.job_handler.submit();
- self.tree.finalize();
}
});
}
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c client/galaxy/scripts/mvc/tools/tools-jobs.js
--- a/client/galaxy/scripts/mvc/tools/tools-jobs.js
+++ b/client/galaxy/scripts/mvc/tools/tools-jobs.js
@@ -1,4 +1,4 @@
-/*
+/**
This class handles job submissions and the error handling.
*/
define(['utils/utils'], function(Utils) {
@@ -12,7 +12,8 @@
this.options = Utils.merge(options, this.optionsDefault);
},
- // create job
+ /** Creates and submits a job request to the api
+ */
submit: function() {
// link this
var self = this;
@@ -26,6 +27,12 @@
// reset
this.app.reset();
+ // validate job definition
+ if (!this._validation(job_def)) {
+ console.debug('tools-jobs::submit - Submission canceled. Validation failed.');
+ return;
+ }
+
// post job
Utils.request('POST', galaxy_config.root + 'api/tools', job_def,
// success handler
@@ -42,7 +49,7 @@
function(response) {
console.debug(response);
if (response && response.message && response.message.data) {
- var error_messages = self.app.tree.match(response.message.data);
+ var error_messages = self.app.tree.matchResponse(response.message.data);
for (var id in error_messages) {
var error_text = error_messages[id];
if (!error_text) {
@@ -55,7 +62,35 @@
);
},
- // refresh history panel
+ /** Validate job definition
+ */
+ _validation: function(job_def) {
+ // get input parameters
+ var job_inputs = job_def.inputs;
+
+ // validation flag
+ var valid = true;
+
+ // check inputs
+ for (var job_input_id in job_inputs) {
+ // collect input field properties
+ var input = job_inputs[job_input_id];
+ var input_id = this.app.tree.match(job_input_id);
+ var input_field = this.app.field_list[input_id];
+
+ // check field validation
+ //if (input_field && input_field.validate && !input_field.validate()) {
+ this.app.element_list[input_id].error('Please verify this parameter.');
+ valid = false;
+ //}
+ }
+
+ // return result
+ return false;
+ },
+
+ /** Refreshes the history panel
+ */
_refreshHdas: function() {
if (parent.Galaxy && parent.Galaxy.currHistoryPanel) {
parent.Galaxy.currHistoryPanel.refreshContents();
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c client/galaxy/scripts/mvc/tools/tools-repeat.js
--- a/client/galaxy/scripts/mvc/tools/tools-repeat.js
+++ b/client/galaxy/scripts/mvc/tools/tools-repeat.js
@@ -1,14 +1,16 @@
// dependencies
define(['utils/utils', 'mvc/ui/ui-table', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc'], function(Utils, Table, Portlet, Ui) {
-// return
+/** This class creates a ui component which enables the dynamic creation of portlets
+*/
var View = Backbone.View.extend({
// default options
optionsDefault : {
max : null
},
- // initialize
+ /** Initialize
+ */
initialize : function(options) {
// configure options
this.options = Utils.merge(options, this.optionsDefault);
@@ -48,12 +50,14 @@
this.list = {};
},
- // size
+ /** Number of repeat blocks
+ */
size: function() {
return _.size(this.list);
},
- // append
+ /** Add new repeat block
+ */
add: function(options) {
// delete button
var button_delete = new Ui.ButtonIcon({
@@ -101,12 +105,15 @@
}
},
- // delete
+ /** Delete repeat block
+ */
del: function(id) {
if (this.list[id]) {
// delete table row
var table_row = this.table.get('row_' + id);
table_row.remove();
+
+ // remove from list
delete this.list[id];
// enable new button
@@ -114,7 +121,8 @@
}
},
- // retitle
+ /** Retitle/Enumerate repeat blocks
+ */
retitle: function(new_title) {
var index = 0;
for (var id in this.list) {
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c client/galaxy/scripts/mvc/tools/tools-section.js
--- a/client/galaxy/scripts/mvc/tools/tools-section.js
+++ b/client/galaxy/scripts/mvc/tools/tools-section.js
@@ -1,4 +1,4 @@
-/*
+/**
This class creates a tool form section and populates it with input elements. It also handles repeat blocks and conditionals by recursively creating new sub sections. New input elements can be plugged in by adding cases to the switch block defined in the _addRow() function.
*/
define(['utils/utils', 'mvc/ui/ui-table', 'mvc/ui/ui-misc', 'mvc/tools/tools-repeat', 'mvc/tools/tools-select-dataset'],
@@ -11,19 +11,24 @@
this.setElement(this._template(options));
},
- // set error text
+ /** Set error text
+ */
error: function(text) {
// set text
this.$el.find('.ui-table-form-error-text').html(text);
this.$el.find('.ui-table-form-error').fadeIn();
+ this.$el.addClass('ui-error');
},
- // reset
+ /** Reset this view
+ */
reset: function() {
this.$el.find('.ui-table-form-error').hide();
+ this.$el.removeClass('ui-error');
},
- // template
+ /** Main Template
+ */
_template: function(options) {
// create table element
var $input = $('<div class="ui-table-element"/>');
@@ -73,7 +78,8 @@
this.render();
},
- // update
+ /** Render section view
+ */
render: function() {
// reset table
this.table.delAll();
@@ -84,7 +90,8 @@
}
},
- // add table row
+ /** Add a new input element
+ */
_add: function(input) {
// link this
var self = this;
@@ -115,7 +122,8 @@
}
},
- // add conditional block
+ /** Add a conditional block
+ */
_addConditional: function(input_def) {
// add label to input definition root
input_def.label = input_def.test_param.label;
@@ -148,11 +156,15 @@
}
},
- // add repeat block
+ /** Add a repeat block
+ */
_addRepeat: function(input_def) {
// link this
var self = this;
+ // block index
+ var block_index = 0;
+
//
// create tab field
//
@@ -161,7 +173,7 @@
max : input_def.max,
onnew : function() {
// create id tag
- var sub_section_id = input_def.id + '-section-' + Utils.uuid();
+ var sub_section_id = input_def.id + '-section-' + (block_index++);
// create sub section
var sub_section = new View(self.app, {
@@ -199,7 +211,7 @@
//
for (var i = 0; i < input_def.min; i++) {
// create id tag
- var sub_section_id = input_def.id + '-section-' + Utils.uuid();
+ var sub_section_id = input_def.id + '-section-' + (block_index++);
// create sub section
var sub_section = new View(self.app, {
@@ -235,7 +247,8 @@
this.table.append(input_def.id);
},
- // add table row
+ /** Add a single field element
+ */
_addRow: function(field_type, input_def) {
// get id
var id = input_def.id;
@@ -333,7 +346,8 @@
return this.table.get(id)
},
- // conditional input field
+ /** Conditional input field selector
+ */
_field_conditional : function(input_def) {
// link this
var self = this;
@@ -385,7 +399,8 @@
});
},
- // data input field
+ /** Data input field
+ */
_field_data : function(input_def) {
// link this
var self = this;
@@ -398,16 +413,19 @@
id : 'field-' + id,
extensions : input_def.extensions,
multiple : input_def.multiple,
- onchange : function(value) {
+ onchange : function(dict) {
// pick the first dataset if multiple might be selected
- // TODO: iterate over all datasets and filter common/consistent columns
- if (value instanceof Array) {
- value = value[0];
- }
+ var value = dict.values[0].id;
// get referenced columns
var column_list = self.app.tree.references(id, 'data_column');
+ // check data column list
+ if (column_list.length <= 0) {
+ console.debug('tool-form::field_data() - Data column parameters unavailable.');
+ return;
+ }
+
// find selected dataset
var dataset = self.app.datasets.filter(value);
@@ -415,7 +433,7 @@
var meta = null;
// check dataset
- if (dataset && column_list.length > 0) {
+ if (dataset) {
// log selection
console.debug('tool-form::field_data() - Selected dataset ' + value + '.');
@@ -427,7 +445,6 @@
console.debug('tool-form::field_data() - FAILED: Could not find metadata for dataset ' + value + '.');
}
} else {
- // log failure
console.debug('tool-form::field_data() - FAILED: Could not find dataset ' + value + '.');
}
@@ -479,7 +496,8 @@
});
},
- // select field
+ /** Select/Checkbox/Radio options field
+ */
_field_select : function (input_def) {
// configure options fields
var options = [];
@@ -510,7 +528,8 @@
});
},
- // text input field
+ /** Text input field
+ */
_field_text : function(input_def) {
return new Ui.Input({
id : 'field-' + input_def.id,
@@ -518,7 +537,8 @@
});
},
- // slider field
+ /** Slider field
+ */
_field_slider: function(input_def) {
// calculate step size
var step = 1;
@@ -535,14 +555,16 @@
});
},
- // hidden field
+ /** Hidden field
+ */
_field_hidden : function(input_def) {
return new Ui.Hidden({
id : 'field-' + input_def.id
});
},
- // boolean field
+ /** Boolean field
+ */
_field_boolean : function(input_def) {
return new Ui.RadioButton.View({
id : 'field-' + input_def.id,
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c client/galaxy/scripts/mvc/tools/tools-select-dataset.js
--- a/client/galaxy/scripts/mvc/tools/tools-select-dataset.js
+++ b/client/galaxy/scripts/mvc/tools/tools-select-dataset.js
@@ -11,13 +11,13 @@
this.setElement('<div/>');
// current selection
- this.current = 'dataset';
+ this.current = 'hda';
// create button
this.button_new = new Ui.RadioButton.View({
value : this.current,
- data : [ { icon: 'fa-file-o', label : 'Select datasets', value : 'dataset' },
- { icon: 'fa-files-o', label : 'Select a collection', value : 'collection' }],
+ data : [ { icon: 'fa-file-o', label : 'Select datasets', value : 'hda' },
+ { icon: 'fa-files-o', label : 'Select a collection', value : 'hdca' }],
onchange: function(value) {
self.current = value;
self.refresh();
@@ -94,29 +94,62 @@
});
},
- // value
+ /** Return the currently selected dataset values */
value : function () {
+ // identify select element
+ var select = null;
switch(this.current) {
- case 'dataset':
- return this.select_datasets.value();
- case 'collection':
- return this.select_collection.value();
+ case 'hda':
+ select = this.select_datasets;
+ break;
+ case 'hdca':
+ select = this.select_collection;
+ break;
+ }
+
+ // transform into an array
+ var id_list = select.value();
+ if (!(id_list instanceof Array)) {
+ id_list = [id_list];
+ }
+
+ // prepare result dict
+ var result = {
+ batch : !this.options.multiple,
+ values : []
+ }
+
+ // append to dataset ids
+ for (var i in id_list) {
+ result.values.push({
+ id : id_list[i],
+ src : this.current
+ });
+ }
+
+ // return
+ return result;
+ },
+
+ /** Validate current selection
+ */
+ validate: function() {
+ switch(this.current) {
+ case 'hda':
+ return this.select_datasets.validate();
+ case 'hdca':
+ return this.select_collection.validate();
}
},
- // render
- update: function(options) {
- this.select.update(options);
- },
-
- // refresh
+ /** Refreshes data selection view */
refresh: function() {
switch (this.current) {
- case 'dataset':
+ case 'hda':
this.select_datasets.$el.fadeIn();
this.select_collection.$el.hide();
break;
- case 'collection':
+ case 'hdca':
this.select_datasets.$el.hide();
this.select_collection.$el.fadeIn();
break;
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c client/galaxy/scripts/mvc/tools/tools-tree.js
--- a/client/galaxy/scripts/mvc/tools/tools-tree.js
+++ b/client/galaxy/scripts/mvc/tools/tools-tree.js
@@ -67,11 +67,30 @@
switch (input.type) {
// handle repeats
case 'repeat':
+ // section identifier
+ var section_label = 'section-';
+
+ // collect repeat block identifiers
+ var block_indices = [];
+ var block_prefix = null;
+ for (var block_label in node) {
+ var pos = block_label.indexOf(section_label);
+ if (pos != -1) {
+ pos += section_label.length;
+ block_indices.push(parseInt(block_label.substr(pos)));
+ if (!block_prefix) {
+ block_prefix = block_label.substr(0, pos);
+ }
+ }
+ }
+
+ // sort repeat blocks
+ block_indices.sort(function(a,b) { return a - b; });
+
+ // add to response dictionary in created order
var index = 0;
- for (var i in node) {
- if (i.indexOf('section') != -1) {
- convert(job_input_id + '_' + index++, node[i]);
- }
+ for (var i in block_indices) {
+ convert(job_input_id + '_' + index++, node[block_prefix + block_indices[i]]);
}
break;
// handle conditionals
@@ -90,32 +109,6 @@
}
}
break;
- // handle data inputs
- case 'data':
- // create array for dataset ids
- var dataset_selection = null;
-
- // collect dataset ids from input field
- var value = self.app.field_list[input.id].value();
- if (typeof value === 'string') {
- dataset_selection = {
- id : value,
- src : 'hda'
- };
- } else {
- // create array of dataset dictionaries for api submission
- dataset_selection = [];
- for (var i in value) {
- dataset_selection.push({
- id : value[i],
- src : 'hda'
- });
- }
- }
-
- // add final array to job definition
- add(job_input_id, input.id, dataset_selection);
- break;
// handle boolean input
case 'boolean':
var value = self.app.field_list[input.id].value();
@@ -136,14 +129,20 @@
// start conversion
convert('', this.dict);
- console.log(this.job_def);
+
// return result
return this.job_def;
},
+ /** Match job definition identifier to input element identifier
+ */
+ match: function (job_input_id) {
+ return this.job_ids && this.job_ids[job_input_id];
+ },
+
/** Matches identifier from api response to input element
*/
- match: function(response) {
+ matchResponse: function(response) {
// final result dictionary
var result = {};
@@ -263,7 +262,7 @@
var id = $(child).attr('id');
// create new branch
- if ($(child).hasClass('section-row') || $(child).hasClass('tab-pane')) {
+ if ($(child).hasClass('section-row')) {
// create sub dictionary
dict[id] = {};
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c client/galaxy/scripts/mvc/ui/ui-options.js
--- a/client/galaxy/scripts/mvc/ui/ui-options.js
+++ b/client/galaxy/scripts/mvc/ui/ui-options.js
@@ -1,7 +1,7 @@
// dependencies
define(['utils/utils'], function(Utils) {
-/** base class for options based ui elements **/
+/** Base class for options based ui elements **/
var OptionsBase = Backbone.View.extend({
// initialize
initialize: function(options) {
@@ -48,7 +48,8 @@
});
},
- // update options
+ /** Update options
+ */
update: function(options) {
// backup current value
var current = this._getValue();
@@ -80,7 +81,8 @@
this.value(current);
},
- // check if selected value exists (or any if multiple)
+ /** Check if selected value exists (or any if multiple)
+ */
exists: function(value) {
if (typeof value === 'string') {
value = [value];
@@ -93,7 +95,8 @@
return false;
},
- // first
+ /** Return first available option
+ */
first: function() {
var options = this.$el.find('input');
if (options.length > 0) {
@@ -103,14 +106,31 @@
}
},
- // change
+ /** Validate the selected option/options
+ */
+ validate: function() {
+ var current = this.value();
+ if (!(current instanceof Array)) {
+ current = [current];
+ }
+ for (var i in current) {
+ if (current[i] === 'null' || !current[i]) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ /** Trigger custom onchange callback function
+ */
_change: function() {
if (this.options.onchange) {
this.options.onchange(this._getValue());
}
},
- // refresh
+ /** Refresh options view
+ */
_refresh: function() {
// count remaining options
var remaining = this.$el.find('.ui-option').length;
@@ -123,7 +143,8 @@
}
},
- // get value
+ /** Return current selection
+ */
_getValue: function() {
// get selected values
var selected = this.$el.find(':checked');
@@ -148,7 +169,7 @@
}
});
-/** radio button field **/
+/** Radio button field **/
var Radio = {};
Radio.View = OptionsBase.extend({
// initialize
@@ -156,7 +177,8 @@
OptionsBase.prototype.initialize.call(this, options);
},
- // value
+ /** Return/Set current value
+ */
value: function (new_val) {
// check if its an array
if (typeof new_val === 'string') {
@@ -178,20 +200,22 @@
return this._getValue();
},
- // template for options
+ /** Template for options
+ */
_templateOption: function(pair) {
return '<div>' +
'<input type="radio" name="' + this.options.id + '" value="' + pair.value + '"/>' + pair.label + '<br>' +
'</div>';
},
- // template
+ /** Main template function
+ */
_template: function() {
return '<div class="ui-options"/>';
}
});
-/** checkbox options field **/
+/** Checkbox options field **/
var Checkbox = {};
Checkbox.View = Radio.View.extend({
// initialize
@@ -200,7 +224,8 @@
Radio.View.prototype.initialize.call(this, options);
},
- // template for options
+ /** Template for options
+ */
_templateOption: function(pair) {
return '<div>' +
'<input type="checkbox" name="' + this.options.id + '" value="' + pair.value + '"/>' + pair.label + '<br>' +
@@ -208,7 +233,7 @@
}
});
-/** radio button options field styled as classic buttons **/
+/** Radio button options field styled as classic buttons **/
var RadioButton = {};
RadioButton.View = OptionsBase.extend({
// initialize
@@ -216,7 +241,8 @@
OptionsBase.prototype.initialize.call(this, options);
},
- // value
+ /** Return/Set current value
+ */
value: function (new_val) {
// set new value
if (new_val !== undefined) {
@@ -229,7 +255,8 @@
return this._getValue();
},
- // template for options
+ /** Template for options
+ */
_templateOption: function(pair) {
var tmpl = '<label class="btn btn-default">';
if (pair.icon) {
@@ -240,7 +267,8 @@
return tmpl;
},
- // template
+ /** Main template function
+ */
_template: function() {
return '<div class="btn-group ui-radiobutton" data-toggle="buttons"/>';
}
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c client/galaxy/scripts/mvc/ui/ui-portlet.js
--- a/client/galaxy/scripts/mvc/ui/ui-portlet.js
+++ b/client/galaxy/scripts/mvc/ui/ui-portlet.js
@@ -153,7 +153,7 @@
// fill regular modal template
_template: function(options) {
- var tmpl = '<div class="' + options.cls + '">';
+ var tmpl = '<div id="' + options.id + '" class="' + options.cls + '">';
if (options.title) {
tmpl += '<div id="portlet-header" class="portlet-header">' +
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c client/galaxy/scripts/mvc/ui/ui-select-default.js
--- a/client/galaxy/scripts/mvc/ui/ui-select-default.js
+++ b/client/galaxy/scripts/mvc/ui/ui-select-default.js
@@ -63,7 +63,8 @@
});
},
- // value
+ /** Return/Set current selection
+ */
value : function (new_value) {
if (new_value !== undefined) {
this.$select.val(new_value);
@@ -71,7 +72,8 @@
return this.$select.val();
},
- // first
+ /** Return the first select option
+ */
first: function() {
var options = this.$select.find('option');
if (options.length > 0) {
@@ -81,12 +83,29 @@
}
},
- // label
+ /** Validate the current selection
+ */
+ validate: function() {
+ var current = this.value();
+ if (!(current instanceof Array)) {
+ current = [current];
+ }
+ for (var i in current) {
+ if (current[i] === 'null' || !current[i]) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ /** Return the label/text of the current selection
+ */
text : function () {
return this.$select.find('option:selected').text();
},
- // show
+ /** Show the select field
+ */
show: function() {
this.$icon.removeClass();
this.$icon.addClass('fa fa-caret-down');
@@ -94,34 +113,40 @@
this.$el.show();
},
- // hide
+ /** Hide the select field
+ */
hide: function() {
this.$el.hide();
},
- // wait
+ /** Show a spinner indicating that the select options are currently loaded
+ */
wait: function() {
this.$icon.removeClass();
this.$icon.addClass('fa fa-spinner fa-spin');
this.$select.hide();
},
- // disabled
+ /** Returns true if the field is disabled
+ */
disabled: function() {
return this.$select.is(':disabled');
},
- // enable
+ /** Enable the select field
+ */
enable: function() {
this.$select.prop('disabled', false);
},
- // disable
+ /** Disable the select field
+ */
disable: function() {
this.$select.prop('disabled', true);
},
- // add
+ /** Add a select option
+ */
add: function(options) {
// add options
this.$select.append(this._templateOption(options));
@@ -130,7 +155,8 @@
this._refresh();
},
- // remove
+ /** Delete a select option
+ */
del: function(value) {
// remove option
this.$select.find('option[value=' + value + ']').remove();
@@ -140,7 +166,8 @@
this._refresh();
},
- // render
+ /** Update select options
+ */
update: function(options) {
// backup current value
var current = this.$select.val();
@@ -165,24 +192,28 @@
}
},
- // set on change event
+ /** Set the custom onchange callback function
+ */
setOnChange: function(callback) {
this.options.onchange = callback;
},
- // check if selected value exists
+ /** Check if a value is an existing option
+ */
exists: function(value) {
return this.$select.find('option[value="' + value + '"]').length > 0;
},
- // change
+ /** Trigger custom onchange callback
+ */
_change: function() {
if (this.options.onchange) {
this.options.onchange(this.$select.val());
}
},
- // refresh
+ /** Refresh the select view
+ */
_refresh: function() {
// remove placeholder
this.$select.find('option[value=null]').remove();
@@ -201,12 +232,14 @@
}
},
- // template option
+ /** Template for select options
+ */
_templateOption: function(options) {
return '<option value="' + options.value + '">' + options.label + '</option>';
},
- // template
+ /** Template for select view
+ */
_template: function(options) {
return '<div id="' + options.id + '">' +
'<div class="button">' +
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c static/scripts/mvc/tools/tools-datasets.js
--- a/static/scripts/mvc/tools/tools-datasets.js
+++ b/static/scripts/mvc/tools/tools-datasets.js
@@ -24,7 +24,8 @@
});
},
- // filter datasets by data type
+ /** Filters datasets by data type.
+ */
filterType: function(options) {
options = options || {};
return this.currHistoryContents.filter(function(content){
@@ -43,7 +44,8 @@
});
},
- // filter datasets by id
+ /** Filter datasets by id.
+ */
filter: function(filter_id) {
return _.first( this.currHistoryContents.filter( function( content ){ return content.get( 'id' ) === filter_id; }) );
}
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c static/scripts/mvc/tools/tools-form.js
--- a/static/scripts/mvc/tools/tools-form.js
+++ b/static/scripts/mvc/tools/tools-form.js
@@ -1,4 +1,4 @@
-/*
+/**
This is the main class of the tool form plugin. It is referenced as 'app' in all lower level modules.
*/
define(['mvc/ui/ui-portlet', 'mvc/ui/ui-misc',
@@ -37,14 +37,14 @@
// creates the job handler
this.job_handler = new ToolJobs(this);
-
- // reset field list
+
+ // reset field list, which contains the input field elements
this.field_list = {};
- // reset sequential input definition list
+ // reset sequential input definition list, which contains the input definitions as provided from the api
this.input_list = {};
- // reset input element definition list
+ // reset input element list, which contains the dom elements of each input element (includes also the input field)
this.element_list = {};
// initialize datasets
@@ -190,8 +190,6 @@
// trigger refresh
self.refresh();
- //self.job_handler.submit();
- self.tree.finalize();
}
});
}
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c static/scripts/mvc/tools/tools-jobs.js
--- a/static/scripts/mvc/tools/tools-jobs.js
+++ b/static/scripts/mvc/tools/tools-jobs.js
@@ -1,4 +1,4 @@
-/*
+/**
This class handles job submissions and the error handling.
*/
define(['utils/utils'], function(Utils) {
@@ -12,7 +12,8 @@
this.options = Utils.merge(options, this.optionsDefault);
},
- // create job
+ /** Creates and submits a job request to the api
+ */
submit: function() {
// link this
var self = this;
@@ -26,6 +27,12 @@
// reset
this.app.reset();
+ // validate job definition
+ if (!this._validation(job_def)) {
+ console.debug('tools-jobs::submit - Submission canceled. Validation failed.');
+ return;
+ }
+
// post job
Utils.request('POST', galaxy_config.root + 'api/tools', job_def,
// success handler
@@ -42,7 +49,7 @@
function(response) {
console.debug(response);
if (response && response.message && response.message.data) {
- var error_messages = self.app.tree.match(response.message.data);
+ var error_messages = self.app.tree.matchResponse(response.message.data);
for (var id in error_messages) {
var error_text = error_messages[id];
if (!error_text) {
@@ -55,7 +62,35 @@
);
},
- // refresh history panel
+ /** Validate job definition
+ */
+ _validation: function(job_def) {
+ // get input parameters
+ var job_inputs = job_def.inputs;
+
+ // validation flag
+ var valid = true;
+
+ // check inputs
+ for (var job_input_id in job_inputs) {
+ // collect input field properties
+ var input = job_inputs[job_input_id];
+ var input_id = this.app.tree.match(job_input_id);
+ var input_field = this.app.field_list[input_id];
+
+ // check field validation
+ //if (input_field && input_field.validate && !input_field.validate()) {
+ this.app.element_list[input_id].error('Please verify this parameter.');
+ valid = false;
+ //}
+ }
+
+ // return result
+ return false;
+ },
+
+ /** Refreshes the history panel
+ */
_refreshHdas: function() {
if (parent.Galaxy && parent.Galaxy.currHistoryPanel) {
parent.Galaxy.currHistoryPanel.refreshContents();
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c static/scripts/mvc/tools/tools-repeat.js
--- a/static/scripts/mvc/tools/tools-repeat.js
+++ b/static/scripts/mvc/tools/tools-repeat.js
@@ -1,14 +1,16 @@
// dependencies
define(['utils/utils', 'mvc/ui/ui-table', 'mvc/ui/ui-portlet', 'mvc/ui/ui-misc'], function(Utils, Table, Portlet, Ui) {
-// return
+/** This class creates a ui component which enables the dynamic creation of portlets
+*/
var View = Backbone.View.extend({
// default options
optionsDefault : {
max : null
},
- // initialize
+ /** Initialize
+ */
initialize : function(options) {
// configure options
this.options = Utils.merge(options, this.optionsDefault);
@@ -48,12 +50,14 @@
this.list = {};
},
- // size
+ /** Number of repeat blocks
+ */
size: function() {
return _.size(this.list);
},
- // append
+ /** Add new repeat block
+ */
add: function(options) {
// delete button
var button_delete = new Ui.ButtonIcon({
@@ -101,12 +105,15 @@
}
},
- // delete
+ /** Delete repeat block
+ */
del: function(id) {
if (this.list[id]) {
// delete table row
var table_row = this.table.get('row_' + id);
table_row.remove();
+
+ // remove from list
delete this.list[id];
// enable new button
@@ -114,7 +121,8 @@
}
},
- // retitle
+ /** Retitle/Enumerate repeat blocks
+ */
retitle: function(new_title) {
var index = 0;
for (var id in this.list) {
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c static/scripts/mvc/tools/tools-section.js
--- a/static/scripts/mvc/tools/tools-section.js
+++ b/static/scripts/mvc/tools/tools-section.js
@@ -1,4 +1,4 @@
-/*
+/**
This class creates a tool form section and populates it with input elements. It also handles repeat blocks and conditionals by recursively creating new sub sections. New input elements can be plugged in by adding cases to the switch block defined in the _addRow() function.
*/
define(['utils/utils', 'mvc/ui/ui-table', 'mvc/ui/ui-misc', 'mvc/tools/tools-repeat', 'mvc/tools/tools-select-dataset'],
@@ -11,19 +11,24 @@
this.setElement(this._template(options));
},
- // set error text
+ /** Set error text
+ */
error: function(text) {
// set text
this.$el.find('.ui-table-form-error-text').html(text);
this.$el.find('.ui-table-form-error').fadeIn();
+ this.$el.addClass('ui-error');
},
- // reset
+ /** Reset this view
+ */
reset: function() {
this.$el.find('.ui-table-form-error').hide();
+ this.$el.removeClass('ui-error');
},
- // template
+ /** Main Template
+ */
_template: function(options) {
// create table element
var $input = $('<div class="ui-table-element"/>');
@@ -73,7 +78,8 @@
this.render();
},
- // update
+ /** Render section view
+ */
render: function() {
// reset table
this.table.delAll();
@@ -84,7 +90,8 @@
}
},
- // add table row
+ /** Add a new input element
+ */
_add: function(input) {
// link this
var self = this;
@@ -115,7 +122,8 @@
}
},
- // add conditional block
+ /** Add a conditional block
+ */
_addConditional: function(input_def) {
// add label to input definition root
input_def.label = input_def.test_param.label;
@@ -148,11 +156,15 @@
}
},
- // add repeat block
+ /** Add a repeat block
+ */
_addRepeat: function(input_def) {
// link this
var self = this;
+ // block index
+ var block_index = 0;
+
//
// create tab field
//
@@ -161,7 +173,7 @@
max : input_def.max,
onnew : function() {
// create id tag
- var sub_section_id = input_def.id + '-section-' + Utils.uuid();
+ var sub_section_id = input_def.id + '-section-' + (block_index++);
// create sub section
var sub_section = new View(self.app, {
@@ -199,7 +211,7 @@
//
for (var i = 0; i < input_def.min; i++) {
// create id tag
- var sub_section_id = input_def.id + '-section-' + Utils.uuid();
+ var sub_section_id = input_def.id + '-section-' + (block_index++);
// create sub section
var sub_section = new View(self.app, {
@@ -235,7 +247,8 @@
this.table.append(input_def.id);
},
- // add table row
+ /** Add a single field element
+ */
_addRow: function(field_type, input_def) {
// get id
var id = input_def.id;
@@ -333,7 +346,8 @@
return this.table.get(id)
},
- // conditional input field
+ /** Conditional input field selector
+ */
_field_conditional : function(input_def) {
// link this
var self = this;
@@ -385,7 +399,8 @@
});
},
- // data input field
+ /** Data input field
+ */
_field_data : function(input_def) {
// link this
var self = this;
@@ -398,16 +413,19 @@
id : 'field-' + id,
extensions : input_def.extensions,
multiple : input_def.multiple,
- onchange : function(value) {
+ onchange : function(dict) {
// pick the first dataset if multiple might be selected
- // TODO: iterate over all datasets and filter common/consistent columns
- if (value instanceof Array) {
- value = value[0];
- }
+ var value = dict.values[0].id;
// get referenced columns
var column_list = self.app.tree.references(id, 'data_column');
+ // check data column list
+ if (column_list.length <= 0) {
+ console.debug('tool-form::field_data() - Data column parameters unavailable.');
+ return;
+ }
+
// find selected dataset
var dataset = self.app.datasets.filter(value);
@@ -415,7 +433,7 @@
var meta = null;
// check dataset
- if (dataset && column_list.length > 0) {
+ if (dataset) {
// log selection
console.debug('tool-form::field_data() - Selected dataset ' + value + '.');
@@ -427,7 +445,6 @@
console.debug('tool-form::field_data() - FAILED: Could not find metadata for dataset ' + value + '.');
}
} else {
- // log failure
console.debug('tool-form::field_data() - FAILED: Could not find dataset ' + value + '.');
}
@@ -479,7 +496,8 @@
});
},
- // select field
+ /** Select/Checkbox/Radio options field
+ */
_field_select : function (input_def) {
// configure options fields
var options = [];
@@ -510,7 +528,8 @@
});
},
- // text input field
+ /** Text input field
+ */
_field_text : function(input_def) {
return new Ui.Input({
id : 'field-' + input_def.id,
@@ -518,7 +537,8 @@
});
},
- // slider field
+ /** Slider field
+ */
_field_slider: function(input_def) {
// calculate step size
var step = 1;
@@ -535,14 +555,16 @@
});
},
- // hidden field
+ /** Hidden field
+ */
_field_hidden : function(input_def) {
return new Ui.Hidden({
id : 'field-' + input_def.id
});
},
- // boolean field
+ /** Boolean field
+ */
_field_boolean : function(input_def) {
return new Ui.RadioButton.View({
id : 'field-' + input_def.id,
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c static/scripts/mvc/tools/tools-select-dataset.js
--- a/static/scripts/mvc/tools/tools-select-dataset.js
+++ b/static/scripts/mvc/tools/tools-select-dataset.js
@@ -11,13 +11,13 @@
this.setElement('<div/>');
// current selection
- this.current = 'dataset';
+ this.current = 'hda';
// create button
this.button_new = new Ui.RadioButton.View({
value : this.current,
- data : [ { icon: 'fa-file-o', label : 'Select datasets', value : 'dataset' },
- { icon: 'fa-files-o', label : 'Select a collection', value : 'collection' }],
+ data : [ { icon: 'fa-file-o', label : 'Select datasets', value : 'hda' },
+ { icon: 'fa-files-o', label : 'Select a collection', value : 'hdca' }],
onchange: function(value) {
self.current = value;
self.refresh();
@@ -94,29 +94,62 @@
});
},
- // value
+ /** Return the currently selected dataset values */
value : function () {
+ // identify select element
+ var select = null;
switch(this.current) {
- case 'dataset':
- return this.select_datasets.value();
- case 'collection':
- return this.select_collection.value();
+ case 'hda':
+ select = this.select_datasets;
+ break;
+ case 'hdca':
+ select = this.select_collection;
+ break;
+ }
+
+ // transform into an array
+ var id_list = select.value();
+ if (!(id_list instanceof Array)) {
+ id_list = [id_list];
+ }
+
+ // prepare result dict
+ var result = {
+ batch : !this.options.multiple,
+ values : []
+ }
+
+ // append to dataset ids
+ for (var i in id_list) {
+ result.values.push({
+ id : id_list[i],
+ src : this.current
+ });
+ }
+
+ // return
+ return result;
+ },
+
+ /** Validate current selection
+ */
+ validate: function() {
+ switch(this.current) {
+ case 'hda':
+ return this.select_datasets.validate();
+ case 'hdca':
+ return this.select_collection.validate();
}
},
- // render
- update: function(options) {
- this.select.update(options);
- },
-
- // refresh
+ /** Refreshes data selection view */
refresh: function() {
switch (this.current) {
- case 'dataset':
+ case 'hda':
this.select_datasets.$el.fadeIn();
this.select_collection.$el.hide();
break;
- case 'collection':
+ case 'hdca':
this.select_datasets.$el.hide();
this.select_collection.$el.fadeIn();
break;
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c static/scripts/mvc/tools/tools-tree.js
--- a/static/scripts/mvc/tools/tools-tree.js
+++ b/static/scripts/mvc/tools/tools-tree.js
@@ -67,11 +67,30 @@
switch (input.type) {
// handle repeats
case 'repeat':
+ // section identifier
+ var section_label = 'section-';
+
+ // collect repeat block identifiers
+ var block_indices = [];
+ var block_prefix = null;
+ for (var block_label in node) {
+ var pos = block_label.indexOf(section_label);
+ if (pos != -1) {
+ pos += section_label.length;
+ block_indices.push(parseInt(block_label.substr(pos)));
+ if (!block_prefix) {
+ block_prefix = block_label.substr(0, pos);
+ }
+ }
+ }
+
+ // sort repeat blocks
+ block_indices.sort(function(a,b) { return a - b; });
+
+ // add to response dictionary in created order
var index = 0;
- for (var i in node) {
- if (i.indexOf('section') != -1) {
- convert(job_input_id + '_' + index++, node[i]);
- }
+ for (var i in block_indices) {
+ convert(job_input_id + '_' + index++, node[block_prefix + block_indices[i]]);
}
break;
// handle conditionals
@@ -90,32 +109,6 @@
}
}
break;
- // handle data inputs
- case 'data':
- // create array for dataset ids
- var dataset_selection = null;
-
- // collect dataset ids from input field
- var value = self.app.field_list[input.id].value();
- if (typeof value === 'string') {
- dataset_selection = {
- id : value,
- src : 'hda'
- };
- } else {
- // create array of dataset dictionaries for api submission
- dataset_selection = [];
- for (var i in value) {
- dataset_selection.push({
- id : value[i],
- src : 'hda'
- });
- }
- }
-
- // add final array to job definition
- add(job_input_id, input.id, dataset_selection);
- break;
// handle boolean input
case 'boolean':
var value = self.app.field_list[input.id].value();
@@ -136,14 +129,20 @@
// start conversion
convert('', this.dict);
- console.log(this.job_def);
+
// return result
return this.job_def;
},
+ /** Match job definition identifier to input element identifier
+ */
+ match: function (job_input_id) {
+ return this.job_ids && this.job_ids[job_input_id];
+ },
+
/** Matches identifier from api response to input element
*/
- match: function(response) {
+ matchResponse: function(response) {
// final result dictionary
var result = {};
@@ -263,7 +262,7 @@
var id = $(child).attr('id');
// create new branch
- if ($(child).hasClass('section-row') || $(child).hasClass('tab-pane')) {
+ if ($(child).hasClass('section-row')) {
// create sub dictionary
dict[id] = {};
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c static/scripts/mvc/ui/ui-options.js
--- a/static/scripts/mvc/ui/ui-options.js
+++ b/static/scripts/mvc/ui/ui-options.js
@@ -1,7 +1,7 @@
// dependencies
define(['utils/utils'], function(Utils) {
-/** base class for options based ui elements **/
+/** Base class for options based ui elements **/
var OptionsBase = Backbone.View.extend({
// initialize
initialize: function(options) {
@@ -48,7 +48,8 @@
});
},
- // update options
+ /** Update options
+ */
update: function(options) {
// backup current value
var current = this._getValue();
@@ -80,7 +81,8 @@
this.value(current);
},
- // check if selected value exists (or any if multiple)
+ /** Check if selected value exists (or any if multiple)
+ */
exists: function(value) {
if (typeof value === 'string') {
value = [value];
@@ -93,7 +95,8 @@
return false;
},
- // first
+ /** Return first available option
+ */
first: function() {
var options = this.$el.find('input');
if (options.length > 0) {
@@ -103,14 +106,31 @@
}
},
- // change
+ /** Validate the selected option/options
+ */
+ validate: function() {
+ var current = this.value();
+ if (!(current instanceof Array)) {
+ current = [current];
+ }
+ for (var i in current) {
+ if (current[i] === 'null' || !current[i]) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ /** Trigger custom onchange callback function
+ */
_change: function() {
if (this.options.onchange) {
this.options.onchange(this._getValue());
}
},
- // refresh
+ /** Refresh options view
+ */
_refresh: function() {
// count remaining options
var remaining = this.$el.find('.ui-option').length;
@@ -123,7 +143,8 @@
}
},
- // get value
+ /** Return current selection
+ */
_getValue: function() {
// get selected values
var selected = this.$el.find(':checked');
@@ -148,7 +169,7 @@
}
});
-/** radio button field **/
+/** Radio button field **/
var Radio = {};
Radio.View = OptionsBase.extend({
// initialize
@@ -156,7 +177,8 @@
OptionsBase.prototype.initialize.call(this, options);
},
- // value
+ /** Return/Set current value
+ */
value: function (new_val) {
// check if its an array
if (typeof new_val === 'string') {
@@ -178,20 +200,22 @@
return this._getValue();
},
- // template for options
+ /** Template for options
+ */
_templateOption: function(pair) {
return '<div>' +
'<input type="radio" name="' + this.options.id + '" value="' + pair.value + '"/>' + pair.label + '<br>' +
'</div>';
},
- // template
+ /** Main template function
+ */
_template: function() {
return '<div class="ui-options"/>';
}
});
-/** checkbox options field **/
+/** Checkbox options field **/
var Checkbox = {};
Checkbox.View = Radio.View.extend({
// initialize
@@ -200,7 +224,8 @@
Radio.View.prototype.initialize.call(this, options);
},
- // template for options
+ /** Template for options
+ */
_templateOption: function(pair) {
return '<div>' +
'<input type="checkbox" name="' + this.options.id + '" value="' + pair.value + '"/>' + pair.label + '<br>' +
@@ -208,7 +233,7 @@
}
});
-/** radio button options field styled as classic buttons **/
+/** Radio button options field styled as classic buttons **/
var RadioButton = {};
RadioButton.View = OptionsBase.extend({
// initialize
@@ -216,7 +241,8 @@
OptionsBase.prototype.initialize.call(this, options);
},
- // value
+ /** Return/Set current value
+ */
value: function (new_val) {
// set new value
if (new_val !== undefined) {
@@ -229,7 +255,8 @@
return this._getValue();
},
- // template for options
+ /** Template for options
+ */
_templateOption: function(pair) {
var tmpl = '<label class="btn btn-default">';
if (pair.icon) {
@@ -240,7 +267,8 @@
return tmpl;
},
- // template
+ /** Main template function
+ */
_template: function() {
return '<div class="btn-group ui-radiobutton" data-toggle="buttons"/>';
}
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c static/scripts/mvc/ui/ui-portlet.js
--- a/static/scripts/mvc/ui/ui-portlet.js
+++ b/static/scripts/mvc/ui/ui-portlet.js
@@ -153,7 +153,7 @@
// fill regular modal template
_template: function(options) {
- var tmpl = '<div class="' + options.cls + '">';
+ var tmpl = '<div id="' + options.id + '" class="' + options.cls + '">';
if (options.title) {
tmpl += '<div id="portlet-header" class="portlet-header">' +
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c static/scripts/mvc/ui/ui-select-default.js
--- a/static/scripts/mvc/ui/ui-select-default.js
+++ b/static/scripts/mvc/ui/ui-select-default.js
@@ -63,7 +63,8 @@
});
},
- // value
+ /** Return/Set current selection
+ */
value : function (new_value) {
if (new_value !== undefined) {
this.$select.val(new_value);
@@ -71,7 +72,8 @@
return this.$select.val();
},
- // first
+ /** Return the first select option
+ */
first: function() {
var options = this.$select.find('option');
if (options.length > 0) {
@@ -81,12 +83,29 @@
}
},
- // label
+ /** Validate the current selection
+ */
+ validate: function() {
+ var current = this.value();
+ if (!(current instanceof Array)) {
+ current = [current];
+ }
+ for (var i in current) {
+ if (current[i] === 'null' || !current[i]) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ /** Return the label/text of the current selection
+ */
text : function () {
return this.$select.find('option:selected').text();
},
- // show
+ /** Show the select field
+ */
show: function() {
this.$icon.removeClass();
this.$icon.addClass('fa fa-caret-down');
@@ -94,34 +113,40 @@
this.$el.show();
},
- // hide
+ /** Hide the select field
+ */
hide: function() {
this.$el.hide();
},
- // wait
+ /** Show a spinner indicating that the select options are currently loaded
+ */
wait: function() {
this.$icon.removeClass();
this.$icon.addClass('fa fa-spinner fa-spin');
this.$select.hide();
},
- // disabled
+ /** Returns true if the field is disabled
+ */
disabled: function() {
return this.$select.is(':disabled');
},
- // enable
+ /** Enable the select field
+ */
enable: function() {
this.$select.prop('disabled', false);
},
- // disable
+ /** Disable the select field
+ */
disable: function() {
this.$select.prop('disabled', true);
},
- // add
+ /** Add a select option
+ */
add: function(options) {
// add options
this.$select.append(this._templateOption(options));
@@ -130,7 +155,8 @@
this._refresh();
},
- // remove
+ /** Delete a select option
+ */
del: function(value) {
// remove option
this.$select.find('option[value=' + value + ']').remove();
@@ -140,7 +166,8 @@
this._refresh();
},
- // render
+ /** Update select options
+ */
update: function(options) {
// backup current value
var current = this.$select.val();
@@ -165,24 +192,28 @@
}
},
- // set on change event
+ /** Set the custom onchange callback function
+ */
setOnChange: function(callback) {
this.options.onchange = callback;
},
- // check if selected value exists
+ /** Check if a value is an existing option
+ */
exists: function(value) {
return this.$select.find('option[value="' + value + '"]').length > 0;
},
- // change
+ /** Trigger custom onchange callback
+ */
_change: function() {
if (this.options.onchange) {
this.options.onchange(this.$select.val());
}
},
- // refresh
+ /** Refresh the select view
+ */
_refresh: function() {
// remove placeholder
this.$select.find('option[value=null]').remove();
@@ -201,12 +232,14 @@
}
},
- // template option
+ /** Template for select options
+ */
_templateOption: function(options) {
return '<option value="' + options.value + '">' + options.label + '</option>';
},
- // template
+ /** Template for select view
+ */
_template: function(options) {
return '<div id="' + options.id + '">' +
'<div class="button">' +
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c static/scripts/packed/mvc/tools/tools-form.js
--- a/static/scripts/packed/mvc/tools/tools-form.js
+++ b/static/scripts/packed/mvc/tools/tools-form.js
@@ -1,1 +1,1 @@
-define(["mvc/ui/ui-portlet","mvc/ui/ui-misc","mvc/citation/citation-model","mvc/citation/citation-view","mvc/tools","mvc/tools/tools-template","mvc/tools/tools-datasets","mvc/tools/tools-section","mvc/tools/tools-tree","mvc/tools/tools-jobs"],function(h,l,j,a,f,d,i,k,c,g){var e=Backbone.Model.extend({initialize:function(m){this.url=galaxy_config.root+"api/tools/"+m.id+"?io_details=true"}});var b=Backbone.View.extend({main_el:"body",initialize:function(n){var m=this;this.options=n;this.model=new e({id:n.id});this.tree=new c(this);this.job_handler=new g(this);this.field_list={};this.input_list={};this.element_list={};this.datasets=new i({history_id:this.options.history_id,success:function(){m._initializeToolForm()}})},message:function(m){$(this.main_el).empty();$(this.main_el).append(d.message(m))},reset:function(){for(var m in this.element_list){this.element_list[m].reset()}},refresh:function(){this.tree.refresh();for(var m in this.field_list){this.field_list[m].trigger("change")}console.debug("tools-form::refresh() - Recreated tree structure. Refresh.")},_initializeToolForm:function(){var n=this;var o=new l.ButtonIcon({icon:"fa-question-circle",title:"Question?",tooltip:"Ask a question about this tool (Biostar)",onclick:function(){window.open(n.options.biostar_url+"/p/new/post/")}});var p=new l.ButtonIcon({icon:"fa-search",title:"Search",tooltip:"Search help for this tool (Biostar)",onclick:function(){window.open(n.options.biostar_url+"/t/"+n.options.id+"/")}});var m=new l.ButtonIcon({icon:"fa-share",title:"Share",tooltip:"Share this tool",onclick:function(){prompt("Copy to clipboard: Ctrl+C, Enter",galaxy_config.root+"root?tool_id="+n.options.id)}});this.model.fetch({error:function(q){console.debug("tools-form::_initializeToolForm() : Attempt to fetch tool model failed.")},success:function(){n.inputs=n.model.get("inputs");n.portlet=new h.View({icon:"fa-wrench",title:"<b>"+n.model.get("name")+"</b> "+n.model.get("description"),buttons:{execute:new l.ButtonIcon({icon:"fa-check",tooltip:"Execute the tool",title:"Execute",floating:"clear",onclick:function(){n.job_handler.submit()}})},operations:{button_question:o,button_search:p,button_share:m}});if(!n.options.biostar_url){o.$el.hide();p.$el.hide()}$(n.main_el).append(n.portlet.$el);if(n.options.help!=""){$(n.main_el).append(d.help(n.options.help))}if(n.options.citations){$(n.main_el).append(d.citations());var q=new j.ToolCitationCollection();q.tool_id=n.options.id;var r=new a.CitationListView({collection:q});r.render();q.fetch()}n.setElement(n.portlet.content());n.section=new k.View(n,{inputs:n.model.get("inputs"),cls:"ui-table-plain"});n.portlet.append(n.section.$el);n.refresh();n.tree.finalize()}})}});return{View:b}});
\ No newline at end of file
+define(["mvc/ui/ui-portlet","mvc/ui/ui-misc","mvc/citation/citation-model","mvc/citation/citation-view","mvc/tools","mvc/tools/tools-template","mvc/tools/tools-datasets","mvc/tools/tools-section","mvc/tools/tools-tree","mvc/tools/tools-jobs"],function(h,l,j,a,f,d,i,k,c,g){var e=Backbone.Model.extend({initialize:function(m){this.url=galaxy_config.root+"api/tools/"+m.id+"?io_details=true"}});var b=Backbone.View.extend({main_el:"body",initialize:function(n){var m=this;this.options=n;this.model=new e({id:n.id});this.tree=new c(this);this.job_handler=new g(this);this.field_list={};this.input_list={};this.element_list={};this.datasets=new i({history_id:this.options.history_id,success:function(){m._initializeToolForm()}})},message:function(m){$(this.main_el).empty();$(this.main_el).append(d.message(m))},reset:function(){for(var m in this.element_list){this.element_list[m].reset()}},refresh:function(){this.tree.refresh();for(var m in this.field_list){this.field_list[m].trigger("change")}console.debug("tools-form::refresh() - Recreated tree structure. Refresh.")},_initializeToolForm:function(){var n=this;var o=new l.ButtonIcon({icon:"fa-question-circle",title:"Question?",tooltip:"Ask a question about this tool (Biostar)",onclick:function(){window.open(n.options.biostar_url+"/p/new/post/")}});var p=new l.ButtonIcon({icon:"fa-search",title:"Search",tooltip:"Search help for this tool (Biostar)",onclick:function(){window.open(n.options.biostar_url+"/t/"+n.options.id+"/")}});var m=new l.ButtonIcon({icon:"fa-share",title:"Share",tooltip:"Share this tool",onclick:function(){prompt("Copy to clipboard: Ctrl+C, Enter",galaxy_config.root+"root?tool_id="+n.options.id)}});this.model.fetch({error:function(q){console.debug("tools-form::_initializeToolForm() : Attempt to fetch tool model failed.")},success:function(){n.inputs=n.model.get("inputs");n.portlet=new h.View({icon:"fa-wrench",title:"<b>"+n.model.get("name")+"</b> "+n.model.get("description"),buttons:{execute:new l.ButtonIcon({icon:"fa-check",tooltip:"Execute the tool",title:"Execute",floating:"clear",onclick:function(){n.job_handler.submit()}})},operations:{button_question:o,button_search:p,button_share:m}});if(!n.options.biostar_url){o.$el.hide();p.$el.hide()}$(n.main_el).append(n.portlet.$el);if(n.options.help!=""){$(n.main_el).append(d.help(n.options.help))}if(n.options.citations){$(n.main_el).append(d.citations());var q=new j.ToolCitationCollection();q.tool_id=n.options.id;var r=new a.CitationListView({collection:q});r.render();q.fetch()}n.setElement(n.portlet.content());n.section=new k.View(n,{inputs:n.model.get("inputs"),cls:"ui-table-plain"});n.portlet.append(n.section.$el);n.refresh()}})}});return{View:b}});
\ No newline at end of file
diff -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 -r 5636e8ac71d5955501e333dc6fa4693cc5905c1c static/scripts/packed/mvc/tools/tools-jobs.js
--- a/static/scripts/packed/mvc/tools/tools-jobs.js
+++ b/static/scripts/packed/mvc/tools/tools-jobs.js
@@ -1,1 +1,1 @@
-define(["utils/utils"],function(a){return Backbone.Model.extend({initialize:function(c,b){this.app=c;this.options=a.merge(b,this.optionsDefault)},submit:function(){var b=this;var c={tool_id:this.app.options.id,inputs:this.app.tree.finalize()};this.app.reset();a.request("POST",galaxy_config.root+"api/tools",c,function(d){if(!d.outputs||d.outputs.length==0){console.debug(d)}b.app.message({text:"A job has been successfully added to the queue. You can check the status of queued jobs and view the resulting data by refreshing the History pane. When the job has been run the status will change from 'running' to 'finished' if completed successfully or 'error' if problems were encountered."});b._refreshHdas()},function(d){console.debug(d);if(d&&d.message&&d.message.data){var g=b.app.tree.match(d.message.data);for(var f in g){var e=g[f];if(!e){e="Please verify this parameter."}b.app.element_list[f].error(e)}}})},_refreshHdas:function(){if(parent.Galaxy&&parent.Galaxy.currHistoryPanel){parent.Galaxy.currHistoryPanel.refreshContents()}}})});
\ No newline at end of file
+define(["utils/utils"],function(a){return Backbone.Model.extend({initialize:function(c,b){this.app=c;this.options=a.merge(b,this.optionsDefault)},submit:function(){var b=this;var c={tool_id:this.app.options.id,inputs:this.app.tree.finalize()};this.app.reset();if(!this._validation(c)){console.debug("tools-jobs::submit - Submission canceled. Validation failed.");return}a.request("POST",galaxy_config.root+"api/tools",c,function(d){if(!d.outputs||d.outputs.length==0){console.debug(d)}b.app.message({text:"A job has been successfully added to the queue. You can check the status of queued jobs and view the resulting data by refreshing the History pane. When the job has been run the status will change from 'running' to 'finished' if completed successfully or 'error' if problems were encountered."});b._refreshHdas()},function(d){console.debug(d);if(d&&d.message&&d.message.data){var g=b.app.tree.matchResponse(d.message.data);for(var f in g){var e=g[f];if(!e){e="Please verify this parameter."}b.app.element_list[f].error(e)}}})},_validation:function(g){var d=g.inputs;var f=true;for(var h in d){var c=d[h];var e=this.app.tree.match(h);var b=this.app.field_list[e];this.app.element_list[e].error("Please verify this parameter.");f=false}return false},_refreshHdas:function(){if(parent.Galaxy&&parent.Galaxy.currHistoryPanel){parent.Galaxy.currHistoryPanel.refreshContents()}}})});
\ No newline at end of file
This diff is so big that we needed to truncate the remainder.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c0c00d69cae3/
Changeset: c0c00d69cae3
Branch: stable
User: martenson
Date: 2014-09-22 18:52:11+00:00
Summary: Fix of a bug involving mistaking ld with ldda and vice versa which (together with our incremental ID approach ) leads to an incorrect dataset being downloaded.
Affected #: 5 files
diff -r e9fab037f8b2d2fa916b517a79f14ab9188be43c -r c0c00d69cae3966a5c1e67abc3ba7aa67a735a64 lib/galaxy/webapps/galaxy/api/lda_datasets.py
--- a/lib/galaxy/webapps/galaxy/api/lda_datasets.py
+++ b/lib/galaxy/webapps/galaxy/api/lda_datasets.py
@@ -175,31 +175,30 @@
:param format: string representing requested archive format
:type format: string
- :param lddas[]: an array of encoded ids
- :type lddas[]: an array
+ :param ld_ids[]: an array of encoded ids
+ :type ld_ids[]: an array
:rtype: file
:returns: either archive with the requested datasets packed inside or a single uncompressed dataset
:raises: MessageException, ItemDeletionException, ItemAccessibilityException, HTTPBadRequest, OSError, IOError, ObjectNotFound
"""
- lddas = []
- datasets_to_download = kwd.get( 'ldda_ids%5B%5D', None )
+ library_datasets = []
+ datasets_to_download = kwd.get( 'ld_ids%5B%5D', None )
if datasets_to_download is None:
- datasets_to_download = kwd.get( 'ldda_ids', None )
-
+ datasets_to_download = kwd.get( 'ld_ids', None )
if ( datasets_to_download is not None ):
datasets_to_download = util.listify( datasets_to_download )
for dataset_id in datasets_to_download:
try:
- ldda = self.get_hda_or_ldda( trans, hda_ldda='ldda', dataset_id=dataset_id )
- lddas.append( ldda )
+ library_dataset = self.get_library_dataset( trans, id=dataset_id, check_ownership=False, check_accessible=True )
+ library_datasets.append( library_dataset )
except HTTPBadRequest, e:
- raise exceptions.RequestParameterInvalidException( 'Bad Request. ' + str( e.err_msg ) )
+ raise exceptions.RequestParameterInvalidException( 'Bad Request.' )
except HTTPInternalServerError, e:
- raise exceptions.InternalServerError( 'Internal error. ' + str( e.err_msg ) )
+ raise exceptions.InternalServerError( 'Internal error.' )
except Exception, e:
- raise exceptions.InternalServerError( 'Unknown error. ' + str( e ) )
+ raise exceptions.InternalServerError( 'Unknown error.' )
else:
raise exceptions.RequestParameterMissingException( 'Request has to contain a list of dataset ids to download.' )
@@ -237,7 +236,8 @@
raise exceptions.InternalServerError( "Unable to create archive for download." )
composite_extensions = trans.app.datatypes_registry.get_composite_extensions()
seen = []
- for ldda in lddas:
+ for ld in library_datasets:
+ ldda = ld.library_dataset_dataset_association
ext = ldda.extension
is_composite = ext in composite_extensions
path = ""
@@ -326,19 +326,21 @@
archive.wsgi_headeritems = trans.response.wsgi_headeritems()
return archive.stream
elif format == 'uncompressed':
- if len(lddas) != 1:
+ if len(library_datasets) != 1:
raise exceptions.RequestParameterInvalidException( "You can download only one uncompressed file at once." )
else:
- single_dataset = lddas[ 0 ]
- trans.response.set_content_type( single_dataset.get_mime() )
- fStat = os.stat( ldda.file_name )
+ single_ld = library_datasets[ 0 ]
+ ldda = single_ld.library_dataset_dataset_association
+ dataset = ldda.dataset
+ fStat = os.stat( dataset.file_name )
+ trans.response.set_content_type( ldda.get_mime() )
trans.response.headers[ 'Content-Length' ] = int( fStat.st_size )
valid_chars = '.,^_-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
fname = ldda.name
fname = ''.join( c in valid_chars and c or '_' for c in fname )[ 0:150 ]
trans.response.headers[ "Content-Disposition" ] = 'attachment; filename="%s"' % fname
try:
- return open( single_dataset.file_name )
+ return open( dataset.file_name )
except:
raise exceptions.InternalServerError( "This dataset contains no content." )
else:
diff -r e9fab037f8b2d2fa916b517a79f14ab9188be43c -r c0c00d69cae3966a5c1e67abc3ba7aa67a735a64 static/scripts/mvc/library/library-dataset-view.js
--- a/static/scripts/mvc/library/library-dataset-view.js
+++ b/static/scripts/mvc/library/library-dataset-view.js
@@ -80,7 +80,7 @@
downloadDataset: function(){
var url = '/api/libraries/datasets/download/uncompressed';
- var data = {'ldda_ids' : this.id};
+ var data = {'ld_ids' : this.id};
this.processDownload(url, data);
},
diff -r e9fab037f8b2d2fa916b517a79f14ab9188be43c -r c0c00d69cae3966a5c1e67abc3ba7aa67a735a64 static/scripts/mvc/library/library-foldertoolbar-view.js
--- a/static/scripts/mvc/library/library-foldertoolbar-view.js
+++ b/static/scripts/mvc/library/library-foldertoolbar-view.js
@@ -285,7 +285,7 @@
});
var url = '/api/libraries/datasets/download/' + format;
- var data = {'ldda_ids' : dataset_ids};
+ var data = {'ld_ids' : dataset_ids};
this.processDownload(url, data, 'get');
},
diff -r e9fab037f8b2d2fa916b517a79f14ab9188be43c -r c0c00d69cae3966a5c1e67abc3ba7aa67a735a64 static/scripts/packed/mvc/library/library-dataset-view.js
--- a/static/scripts/packed/mvc/library/library-dataset-view.js
+++ b/static/scripts/packed/mvc/library/library-dataset-view.js
@@ -1,1 +1,1 @@
-define(["libs/toastr","mvc/library/library-model","mvc/ui/ui-select"],function(d,c,b){var a=Backbone.View.extend({el:"#center",model:null,options:{},events:{"click .toolbtn_modify_dataset":"enableModification","click .toolbtn_cancel_modifications":"render","click .toolbtn-download-dataset":"downloadDataset","click .toolbtn-import-dataset":"importIntoHistory","click .toolbtn-share-dataset":"shareDataset","click .toolbtn_save_modifications":"comingSoon","click .btn-remove-restrictions":"comingSoon","click .btn-make-private":"comingSoon","click .btn-share-dataset":"comingSoon"},initialize:function(e){this.options=_.extend(this.options,e);if(this.options.id){this.fetchDataset()}},fetchDataset:function(e){this.options=_.extend(this.options,e);this.model=new c.Item({id:this.options.id});var f=this;this.model.fetch({success:function(){if(f.options.show_permissions){f.showPermissions()}else{f.render()}},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg+" Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}else{d.error("An error ocurred :(. Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}}})},render:function(e){$(".tooltip").remove();this.options=_.extend(this.options,e);var f=this.templateDataset();this.$el.html(f({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},enableModification:function(){$(".tooltip").remove();var e=this.templateModifyDataset();this.$el.html(e({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},downloadDataset:function(){var e="/api/libraries/datasets/download/uncompressed";var f={ldda_ids:this.id};this.processDownload(e,f)},processDownload:function(f,g,h){if(f&&g){g=typeof g=="string"?g:$.param(g);var e="";$.each(g.split("&"),function(){var i=this.split("=");e+='<input type="hidden" name="'+i[0]+'" value="'+i[1]+'" />'});$('<form action="'+f+'" method="'+(h||"post")+'">'+e+"</form>").appendTo("body").submit().remove();d.info("Your download will begin soon")}},importIntoHistory:function(){this.refreshUserHistoriesList(function(e){var f=e.templateBulkImportInModal();e.modal=Galaxy.modal;e.modal.show({closing_events:true,title:"Import into History",body:f({histories:e.histories.models}),buttons:{Import:function(){e.importCurrentIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})},refreshUserHistoriesList:function(f){var e=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(){f(e)},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg)}else{d.error("An error ocurred :(")}}})},importCurrentIntoHistory:function(){var f=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();var g=new c.HistoryItem();g.url=g.urlRoot+f+"/contents";var e="/api/histories/"+f+"/set_as_current";$.ajax({url:e,type:"PUT"});g.save({content:this.id,source:"library"},{success:function(){Galaxy.modal.hide();d.success("Dataset imported. Click this to start analysing it.","",{onclick:function(){window.location="/"}})},error:function(i,h){if(typeof h.responseJSON!=="undefined"){d.error("Dataset not imported. "+h.responseJSON.err_msg)}else{d.error("An error occured! Dataset not imported. Please try again.")}}})},shareDataset:function(){d.info("Feature coming soon.")},goBack:function(){Galaxy.libraries.library_router.back()},showPermissions:function(){$(".tooltip").remove();var f=this.templateDatasetPermissions();this.$el.html(f({item:this.model}));var g=false;if(Galaxy.currUser){g=Galaxy.currUser.isAdmin()}var e=this;$.get("/api/libraries/datasets/"+e.id+"/permissions/current").done(function(j){var k=[];for(var m=0;m<j.length;m++){k.push(j[m]+":"+j[m])}if(g){var h={minimumInputLength:1,css:"access_perm",multiple:true,placeholder:"Click to select a role",container:e.$el.find("#access_perm"),ajax:{url:"/api/libraries/datasets/"+e.id+"/permissions",dataType:"json",quietMillis:100,data:function(i,p){return{q:i,page_limit:10,page:p}},results:function(q,p){var i=(p*10)<q.total;return{results:q.roles,more:i}}},formatResult:function l(i){return i.name+" type: "+i.type},formatSelection:function o(i){return i.name},initSelection:function(i,q){var p=[];$(i.val().split(",")).each(function(){var r=this.split(":");p.push({id:r[1],name:r[1]})});q(p)},initialData:k.join(","),dropdownCssClass:"bigdrop"};this.accessSelectObject=new b.View(h)}else{var n=this.templateAccessSelect();$.get("/api/libraries/datasets/"+e.id+"/permissions",function(i){$(".access_perm").html(n({options:i.roles}));this.accessSelectObject=$("#access_select").select2()}).fail(function(){d.error("An error occurred while fetching data with permissions. :(")})}}).fail(function(){d.error("An error occurred while fetching data with permissions. :(")});$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},comingSoon:function(){d.warning("Feature coming soon")},templateDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Download dataset" class="btn btn-default toolbtn-download-dataset primary-button" type="button"><span class="fa fa-download"></span> Download</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Import dataset into history" class="btn btn-default toolbtn-import-dataset primary-button" type="button"><span class="fa fa-book"></span> to History</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Modify dataset" class="btn btn-default toolbtn_modify_dataset primary-button" type="button"><span class="fa fa-pencil"></span> Modify</span></button>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>/permissions"><button data-toggle="tooltip" data-placement="top" title="Change permissions" class="btn btn-default toolbtn_change_permissions primary-button" type="button"><span class="fa fa-group"></span> Permissions</span></button></a>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Share dataset" class="btn btn-default toolbtn-share-dataset primary-button" type="button"><span class="fa fa-share"></span> Share</span></button>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<div class="dataset_table">');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><%= _.escape(item.get("name")) %></td>');e.push(" </tr>");e.push(' <% if (item.get("data_type")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("data_type")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("genome_build")) { %>');e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("file_size")) { %>');e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("date_uploaded")) { %>');e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("uploaded_by")) { %>');e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_data_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_comment_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_columns")) { %>');e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_column_types")) { %>');e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("message")) { %>');e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_blurb")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_info")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(" </table>");e.push(" <div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push(" </div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateModifyDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Cancel modifications" class="btn btn-default toolbtn_cancel_modifications primary-button" type="button"><span class="fa fa-times"></span> Cancel</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_modifications primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<div class="dataset_table">');e.push('<p>For more editing options please import the dataset to history and use "Edit attributes" on it.</p>');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><input class="input_dataset_name form-control" type="text" placeholder="name" value="<%= _.escape(item.get("name")) %>"></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("data_type")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(' <tr scope="row">');e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <% if (item.get("metadata_comment_lines") === "") { %>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" <% } else { %>");e.push(' <td scope="row">unknown</td>');e.push(" <% } %>");e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" </table>");e.push("<div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push("</div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateDatasetPermissions:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <a href="#folders/<%- item.get("folder_id") %>"><button data-toggle="tooltip" data-placement="top" title="Go back to folder" class="btn btn-default primary-button" type="button"><span class="fa fa-folder-open-o"></span> go to Folder</span></button></a>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>"><button data-toggle="tooltip" data-placement="top" title="Go back to dataset" class="btn btn-default primary-button" type="button"><span class="fa fa-file-o"></span> see the Dataset</span></button><a>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<h1><%= _.escape(item.get("name")) %></h1>');e.push('<div class="alert alert-success">You have rights to change permissions on this dataset. That means you can control who can access it, who can modify it and also appoint others that can manage permissions on it.</div>');e.push('<div class="dataset_table">');e.push("<h2>Basic permissions</h2>");e.push("<p>You can remove all access restrictions on this dataset. ");e.push('<button data-toggle="tooltip" data-placement="top" title="Everybody will be able to see the dataset." class="btn btn-default btn-remove-restrictions primary-button" type="button"><span class="fa fa-globe"></span> Remove restrictions</span></button>');e.push("</p>");e.push("<p>You can make this dataset private to you. ");e.push('<button data-toggle="tooltip" data-placement="top" title="Only you will be able to see the dataset." class="btn btn-default btn-make-private primary-button" type="button"><span class="fa fa-key"></span> Make private</span></button>');e.push("</p>");e.push("<p>You can share this dataset with another Galaxy user. ");e.push('<button data-toggle="tooltip" data-placement="top" title="Only you and the other user will be able to see the dataset." class="btn btn-default btn-share-dataset primary-button" type="button"><span class="fa fa-share"></span> Share</span></button>');e.push("</p>");e.push("<h2>Advanced permissions</h2>");e.push("<p>You can assign any number of roles to any of the following three dataset permission types. However please read carefully the implications of such actions.</p>");e.push("<h3>Access Roles</h3>");e.push('<div class="alert alert-info">User has to have <strong>all these roles</strong> in order to see this dataset.</div>');e.push('<div id="access_perm" class="access_perm roles-selection"></div>');e.push('<button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_modifications primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push("<h3>Modify Roles</h3>");e.push('<div class="alert alert-info">Users with <strong>any</strong> of these roles can modify the information about this dataset.</div>');e.push('<div id="modify_perm" class="modify_perm"></div>');e.push("<h3>Manage Roles</h3>");e.push('<div class="alert alert-info">Users with <strong>any</strong> of these roles can change permissions of this dataset.</div>');e.push('<div id="manage_perm" class="manage_perm"></div>');e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateBulkImportInModal:function(){var e=[];e.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');e.push("Select history: ");e.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');e.push(" <% _.each(histories, function(history) { %>");e.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');e.push(" <% }); %>");e.push("</select>");e.push("</span>");return _.template(e.join(""))},templateAccessSelect:function(){var e=[];e.push('<select id="access_select" multiple>');e.push(" <% _.each(options, function(option) { %>");e.push(' <option value="<%- option.name %>"><%- option.name %></option>');e.push(" <% }); %>");e.push("</select>");return _.template(e.join(""))}});return{LibraryDatasetView:a}});
\ No newline at end of file
+define(["libs/toastr","mvc/library/library-model","mvc/ui/ui-select"],function(d,c,b){var a=Backbone.View.extend({el:"#center",model:null,options:{},events:{"click .toolbtn_modify_dataset":"enableModification","click .toolbtn_cancel_modifications":"render","click .toolbtn-download-dataset":"downloadDataset","click .toolbtn-import-dataset":"importIntoHistory","click .toolbtn-share-dataset":"shareDataset","click .toolbtn_save_modifications":"comingSoon","click .btn-remove-restrictions":"comingSoon","click .btn-make-private":"comingSoon","click .btn-share-dataset":"comingSoon"},initialize:function(e){this.options=_.extend(this.options,e);if(this.options.id){this.fetchDataset()}},fetchDataset:function(e){this.options=_.extend(this.options,e);this.model=new c.Item({id:this.options.id});var f=this;this.model.fetch({success:function(){if(f.options.show_permissions){f.showPermissions()}else{f.render()}},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg+" Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}else{d.error("An error ocurred :(. Click this to go back.","",{onclick:function(){Galaxy.libraries.library_router.back()}})}}})},render:function(e){$(".tooltip").remove();this.options=_.extend(this.options,e);var f=this.templateDataset();this.$el.html(f({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},enableModification:function(){$(".tooltip").remove();var e=this.templateModifyDataset();this.$el.html(e({item:this.model}));$(".peek").html(this.model.get("peek"));$("#center [data-toggle]").tooltip()},downloadDataset:function(){var e="/api/libraries/datasets/download/uncompressed";var f={ld_ids:this.id};this.processDownload(e,f)},processDownload:function(f,g,h){if(f&&g){g=typeof g=="string"?g:$.param(g);var e="";$.each(g.split("&"),function(){var i=this.split("=");e+='<input type="hidden" name="'+i[0]+'" value="'+i[1]+'" />'});$('<form action="'+f+'" method="'+(h||"post")+'">'+e+"</form>").appendTo("body").submit().remove();d.info("Your download will begin soon")}},importIntoHistory:function(){this.refreshUserHistoriesList(function(e){var f=e.templateBulkImportInModal();e.modal=Galaxy.modal;e.modal.show({closing_events:true,title:"Import into History",body:f({histories:e.histories.models}),buttons:{Import:function(){e.importCurrentIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})},refreshUserHistoriesList:function(f){var e=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(){f(e)},error:function(h,g){if(typeof g.responseJSON!=="undefined"){d.error(g.responseJSON.err_msg)}else{d.error("An error ocurred :(")}}})},importCurrentIntoHistory:function(){var f=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();var g=new c.HistoryItem();g.url=g.urlRoot+f+"/contents";var e="/api/histories/"+f+"/set_as_current";$.ajax({url:e,type:"PUT"});g.save({content:this.id,source:"library"},{success:function(){Galaxy.modal.hide();d.success("Dataset imported. Click this to start analysing it.","",{onclick:function(){window.location="/"}})},error:function(i,h){if(typeof h.responseJSON!=="undefined"){d.error("Dataset not imported. "+h.responseJSON.err_msg)}else{d.error("An error occured! Dataset not imported. Please try again.")}}})},shareDataset:function(){d.info("Feature coming soon.")},goBack:function(){Galaxy.libraries.library_router.back()},showPermissions:function(){$(".tooltip").remove();var f=this.templateDatasetPermissions();this.$el.html(f({item:this.model}));var g=false;if(Galaxy.currUser){g=Galaxy.currUser.isAdmin()}var e=this;$.get("/api/libraries/datasets/"+e.id+"/permissions/current").done(function(j){var k=[];for(var m=0;m<j.length;m++){k.push(j[m]+":"+j[m])}if(g){var h={minimumInputLength:1,css:"access_perm",multiple:true,placeholder:"Click to select a role",container:e.$el.find("#access_perm"),ajax:{url:"/api/libraries/datasets/"+e.id+"/permissions",dataType:"json",quietMillis:100,data:function(i,p){return{q:i,page_limit:10,page:p}},results:function(q,p){var i=(p*10)<q.total;return{results:q.roles,more:i}}},formatResult:function l(i){return i.name+" type: "+i.type},formatSelection:function o(i){return i.name},initSelection:function(i,q){var p=[];$(i.val().split(",")).each(function(){var r=this.split(":");p.push({id:r[1],name:r[1]})});q(p)},initialData:k.join(","),dropdownCssClass:"bigdrop"};this.accessSelectObject=new b.View(h)}else{var n=this.templateAccessSelect();$.get("/api/libraries/datasets/"+e.id+"/permissions",function(i){$(".access_perm").html(n({options:i.roles}));this.accessSelectObject=$("#access_select").select2()}).fail(function(){d.error("An error occurred while fetching data with permissions. :(")})}}).fail(function(){d.error("An error occurred while fetching data with permissions. :(")});$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},comingSoon:function(){d.warning("Feature coming soon")},templateDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Download dataset" class="btn btn-default toolbtn-download-dataset primary-button" type="button"><span class="fa fa-download"></span> Download</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Import dataset into history" class="btn btn-default toolbtn-import-dataset primary-button" type="button"><span class="fa fa-book"></span> to History</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Modify dataset" class="btn btn-default toolbtn_modify_dataset primary-button" type="button"><span class="fa fa-pencil"></span> Modify</span></button>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>/permissions"><button data-toggle="tooltip" data-placement="top" title="Change permissions" class="btn btn-default toolbtn_change_permissions primary-button" type="button"><span class="fa fa-group"></span> Permissions</span></button></a>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Share dataset" class="btn btn-default toolbtn-share-dataset primary-button" type="button"><span class="fa fa-share"></span> Share</span></button>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<div class="dataset_table">');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><%= _.escape(item.get("name")) %></td>');e.push(" </tr>");e.push(' <% if (item.get("data_type")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("data_type")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("genome_build")) { %>');e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("file_size")) { %>');e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("date_uploaded")) { %>');e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("uploaded_by")) { %>');e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_data_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_comment_lines")) { %>');e.push(" <tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_columns")) { %>');e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("metadata_column_types")) { %>');e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("message")) { %>');e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_blurb")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(' <% if (item.get("misc_info")) { %>');e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <% } %>");e.push(" </table>");e.push(" <div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push(" </div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateModifyDataset:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <button data-toggle="tooltip" data-placement="top" title="Cancel modifications" class="btn btn-default toolbtn_cancel_modifications primary-button" type="button"><span class="fa fa-times"></span> Cancel</span></button>');e.push(' <button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_modifications primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<div class="dataset_table">');e.push('<p>For more editing options please import the dataset to history and use "Edit attributes" on it.</p>');e.push(' <table class="grid table table-striped table-condensed">');e.push(" <tr>");e.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');e.push(' <td><input class="input_dataset_name form-control" type="text" placeholder="name" value="<%= _.escape(item.get("name")) %>"></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Data type</th>');e.push(' <td><%= _.escape(item.get("data_type")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Genome build</th>');e.push(' <td><%= _.escape(item.get("genome_build")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Size</th>');e.push(' <td><%= _.escape(item.get("file_size")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Date uploaded (UTC)</th>');e.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Uploaded by</th>');e.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');e.push(" </tr>");e.push(' <tr scope="row">');e.push(' <th scope="row">Data Lines</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');e.push(" </tr>");e.push(' <th scope="row">Comment Lines</th>');e.push(' <% if (item.get("metadata_comment_lines") === "") { %>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');e.push(" <% } else { %>");e.push(' <td scope="row">unknown</td>');e.push(" <% } %>");e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Number of Columns</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Column Types</th>');e.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Message</th>');e.push(' <td scope="row"><%= _.escape(item.get("message")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous information</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_info")) %></td>');e.push(" </tr>");e.push(" <tr>");e.push(' <th scope="row">Miscellaneous blurb</th>');e.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');e.push(" </tr>");e.push(" </table>");e.push("<div>");e.push(' <pre class="peek">');e.push(" </pre>");e.push("</div>");e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateDatasetPermissions:function(){var e=[];e.push('<div class="library_style_container">');e.push(' <div id="library_toolbar">');e.push(' <a href="#folders/<%- item.get("folder_id") %>"><button data-toggle="tooltip" data-placement="top" title="Go back to folder" class="btn btn-default primary-button" type="button"><span class="fa fa-folder-open-o"></span> go to Folder</span></button></a>');e.push(' <a href="#folders/<%- item.get("folder_id") %>/datasets/<%- item.id %>"><button data-toggle="tooltip" data-placement="top" title="Go back to dataset" class="btn btn-default primary-button" type="button"><span class="fa fa-file-o"></span> see the Dataset</span></button><a>');e.push(" </div>");e.push('<ol class="breadcrumb">');e.push(' <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');e.push(' <% _.each(item.get("full_path"), function(path_item) { %>');e.push(" <% if (path_item[0] != item.id) { %>");e.push(' <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');e.push("<% } else { %>");e.push(' <li class="active"><span title="You are here"><%- path_item[1] %></span></li>');e.push(" <% } %>");e.push(" <% }); %>");e.push("</ol>");e.push('<h1><%= _.escape(item.get("name")) %></h1>');e.push('<div class="alert alert-success">You have rights to change permissions on this dataset. That means you can control who can access it, who can modify it and also appoint others that can manage permissions on it.</div>');e.push('<div class="dataset_table">');e.push("<h2>Basic permissions</h2>");e.push("<p>You can remove all access restrictions on this dataset. ");e.push('<button data-toggle="tooltip" data-placement="top" title="Everybody will be able to see the dataset." class="btn btn-default btn-remove-restrictions primary-button" type="button"><span class="fa fa-globe"></span> Remove restrictions</span></button>');e.push("</p>");e.push("<p>You can make this dataset private to you. ");e.push('<button data-toggle="tooltip" data-placement="top" title="Only you will be able to see the dataset." class="btn btn-default btn-make-private primary-button" type="button"><span class="fa fa-key"></span> Make private</span></button>');e.push("</p>");e.push("<p>You can share this dataset with another Galaxy user. ");e.push('<button data-toggle="tooltip" data-placement="top" title="Only you and the other user will be able to see the dataset." class="btn btn-default btn-share-dataset primary-button" type="button"><span class="fa fa-share"></span> Share</span></button>');e.push("</p>");e.push("<h2>Advanced permissions</h2>");e.push("<p>You can assign any number of roles to any of the following three dataset permission types. However please read carefully the implications of such actions.</p>");e.push("<h3>Access Roles</h3>");e.push('<div class="alert alert-info">User has to have <strong>all these roles</strong> in order to see this dataset.</div>');e.push('<div id="access_perm" class="access_perm roles-selection"></div>');e.push('<button data-toggle="tooltip" data-placement="top" title="Save modifications" class="btn btn-default toolbtn_save_modifications primary-button" type="button"><span class="fa fa-floppy-o"></span> Save</span></button>');e.push("<h3>Modify Roles</h3>");e.push('<div class="alert alert-info">Users with <strong>any</strong> of these roles can modify the information about this dataset.</div>');e.push('<div id="modify_perm" class="modify_perm"></div>');e.push("<h3>Manage Roles</h3>");e.push('<div class="alert alert-info">Users with <strong>any</strong> of these roles can change permissions of this dataset.</div>');e.push('<div id="manage_perm" class="manage_perm"></div>');e.push("</div>");e.push("</div>");return _.template(e.join(""))},templateBulkImportInModal:function(){var e=[];e.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');e.push("Select history: ");e.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');e.push(" <% _.each(histories, function(history) { %>");e.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');e.push(" <% }); %>");e.push("</select>");e.push("</span>");return _.template(e.join(""))},templateAccessSelect:function(){var e=[];e.push('<select id="access_select" multiple>');e.push(" <% _.each(options, function(option) { %>");e.push(' <option value="<%- option.name %>"><%- option.name %></option>');e.push(" <% }); %>");e.push("</select>");return _.template(e.join(""))}});return{LibraryDatasetView:a}});
\ No newline at end of file
diff -r e9fab037f8b2d2fa916b517a79f14ab9188be43c -r c0c00d69cae3966a5c1e67abc3ba7aa67a735a64 static/scripts/packed/mvc/library/library-foldertoolbar-view.js
--- a/static/scripts/packed/mvc/library/library-foldertoolbar-view.js
+++ b/static/scripts/packed/mvc/library/library-foldertoolbar-view.js
@@ -1,1 +1,1 @@
-define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({el:"#center",events:{"click #toolbtn_create_folder":"createFolderFromModal","click #toolbtn_bulk_import":"modalBulkImport","click .toolbtn_add_files":"addFilesToFolderModal","click #include_deleted_datasets_chk":"checkIncludeDeleted","click #toolbtn_bulk_delete":"deleteSelectedDatasets"},defaults:{can_add_library_item:false,contains_file:false,chain_call_control:{total_number:0,failed_number:0}},modal:null,histories:null,initialize:function(f){this.options=_.defaults(f||{},this.defaults);this.render()},render:function(g){this.options=_.extend(this.options,g);var i=false;var f=true;if(Galaxy.currUser){i=Galaxy.currUser.isAdmin();f=Galaxy.currUser.isAnonymous()}var h=this.templateToolBar();this.$el.html(h({id:this.options.id,admin_user:i,anonym:f}))},configureElements:function(f){this.options=_.extend(this.options,f);if(this.options.can_add_library_item===true){$(".add-library-items").show()}else{$(".add-library-items").hide()}if(this.options.contains_file===true){if(Galaxy.currUser){if(!Galaxy.currUser.isAnonymous()){$(".logged-dataset-manipulation").show();$(".dataset-manipulation").show()}else{$(".dataset-manipulation").show();$(".logged-dataset-manipulation").hide()}}else{$(".logged-dataset-manipulation").hide();$(".dataset-manipulation").hide()}}else{$(".logged-dataset-manipulation").hide();$(".dataset-manipulation").hide()}this.$el.find("[data-toggle]").tooltip()},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var f=this;var g=this.templateNewFolderInModal();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:g(),buttons:{Create:function(){f.create_new_folder_event()},Close:function(){Galaxy.modal.hide()}}})},create_new_folder_event:function(){var f=this.serialize_new_folder();if(this.validate_new_folder(f)){var g=new c.FolderAsModel();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];g.url=g.urlRoot+"/"+current_folder_id;g.save(f,{success:function(h){Galaxy.modal.hide();e.success("Folder created");h.set({type:"folder"});Galaxy.libraries.folderListView.collection.add(h)},error:function(i,h){Galaxy.modal.hide();if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})}else{e.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(f){return f.name!==""},modalBulkImport:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{this.refreshUserHistoriesList(function(g){var h=g.templateBulkImportInModal();g.modal=Galaxy.modal;g.modal.show({closing_events:true,title:"Import into History",body:h({histories:g.histories.models}),buttons:{Import:function(){g.importAllIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})}},refreshUserHistoriesList:function(g){var f=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(){g(f)},error:function(i,h){if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})},importAllIntoHistory:function(){this.modal.disableButton("Import");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var k=$("select[name=dataset_import_bulk] option:selected").val();this.options.last_used_history_id=k;var n=$("select[name=dataset_import_bulk] option:selected").text();var p=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){p.push(this.parentElement.parentElement.id)}});var o=this.templateImportIntoHistoryProgressBar();this.modal.$el.find(".modal-body").html(o({history_name:n}));var l=100/p.length;this.initProgress(l);var f=[];for(var h=p.length-1;h>=0;h--){var j=p[h];var m=new c.HistoryItem();m.url=m.urlRoot+k+"/contents";m.content=j;m.source="library";f.push(m)}this.options.chain_call_control.total_number=f.length;var g="/api/histories/"+k+"/set_as_current";$.ajax({url:g,type:"PUT"});this.chainCall(f,n)},chainCall:function(g,j){var f=this;var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets imported into history. Click this to start analysing it.","",{onclick:function(){window.location="/"}})}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were imported into history.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be imported into history. Click this to see what was imported.","",{onclick:function(){window.location="/"}})}}}Galaxy.modal.hide();return}var i=$.when(h.save({content:h.content,source:h.source}));i.done(function(){f.updateProgress();f.chainCall(g,j)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCall(g,j)})},initProgress:function(f){this.progress=0;this.progressStep=f},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(f,j){var h=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){h.push(this.parentElement.parentElement.id)}});var g="/api/libraries/datasets/download/"+j;var i={ldda_ids:h};this.processDownload(g,i,"get")},processDownload:function(g,h,i){if(g&&h){h=typeof h==="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+='<input type="hidden" name="'+j[0]+'" value="'+j[1]+'" />'});$('<form action="'+g+'" method="'+(i||"post")+'">'+f+"</form>").appendTo("body").submit().remove();e.info("Your download will begin soon")}},addFilesToFolderModal:function(){this.refreshUserHistoriesList(function(f){f.modal=Galaxy.modal;var g=f.templateAddFilesInModal();f.modal.show({closing_events:true,title:"Add datasets from history to "+f.options.folder_name,body:g({histories:f.histories.models}),buttons:{Add:function(){f.addAllDatasetsFromHistory()},Close:function(){Galaxy.modal.hide()}}});if(f.histories.models.length>0){f.fetchAndDisplayHistoryContents(f.histories.models[0].id);$("#dataset_add_bulk").change(function(h){f.fetchAndDisplayHistoryContents(h.target.value)})}else{e.error("An error ocurred :(")}})},fetchAndDisplayHistoryContents:function(h){var g=new c.HistoryContents({id:h});var f=this;g.fetch({success:function(j){var i=f.templateHistoryContents();f.histories.get(h).set({contents:j});f.modal.$el.find("#selected_history_content").html(i({history_contents:j.models.reverse()}))},error:function(){e.error("An error ocurred :(")}})},addAllDatasetsFromHistory:function(){this.modal.disableButton("Add");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var f=[];this.modal.$el.find("#selected_history_content").find(":checked").each(function(){var i=$(this.parentElement).data("id");if(i){f.push(i)}});var l=this.options.folder_name;var k=this.templateAddingDatasetsProgressBar();this.modal.$el.find(".modal-body").html(k({folder_name:l}));this.progressStep=100/f.length;this.progress=0;var j=[];for(var h=f.length-1;h>=0;h--){history_dataset_id=f[h];var g=new c.Item();g.url="/api/folders/"+this.options.id+"/contents";g.set({from_hda_id:history_dataset_id});j.push(g)}this.options.chain_call_control.total_number=j.length;this.chainCallAddingHdas(j)},chainCallAddingHdas:function(g){var f=this;this.added_hdas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets from history added to the folder")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were added to the folder.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be added to the folder")}}}Galaxy.modal.hide();return this.added_hdas}var i=$.when(h.save({from_hda_id:h.get("from_hda_id")}));i.done(function(j){Galaxy.libraries.folderListView.collection.add(j);f.updateProgress();f.chainCallAddingHdas(g)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallAddingHdas(g)})},checkIncludeDeleted:function(f){if(f.target.checked){Galaxy.libraries.folderListView.fetchFolder({include_deleted:true})}else{Galaxy.libraries.folderListView.fetchFolder({include_deleted:false})}},deleteSelectedDatasets:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{var j=this.templateDeletingDatasetsProgressBar();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Deleting selected datasets",body:j({}),buttons:{Close:function(){Galaxy.modal.hide()}}});this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var g=[];f.each(function(){if(this.parentElement.parentElement.id!==""){g.push(this.parentElement.parentElement.id)}});this.progressStep=100/g.length;this.progress=0;var l=[];for(var h=g.length-1;h>=0;h--){var k=new c.Item({id:g[h]});l.push(k)}this.options.chain_call_control.total_number=g.length;this.chainCallDeletingHdas(l)}},chainCallDeletingHdas:function(g){var f=this;this.deleted_lddas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets deleted")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were deleted.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be deleted")}}}Galaxy.modal.hide();return this.deleted_lddas}var i=$.when(h.destroy());i.done(function(k){Galaxy.libraries.folderListView.collection.remove(h.id);f.updateProgress();if(Galaxy.libraries.folderListView.options.include_deleted){var j=new c.Item(k);Galaxy.libraries.folderListView.collection.add(j)}f.chainCallDeletingHdas(g)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallDeletingHdas(g)})},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push('<div id="library_toolbar">');tmpl_array.push('<span data-toggle="tooltip" data-placement="top" class="logged-dataset-manipulation" title="Include deleted datasets" style="display:none;"><input id="include_deleted_datasets_chk" style="margin: 0;" type="checkbox"> include deleted</input></span>');tmpl_array.push('<div class="btn-group add-library-items" style="display:none;">');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Create New Folder" id="toolbtn_create_folder" class="btn btn-default primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Add Datasets to Current Folder" id="toolbtn_add_files" class="btn btn-default toolbtn_add_files primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-file"></span></span></button>');tmpl_array.push("</div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button dataset-manipulation" style="margin-left: 0.5em; display:none;" type="button"><span class="fa fa-book"></span> to History</button>');tmpl_array.push(' <div id="toolbtn_dl" class="btn-group dataset-manipulation" style="margin-left: 0.5em; display:none; ">');tmpl_array.push(' <button title="Download selected datasets as archive" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');tmpl_array.push(' <span class="fa fa-download"></span> Download <span class="caret"></span>');tmpl_array.push(" </button>");tmpl_array.push(' <ul class="dropdown-menu" role="menu">');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');tmpl_array.push(" </ul>");tmpl_array.push(" </div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Mark selected datasets deleted" id="toolbtn_bulk_delete" class="primary-button logged-dataset-manipulation" style="margin-left: 0.5em; display:none; " type="button"><span class="fa fa-times"></span> Delete</button>');tmpl_array.push(" </div>");tmpl_array.push(' <div id="folder_items_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateBulkImportInModal:function(){var f=[];f.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');f.push("Select history: ");f.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</span>");return _.template(f.join(""))},templateImportIntoHistoryProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Adding selected datasets from history to library folder <b><%= _.escape(folder_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateDeletingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-delete" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddFilesInModal:function(){var f=[];f.push('<div id="add_files_modal">');f.push('<div id="history_modal_combo_bulk">');f.push("Select history: ");f.push('<select id="dataset_add_bulk" name="dataset_add_bulk" style="width:66%; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</div>");f.push('<div id="selected_history_content">');f.push("</div>");f.push("</div>");return _.template(f.join(""))},templateHistoryContents:function(){var f=[];f.push("Choose the datasets to import:");f.push("<ul>");f.push(" <% _.each(history_contents, function(history_item) { %>");f.push(' <li data-id="<%= _.escape(history_item.get("id")) %>">');f.push(' <input style="margin: 0;" type="checkbox"><%= _.escape(history_item.get("hid")) %>: <%= _.escape(history_item.get("name")) %>');f.push(" </li>");f.push(" <% }); %>");f.push("</ul>");return _.template(f.join(""))}});return{FolderToolbarView:a}});
\ No newline at end of file
+define(["galaxy.masthead","utils/utils","libs/toastr","mvc/library/library-model"],function(b,d,e,c){var a=Backbone.View.extend({el:"#center",events:{"click #toolbtn_create_folder":"createFolderFromModal","click #toolbtn_bulk_import":"modalBulkImport","click .toolbtn_add_files":"addFilesToFolderModal","click #include_deleted_datasets_chk":"checkIncludeDeleted","click #toolbtn_bulk_delete":"deleteSelectedDatasets"},defaults:{can_add_library_item:false,contains_file:false,chain_call_control:{total_number:0,failed_number:0}},modal:null,histories:null,initialize:function(f){this.options=_.defaults(f||{},this.defaults);this.render()},render:function(g){this.options=_.extend(this.options,g);var i=false;var f=true;if(Galaxy.currUser){i=Galaxy.currUser.isAdmin();f=Galaxy.currUser.isAnonymous()}var h=this.templateToolBar();this.$el.html(h({id:this.options.id,admin_user:i,anonym:f}))},configureElements:function(f){this.options=_.extend(this.options,f);if(this.options.can_add_library_item===true){$(".add-library-items").show()}else{$(".add-library-items").hide()}if(this.options.contains_file===true){if(Galaxy.currUser){if(!Galaxy.currUser.isAnonymous()){$(".logged-dataset-manipulation").show();$(".dataset-manipulation").show()}else{$(".dataset-manipulation").show();$(".logged-dataset-manipulation").hide()}}else{$(".logged-dataset-manipulation").hide();$(".dataset-manipulation").hide()}}else{$(".logged-dataset-manipulation").hide();$(".dataset-manipulation").hide()}this.$el.find("[data-toggle]").tooltip()},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var f=this;var g=this.templateNewFolderInModal();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:g(),buttons:{Create:function(){f.create_new_folder_event()},Close:function(){Galaxy.modal.hide()}}})},create_new_folder_event:function(){var f=this.serialize_new_folder();if(this.validate_new_folder(f)){var g=new c.FolderAsModel();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];g.url=g.urlRoot+"/"+current_folder_id;g.save(f,{success:function(h){Galaxy.modal.hide();e.success("Folder created");h.set({type:"folder"});Galaxy.libraries.folderListView.collection.add(h)},error:function(i,h){Galaxy.modal.hide();if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})}else{e.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(f){return f.name!==""},modalBulkImport:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{this.refreshUserHistoriesList(function(g){var h=g.templateBulkImportInModal();g.modal=Galaxy.modal;g.modal.show({closing_events:true,title:"Import into History",body:h({histories:g.histories.models}),buttons:{Import:function(){g.importAllIntoHistory()},Close:function(){Galaxy.modal.hide()}}})})}},refreshUserHistoriesList:function(g){var f=this;this.histories=new c.GalaxyHistories();this.histories.fetch({success:function(){g(f)},error:function(i,h){if(typeof h.responseJSON!=="undefined"){e.error(h.responseJSON.err_msg)}else{e.error("An error ocurred :(")}}})},importAllIntoHistory:function(){this.modal.disableButton("Import");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var k=$("select[name=dataset_import_bulk] option:selected").val();this.options.last_used_history_id=k;var n=$("select[name=dataset_import_bulk] option:selected").text();var p=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){p.push(this.parentElement.parentElement.id)}});var o=this.templateImportIntoHistoryProgressBar();this.modal.$el.find(".modal-body").html(o({history_name:n}));var l=100/p.length;this.initProgress(l);var f=[];for(var h=p.length-1;h>=0;h--){var j=p[h];var m=new c.HistoryItem();m.url=m.urlRoot+k+"/contents";m.content=j;m.source="library";f.push(m)}this.options.chain_call_control.total_number=f.length;var g="/api/histories/"+k+"/set_as_current";$.ajax({url:g,type:"PUT"});this.chainCall(f,n)},chainCall:function(g,j){var f=this;var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets imported into history. Click this to start analysing it.","",{onclick:function(){window.location="/"}})}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were imported into history.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be imported into history. Click this to see what was imported.","",{onclick:function(){window.location="/"}})}}}Galaxy.modal.hide();return}var i=$.when(h.save({content:h.content,source:h.source}));i.done(function(){f.updateProgress();f.chainCall(g,j)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCall(g,j)})},initProgress:function(f){this.progress=0;this.progressStep=f},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(f,j){var h=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!==""){h.push(this.parentElement.parentElement.id)}});var g="/api/libraries/datasets/download/"+j;var i={ld_ids:h};this.processDownload(g,i,"get")},processDownload:function(g,h,i){if(g&&h){h=typeof h==="string"?h:$.param(h);var f="";$.each(h.split("&"),function(){var j=this.split("=");f+='<input type="hidden" name="'+j[0]+'" value="'+j[1]+'" />'});$('<form action="'+g+'" method="'+(i||"post")+'">'+f+"</form>").appendTo("body").submit().remove();e.info("Your download will begin soon")}},addFilesToFolderModal:function(){this.refreshUserHistoriesList(function(f){f.modal=Galaxy.modal;var g=f.templateAddFilesInModal();f.modal.show({closing_events:true,title:"Add datasets from history to "+f.options.folder_name,body:g({histories:f.histories.models}),buttons:{Add:function(){f.addAllDatasetsFromHistory()},Close:function(){Galaxy.modal.hide()}}});if(f.histories.models.length>0){f.fetchAndDisplayHistoryContents(f.histories.models[0].id);$("#dataset_add_bulk").change(function(h){f.fetchAndDisplayHistoryContents(h.target.value)})}else{e.error("An error ocurred :(")}})},fetchAndDisplayHistoryContents:function(h){var g=new c.HistoryContents({id:h});var f=this;g.fetch({success:function(j){var i=f.templateHistoryContents();f.histories.get(h).set({contents:j});f.modal.$el.find("#selected_history_content").html(i({history_contents:j.models.reverse()}))},error:function(){e.error("An error ocurred :(")}})},addAllDatasetsFromHistory:function(){this.modal.disableButton("Add");this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var f=[];this.modal.$el.find("#selected_history_content").find(":checked").each(function(){var i=$(this.parentElement).data("id");if(i){f.push(i)}});var l=this.options.folder_name;var k=this.templateAddingDatasetsProgressBar();this.modal.$el.find(".modal-body").html(k({folder_name:l}));this.progressStep=100/f.length;this.progress=0;var j=[];for(var h=f.length-1;h>=0;h--){history_dataset_id=f[h];var g=new c.Item();g.url="/api/folders/"+this.options.id+"/contents";g.set({from_hda_id:history_dataset_id});j.push(g)}this.options.chain_call_control.total_number=j.length;this.chainCallAddingHdas(j)},chainCallAddingHdas:function(g){var f=this;this.added_hdas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets from history added to the folder")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were added to the folder.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be added to the folder")}}}Galaxy.modal.hide();return this.added_hdas}var i=$.when(h.save({from_hda_id:h.get("from_hda_id")}));i.done(function(j){Galaxy.libraries.folderListView.collection.add(j);f.updateProgress();f.chainCallAddingHdas(g)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallAddingHdas(g)})},checkIncludeDeleted:function(f){if(f.target.checked){Galaxy.libraries.folderListView.fetchFolder({include_deleted:true})}else{Galaxy.libraries.folderListView.fetchFolder({include_deleted:false})}},deleteSelectedDatasets:function(){var f=$("#folder_table").find(":checked");if(f.length===0){e.info("You have to select some datasets first")}else{var j=this.templateDeletingDatasetsProgressBar();this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Deleting selected datasets",body:j({}),buttons:{Close:function(){Galaxy.modal.hide()}}});this.options.chain_call_control.total_number=0;this.options.chain_call_control.failed_number=0;var g=[];f.each(function(){if(this.parentElement.parentElement.id!==""){g.push(this.parentElement.parentElement.id)}});this.progressStep=100/g.length;this.progress=0;var l=[];for(var h=g.length-1;h>=0;h--){var k=new c.Item({id:g[h]});l.push(k)}this.options.chain_call_control.total_number=g.length;this.chainCallDeletingHdas(l)}},chainCallDeletingHdas:function(g){var f=this;this.deleted_lddas=new c.Folder();var h=g.pop();if(typeof h==="undefined"){if(this.options.chain_call_control.failed_number===0){e.success("Selected datasets deleted")}else{if(this.options.chain_call_control.failed_number===this.options.chain_call_control.total_number){e.error("There was an error and no datasets were deleted.")}else{if(this.options.chain_call_control.failed_number<this.options.chain_call_control.total_number){e.warning("Some of the datasets could not be deleted")}}}Galaxy.modal.hide();return this.deleted_lddas}var i=$.when(h.destroy());i.done(function(k){Galaxy.libraries.folderListView.collection.remove(h.id);f.updateProgress();if(Galaxy.libraries.folderListView.options.include_deleted){var j=new c.Item(k);Galaxy.libraries.folderListView.collection.add(j)}f.chainCallDeletingHdas(g)}).fail(function(){f.options.chain_call_control.failed_number+=1;f.updateProgress();f.chainCallDeletingHdas(g)})},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div class="library_style_container">');tmpl_array.push('<div id="library_toolbar">');tmpl_array.push('<span data-toggle="tooltip" data-placement="top" class="logged-dataset-manipulation" title="Include deleted datasets" style="display:none;"><input id="include_deleted_datasets_chk" style="margin: 0;" type="checkbox"> include deleted</input></span>');tmpl_array.push('<div class="btn-group add-library-items" style="display:none;">');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Create New Folder" id="toolbtn_create_folder" class="btn btn-default primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder"></span></button>');tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Add Datasets to Current Folder" id="toolbtn_add_files" class="btn btn-default toolbtn_add_files primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-file"></span></span></button>');tmpl_array.push("</div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button dataset-manipulation" style="margin-left: 0.5em; display:none;" type="button"><span class="fa fa-book"></span> to History</button>');tmpl_array.push(' <div id="toolbtn_dl" class="btn-group dataset-manipulation" style="margin-left: 0.5em; display:none; ">');tmpl_array.push(' <button title="Download selected datasets as archive" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');tmpl_array.push(' <span class="fa fa-download"></span> Download <span class="caret"></span>');tmpl_array.push(" </button>");tmpl_array.push(' <ul class="dropdown-menu" role="menu">');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');tmpl_array.push(' <li id="download_archive"><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');tmpl_array.push(" </ul>");tmpl_array.push(" </div>");tmpl_array.push(' <button data-toggle="tooltip" data-placement="top" title="Mark selected datasets deleted" id="toolbtn_bulk_delete" class="primary-button logged-dataset-manipulation" style="margin-left: 0.5em; display:none; " type="button"><span class="fa fa-times"></span> Delete</button>');tmpl_array.push(" </div>");tmpl_array.push(' <div id="folder_items_element">');tmpl_array.push(" </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateBulkImportInModal:function(){var f=[];f.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');f.push("Select history: ");f.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</span>");return _.template(f.join(""))},templateImportIntoHistoryProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("Adding selected datasets from history to library folder <b><%= _.escape(folder_name) %></b>");f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateDeletingDatasetsProgressBar:function(){var f=[];f.push('<div class="import_text">');f.push("</div>");f.push('<div class="progress">');f.push(' <div class="progress-bar progress-bar-delete" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');f.push(' <span class="completion_span">0% Complete</span>');f.push(" </div>");f.push("</div>");f.push("");return _.template(f.join(""))},templateAddFilesInModal:function(){var f=[];f.push('<div id="add_files_modal">');f.push('<div id="history_modal_combo_bulk">');f.push("Select history: ");f.push('<select id="dataset_add_bulk" name="dataset_add_bulk" style="width:66%; "> ');f.push(" <% _.each(histories, function(history) { %>");f.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');f.push(" <% }); %>");f.push("</select>");f.push("</div>");f.push('<div id="selected_history_content">');f.push("</div>");f.push("</div>");return _.template(f.join(""))},templateHistoryContents:function(){var f=[];f.push("Choose the datasets to import:");f.push("<ul>");f.push(" <% _.each(history_contents, function(history_item) { %>");f.push(' <li data-id="<%= _.escape(history_item.get("id")) %>">');f.push(' <input style="margin: 0;" type="checkbox"><%= _.escape(history_item.get("hid")) %>: <%= _.escape(history_item.get("name")) %>');f.push(" </li>");f.push(" <% }); %>");f.push("</ul>");return _.template(f.join(""))}});return{FolderToolbarView:a}});
\ No newline at end of file
https://bitbucket.org/galaxy/galaxy-central/commits/9f15bf53a11b/
Changeset: 9f15bf53a11b
Branch: stable
User: martenson
Date: 2014-09-22 19:17:51+00:00
Summary: putting back the removed exception messages
Affected #: 1 file
diff -r c0c00d69cae3966a5c1e67abc3ba7aa67a735a64 -r 9f15bf53a11b8a91301381d836271a0ac3b23e71 lib/galaxy/webapps/galaxy/api/lda_datasets.py
--- a/lib/galaxy/webapps/galaxy/api/lda_datasets.py
+++ b/lib/galaxy/webapps/galaxy/api/lda_datasets.py
@@ -194,11 +194,11 @@
library_dataset = self.get_library_dataset( trans, id=dataset_id, check_ownership=False, check_accessible=True )
library_datasets.append( library_dataset )
except HTTPBadRequest, e:
- raise exceptions.RequestParameterInvalidException( 'Bad Request.' )
+ raise exceptions.RequestParameterInvalidException( 'Bad Request. ' + str( e ) )
except HTTPInternalServerError, e:
- raise exceptions.InternalServerError( 'Internal error.' )
+ raise exceptions.InternalServerError( 'Internal error. ' + str( e ) )
except Exception, e:
- raise exceptions.InternalServerError( 'Unknown error.' )
+ raise exceptions.InternalServerError( 'Unknown error. ' + str( e ) )
else:
raise exceptions.RequestParameterMissingException( 'Request has to contain a list of dataset ids to download.' )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
4 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/6ccbeeccc70b/
Changeset: 6ccbeeccc70b
Branch: srma_memory
User: lance_parsons
Date: 2014-09-04 20:12:51+00:00
Summary: SRMA tool requires at least 2048m memory and LENIENT validation stringency
Affected #: 1 file
diff -r 9b6cccb3af2d6b13a1a1da7def87dcc19172be88 -r 6ccbeeccc70bc8e2e489f621d13a64f494ae2518 tools/sr_mapping/srma_wrapper.py
--- a/tools/sr_mapping/srma_wrapper.py
+++ b/tools/sr_mapping/srma_wrapper.py
@@ -142,6 +142,8 @@
else:
range = options.range
srma_cmds = "OFFSET=%s MIN_MAPQ=%s MINIMUM_ALLELE_PROBABILITY=%s MINIMUM_ALLELE_COVERAGE=%s RANGES=%s RANGE=%s CORRECT_BASES=%s USE_SEQUENCE_QUALITIES=%s MAX_HEAP_SIZE=%s" % ( options.offset, options.minMappingQuality, options.minAlleleProbability, options.minAlleleCoverage, ranges, range, options.correctBases, options.useSequenceQualities, options.maxHeapSize )
+
+ srma_cmds = "%s VALIDATION_STRINGENCY=LENIENT" % srma_cmds
# perform alignments
buffsize = 1048576
@@ -155,7 +157,7 @@
#create a temp output name, ending in .bam due to required naming conventions? unkown if required
output_bam_filename = os.path.join( tmp_dir, "%s.bam" % os.path.split( options.output )[-1] )
# generate commandline
- cmd = 'java -jar %s I=%s O=%s R=%s %s' % ( os.path.join( options.jarBin, options.jarFile ), input_bam_filename, output_bam_filename, reference_filepath_name, srma_cmds )
+ cmd = 'java -Xmx2048m -jar %s I=%s O=%s R=%s %s' % ( os.path.join( options.jarBin, options.jarFile ), input_bam_filename, output_bam_filename, reference_filepath_name, srma_cmds )
# need to nest try-except in try-finally to handle 2.4
try:
https://bitbucket.org/galaxy/galaxy-central/commits/bb4faa5a3b19/
Changeset: bb4faa5a3b19
User: jmchilton
Date: 2014-09-22 17:17:11+00:00
Summary: Merge pull request #489.
Thanks Lance!
Affected #: 1 file
diff -r 579d211c2b0fa8ef4195930cb999edbb9a0cf8eb -r bb4faa5a3b1957b2ea220a94ee2315e22354a3cf tools/sr_mapping/srma_wrapper.py
--- a/tools/sr_mapping/srma_wrapper.py
+++ b/tools/sr_mapping/srma_wrapper.py
@@ -142,6 +142,8 @@
else:
range = options.range
srma_cmds = "OFFSET=%s MIN_MAPQ=%s MINIMUM_ALLELE_PROBABILITY=%s MINIMUM_ALLELE_COVERAGE=%s RANGES=%s RANGE=%s CORRECT_BASES=%s USE_SEQUENCE_QUALITIES=%s MAX_HEAP_SIZE=%s" % ( options.offset, options.minMappingQuality, options.minAlleleProbability, options.minAlleleCoverage, ranges, range, options.correctBases, options.useSequenceQualities, options.maxHeapSize )
+
+ srma_cmds = "%s VALIDATION_STRINGENCY=LENIENT" % srma_cmds
# perform alignments
buffsize = 1048576
@@ -155,7 +157,7 @@
#create a temp output name, ending in .bam due to required naming conventions? unkown if required
output_bam_filename = os.path.join( tmp_dir, "%s.bam" % os.path.split( options.output )[-1] )
# generate commandline
- cmd = 'java -jar %s I=%s O=%s R=%s %s' % ( os.path.join( options.jarBin, options.jarFile ), input_bam_filename, output_bam_filename, reference_filepath_name, srma_cmds )
+ cmd = 'java -Xmx2048m -jar %s I=%s O=%s R=%s %s' % ( os.path.join( options.jarBin, options.jarFile ), input_bam_filename, output_bam_filename, reference_filepath_name, srma_cmds )
# need to nest try-except in try-finally to handle 2.4
try:
https://bitbucket.org/galaxy/galaxy-central/commits/35f770b6bed8/
Changeset: 35f770b6bed8
Branch: srma_memory
User: jmchilton
Date: 2014-09-22 17:18:07+00:00
Summary: Close branch.
Affected #: 0 files
https://bitbucket.org/galaxy/galaxy-central/commits/f9e429b15b0e/
Changeset: f9e429b15b0e
User: jmchilton
Date: 2014-09-22 17:20:49+00:00
Summary: Rework pull request #489 memory handling to respect deployer set _JAVA_OPTIONS.
As discussed here https://bitbucket.org/galaxy/galaxy-central/pull-request/489/srma-tool-requ…. Thanks to Bjoern for input.
Affected #: 1 file
diff -r bb4faa5a3b1957b2ea220a94ee2315e22354a3cf -r f9e429b15b0eacada3a248d14e9b9dcc9be67ed5 tools/sr_mapping/srma_wrapper.py
--- a/tools/sr_mapping/srma_wrapper.py
+++ b/tools/sr_mapping/srma_wrapper.py
@@ -157,8 +157,10 @@
#create a temp output name, ending in .bam due to required naming conventions? unkown if required
output_bam_filename = os.path.join( tmp_dir, "%s.bam" % os.path.split( options.output )[-1] )
# generate commandline
- cmd = 'java -Xmx2048m -jar %s I=%s O=%s R=%s %s' % ( os.path.join( options.jarBin, options.jarFile ), input_bam_filename, output_bam_filename, reference_filepath_name, srma_cmds )
-
+ java_opts = ''
+ if '_JAVA_OPTIONS' not in os.environ:
+ java_opts = '-Xmx2048m'
+ cmd = 'java %s -jar %s I=%s O=%s R=%s %s' % ( java_opts, os.path.join( options.jarBin, options.jarFile ), input_bam_filename, output_bam_filename, reference_filepath_name, srma_cmds )
# need to nest try-except in try-finally to handle 2.4
try:
try:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
[galaxyproject/usegalaxy-playbook] d47c88: Update Test/Main pulsar vars for galaxy role v0.3.
by GitHub 22 Sep '14
by GitHub 22 Sep '14
22 Sep '14
Branch: refs/heads/master
Home: https://github.com/galaxyproject/usegalaxy-playbook
Commit: d47c88c310550e10930c6fc229e68bbae5d5743f
https://github.com/galaxyproject/usegalaxy-playbook/commit/d47c88c310550e10…
Author: Nate Coraor <nate(a)bx.psu.edu>
Date: 2014-09-22 (Mon, 22 Sep 2014)
Changed paths:
M production/group_vars/pulsarservers.yml
M stage/group_vars/pulsarservers.yml
Log Message:
-----------
Update Test/Main pulsar vars for galaxy role v0.3.
1
0
[galaxyproject/usegalaxy-playbook] d7c6b6: Update Main and vars for galaxy role v0.3.
by GitHub 22 Sep '14
by GitHub 22 Sep '14
22 Sep '14
Branch: refs/heads/master
Home: https://github.com/galaxyproject/usegalaxy-playbook
Commit: d7c6b61f0a3c8da83aee108eb8e68007c6282fd9
https://github.com/galaxyproject/usegalaxy-playbook/commit/d7c6b61f0a3c8da8…
Author: Nate Coraor <nate(a)bx.psu.edu>
Date: 2014-09-22 (Mon, 22 Sep 2014)
Changed paths:
M production/group_vars/all.yml
M production/group_vars/galaxyservers.yml
M templates/galaxy/usegalaxy.org/config/job_conf.xml.j2
Log Message:
-----------
Update Main and vars for galaxy role v0.3.
1
0
[galaxyproject/usegalaxy-playbook] b38416: Update Test vars for galaxy role v0.3.
by GitHub 22 Sep '14
by GitHub 22 Sep '14
22 Sep '14
Branch: refs/heads/master
Home: https://github.com/galaxyproject/usegalaxy-playbook
Commit: b3841642aee7ae8811777f4a3c7e304c78ca9a3d
https://github.com/galaxyproject/usegalaxy-playbook/commit/b3841642aee7ae88…
Author: Nate Coraor <nate(a)bx.psu.edu>
Date: 2014-09-22 (Mon, 22 Sep 2014)
Changed paths:
M stage/group_vars/galaxyservers.yml
Log Message:
-----------
Update Test vars for galaxy role v0.3.
1
0
Branch: refs/heads/master
Home: https://github.com/galaxyproject/usegalaxy-playbook
Commit: f8c99417741bb7680bdd026a5080b2ff6507310a
https://github.com/galaxyproject/usegalaxy-playbook/commit/f8c99417741bb768…
Author: Nate Coraor <nate(a)bx.psu.edu>
Date: 2014-09-22 (Mon, 22 Sep 2014)
Changed paths:
M stage/group_vars/all.yml
Log Message:
-----------
Update Test.
Commit: 63715c21513810a4d3ea353614e3fc2130c35170
https://github.com/galaxyproject/usegalaxy-playbook/commit/63715c21513810a4…
Author: Nate Coraor <nate(a)bx.psu.edu>
Date: 2014-09-22 (Mon, 22 Sep 2014)
Changed paths:
M roles/galaxyprojectdotorg.galaxy/README.md
M roles/galaxyprojectdotorg.galaxy/defaults/main.yml
M roles/galaxyprojectdotorg.galaxy/meta/.galaxy_install_info
M roles/galaxyprojectdotorg.galaxy/meta/main.yml
M roles/galaxyprojectdotorg.galaxy/tasks/eggs.yml
M roles/galaxyprojectdotorg.galaxy/tasks/static_setup.yml
Log Message:
-----------
Update galaxyprojectdotorg.galaxy to v0.3.
Compare: https://github.com/galaxyproject/usegalaxy-playbook/compare/d2e65c460baf...…
1
0
Branch: refs/tags/0.3
Home: https://github.com/galaxyproject/ansible-galaxy
1
0
[galaxyproject/ansible-galaxy] aa1a0e: Update defaults for config sample move in 14.10 Ga...
by GitHub 22 Sep '14
by GitHub 22 Sep '14
22 Sep '14
Branch: refs/heads/master
Home: https://github.com/galaxyproject/ansible-galaxy
Commit: aa1a0e0e0b87a1b276a30993e7d7cbfa63e518db
https://github.com/galaxyproject/ansible-galaxy/commit/aa1a0e0e0b87a1b276a3…
Author: Nate Coraor <nate(a)bx.psu.edu>
Date: 2014-09-22 (Mon, 22 Sep 2014)
Changed paths:
M defaults/main.yml
Log Message:
-----------
Update defaults for config sample move in 14.10 Galaxy release.
1
0
3 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/be1142c63cb3/
Changeset: be1142c63cb3
Branch: next-stable
User: natefoo
Date: 2014-09-22 14:49:37+00:00
Summary: Open next-stable branch for 2014.10 release.
Affected #: 946 files
diff -r f2a70e7bac29aa06b47a499a28af1bc7ee61c70f -r be1142c63cb38346b8c13d24367c931b6c75243a .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -8,7 +8,7 @@
5e605ed6069fe4c5ca9875e95e91b2713499e8ca release_2014.02.10
9e53251b0b7e93b9563008a2b112f2e815a04bbc release_2014.04.14
7e257c7b10badb65772b1528cb61d58175a42e47 release_2014.06.02
-8c30e91bc9ae19ee4dc7ec2c22fa825979497108 latest_2014.06.02
+7a4d321c0e38fa263ea83d29a35a608c3181fcba latest_2014.06.02
9661b9d5d5b330483ae3ad2236410e0efaa7c500 latest_2014.04.14
6b0bd93038a843b1585155f0d63f0eea2459c70b latest_2013.01.13
3e62060b14b9afc46f8e0ec02e1a4500d77db9e1 latest_2013.02.08
@@ -17,3 +17,5 @@
9ed84cd208e07e8985ec917cb025fcbbb09edcfb latest_2013.08.12
81fbe25bd02edcd53065e8e4476dd1dfb5a72cf2 latest_2013.11.04
2a756ca2cb1826db7796018e77d12e2dd7b67603 latest_2014.02.10
+ca45b78adb4152fc6e7395514d46eba6b7d0b838 release_2014.08.11
+21f2a42a06d7d2b8c408aed22c691f5e8b209311 latest_2014.08.11
diff -r f2a70e7bac29aa06b47a499a28af1bc7ee61c70f -r be1142c63cb38346b8c13d24367c931b6c75243a README.txt
--- a/README.txt
+++ b/README.txt
@@ -1,31 +1,34 @@
-GALAXY
-======
-http://galaxyproject.org/
-
-The latest information about Galaxy is always available via the Galaxy
-website above.
-
-HOW TO START
-============
-Galaxy requires Python 2.6 or 2.7. To check your python version, run:
-
-% python -V
-Python 2.7.3
-
-Start Galaxy:
-
-% sh run.sh
-
-Once Galaxy completes startup, you should be able to view Galaxy in your
-browser at:
-
-http://localhost:8080
-
-You may wish to make changes from the default configuration. This can be done
-in the universe_wsgi.ini file. Tools are configured in tool_conf.xml. Details
-on adding tools can be found on the Galaxy website (linked above).
-
-Not all dependencies are included for the tools provided in the sample
-tool_conf.xml. A full list of external dependencies is available at:
-
-https://wiki.galaxyproject.org/Admin/Tools/ToolDependencies
+GALAXY
+======
+http://galaxyproject.org/
+
+The latest information about Galaxy is always available via the Galaxy
+website above.
+
+HOW TO START
+============
+Galaxy requires Python 2.6 or 2.7. To check your python version, run:
+
+% python -V
+Python 2.7.3
+
+Start Galaxy:
+
+% sh run.sh
+
+Once Galaxy completes startup, you should be able to view Galaxy in your
+browser at:
+
+http://localhost:8080
+
+You may wish to make changes from the default configuration. This can be done
+in the config/galaxy.ini file. Tools can be either installed from the Tool Shed
+or added manually. For details please see the Galaxy wiki:
+
+https://wiki.galaxyproject.org/Admin/Tools/AddToolFromToolShedTutorial
+
+
+Not all dependencies are included for the tools provided in the sample
+tool_conf.xml. A full list of external dependencies is available at:
+
+https://wiki.galaxyproject.org/Admin/Tools/ToolDependencies
diff -r f2a70e7bac29aa06b47a499a28af1bc7ee61c70f -r be1142c63cb38346b8c13d24367c931b6c75243a buildbot_setup.sh
--- a/buildbot_setup.sh
+++ b/buildbot_setup.sh
@@ -43,21 +43,13 @@
"
SAMPLES="
-tool_conf.xml.sample
-datatypes_conf.xml.sample
-universe_wsgi.ini.sample
-tool_data_table_conf.xml.sample
-tool_sheds_conf.xml.sample
-shed_tool_data_table_conf.xml.sample
-migrated_tools_conf.xml.sample
-data_manager_conf.xml.sample
-shed_data_manager_conf.xml.sample
-tool-data/shared/ensembl/builds.txt.sample
+config/galaxy.ini.sample
+config/shed_tool_data_table_conf.xml.sample
+config/migrated_tools_conf.xml.sample
+config/shed_data_manager_conf.xml.sample
tool-data/shared/igv/igv_build_sites.txt.sample
-tool-data/shared/ncbi/builds.txt.sample
tool-data/shared/rviewer/rviewer_build_sites.txt.sample
tool-data/shared/ucsc/builds.txt.sample
-tool-data/shared/ucsc/publicbuilds.txt.sample
tool-data/shared/ucsc/ucsc_build_sites.txt.sample
"
@@ -115,7 +107,7 @@
done
echo "Copying job_conf.xml.sample_basic to job_conf.xml"
-cp job_conf.xml.sample_basic job_conf.xml
+cp config/job_conf.xml.sample_basic config/job_conf.xml
for dir in $DIRS; do
if [ ! -d $dir ]; then
diff -r f2a70e7bac29aa06b47a499a28af1bc7ee61c70f -r be1142c63cb38346b8c13d24367c931b6c75243a client/GruntFile.js
--- /dev/null
+++ b/client/GruntFile.js
@@ -0,0 +1,88 @@
+module.exports = function(grunt) {
+
+ // Project configuration.
+ grunt.initConfig({
+ pkg: grunt.file.readJSON( 'package.json' ),
+
+ // default task
+ // use 'grunt copy' to copy the entire <galaxy>/client/galaxy/scripts dir into <galaxy>/static/scripts
+ copy: {
+ main: {
+ files: [
+ {
+ expand : true,
+ cwd : 'galaxy/scripts/',
+ src : '**',
+ dest : '../static/scripts'
+ }
+ ]
+ }
+ },
+
+ // use 'grunt pack' to call pack_scripts.py to pack all or selected files in static/scripts
+ exec: {
+ packScripts: {
+ cwd: '../static/scripts',
+ target: [],
+ cmd: function(){
+ var targets = grunt.config( 'exec.packScripts.target' );
+ // if nothing was passed in pack all scripts
+ if( !targets.length ){
+ return './pack_scripts.py';
+ }
+
+ grunt.log.write( 'packing: ' + targets + '\n' );
+ return targets.map( function( target ){
+ return './pack_scripts.py ' + target;
+ }).join( '; ' );
+ }
+ }
+ },
+
+ // use 'grunt watch' (from a new tab in your terminal) to have grunt re-copy changed files automatically
+ watch: {
+ // watch for changes in the src dir
+ files: [ 'galaxy/scripts/**' ],
+ tasks: [ 'copy', 'pack' ],
+ options: {
+ spawn: false
+ }
+ }
+ });
+
+ grunt.loadNpmTasks( 'grunt-contrib-watch' );
+ grunt.loadNpmTasks( 'grunt-contrib-copy');
+ grunt.loadNpmTasks('grunt-exec');
+
+ grunt.registerTask( 'pack', [ 'exec' ] );
+ grunt.registerTask( 'default', [ 'copy', 'pack' ] );
+
+ // -------------------------------------------------------------------------- copy,pack only those changed
+ // adapted from grunt-contrib-watch jslint example
+ //TODO: a bit hacky and there's prob. a better way
+ //NOTE: copy will fail silently if a file isn't found
+
+ // outer scope variable for the event handler and onChange fn - begin with empty hash
+ var changedFiles = Object.create(null);
+
+ // when files are changed, set the copy src and packScripts target to the filenames of the updated files
+ var onChange = grunt.util._.debounce(function() {
+ grunt.config( 'copy.main.files', [{
+ expand: true,
+ cwd: 'galaxy/scripts',
+ src: Object.keys( changedFiles ),
+ dest: '../static/scripts/'
+ }]);
+ grunt.config( 'exec.packScripts.target', Object.keys( changedFiles ) );
+ changedFiles = Object.create(null);
+ }, 200);
+
+ grunt.event.on('watch', function(action, filepath) {
+ // store each filepath in a Files obj, the debounced fn above will use it as an aggregate list for copying
+ // we need to take galaxy/scripts out of the filepath or it will be copied to the wrong loc
+ filepath = filepath.replace( /galaxy\/scripts\//, '' );
+ changedFiles[filepath] = action;
+ onChange();
+ });
+
+};
diff -r f2a70e7bac29aa06b47a499a28af1bc7ee61c70f -r be1142c63cb38346b8c13d24367c931b6c75243a client/README.txt
--- /dev/null
+++ b/client/README.txt
@@ -0,0 +1,42 @@
+Client Build System
+===================
+
+Builds and moves the client-side scripts necessary for running the Galaxy webapps. There's no need to use this system
+unless you are modifying or developing client-side scripts.
+
+You'll need Node and the Node Package Manager (npm): nodejs.org.
+
+Once npm is installed, install the grunt task manager and it's command line into your global scope:
+
+ npm install -g grunt grunt-cli
+
+Next, from within this directory, install the local build dependencies:
+
+ cd client
+ npm install
+
+You're now ready to re-build the client scripts after modifying them.
+
+
+Rebuilding
+==========
+
+There are two methods for rebuilding: a complete rebuild and automatic, partial rebuilds while you develop.
+
+A complete rebuild can be done with the following (from the `client` directory):
+
+ grunt
+
+This will copy any files in `client/galaxy/scripts` to `static/scripts` and run `static/scripts/pack_scripts.py` on all.
+
+Grunt can also do an automatic, partial rebuild of any files you change *as you develop* by:
+
+ 1. opening a new terminal session
+ 2. `cd client`
+ 3. `grunt watch`
+
+This starts a new grunt watch process that will monitor the files in `client/galaxy/scripts` for changes and copy and
+pack them when they change.
+
+You can stop the `grunt watch` task by pressing `Ctrl+C`. Note: you should also be able to background that task if you
+prefer.
diff -r f2a70e7bac29aa06b47a499a28af1bc7ee61c70f -r be1142c63cb38346b8c13d24367c931b6c75243a client/galaxy/scripts/base.js
--- /dev/null
+++ b/client/galaxy/scripts/base.js
@@ -0,0 +1,15 @@
+define( ["libs/backbone/backbone"], function( Backbone ) {
+
+ var Base = function() {
+ if( this.initialize ) {
+ this.initialize.apply(this, arguments);
+ }
+ };
+ Base.extend = Backbone.Model.extend;
+
+ return {
+ Base: Base,
+ Backbone: Backbone
+ };
+
+});
\ No newline at end of file
diff -r f2a70e7bac29aa06b47a499a28af1bc7ee61c70f -r be1142c63cb38346b8c13d24367c931b6c75243a client/galaxy/scripts/galaxy-app-base.js
--- /dev/null
+++ b/client/galaxy/scripts/galaxy-app-base.js
@@ -0,0 +1,160 @@
+define([
+ 'mvc/user/user-model',
+ 'utils/metrics-logger',
+ 'utils/add-logging',
+ 'utils/localization',
+ 'bootstrapped-data'
+], function( userModel, metricsLogger, addLogging, localize, bootstrapped ){
+// ============================================================================
+/** Base galaxy client-side application.
+ * Iniitializes:
+ * logger : the logger/metrics-logger
+ * localize : the string localizer
+ * config : the current configuration (any k/v in
+ * galaxy.ini available from the configuration API)
+ * user : the current user (as a mvc/user/user-model)
+ */
+function GalaxyApp( options ){
+ var self = this;
+ return self._init( options || {} );
+}
+
+// add logging shortcuts for this object
+addLogging( GalaxyApp, 'GalaxyApp' );
+
+/** default options */
+GalaxyApp.prototype.defaultOptions = {
+ /** monkey patch attributes from existing window.Galaxy object? */
+ patchExisting : true,
+ /** root url of this app */
+ // move to self.root?
+ root : '/'
+};
+
+/** initalize options and sub-components */
+GalaxyApp.prototype._init = function init( options ){
+ var self = this;
+ _.extend( self, Backbone.Events );
+
+ self._processOptions( options );
+ self.debug( 'GalaxyApp.options: ', self.options );
+
+ self._patchGalaxy( window.Galaxy );
+
+ self._initLogger( options.loggerOptions || {} );
+ self.debug( 'GalaxyApp.logger: ', self.logger );
+
+ self._initLocale();
+ self.debug( 'GalaxyApp.localize: ', self.localize );
+
+ self.config = options.config || bootstrapped.config || {};
+ self.debug( 'GalaxyApp.config: ', self.config );
+
+ self._initUser( options.user || bootstrapped.user || {} );
+ self.debug( 'GalaxyApp.user: ', self.user );
+
+ //TODO: temp
+ self.trigger( 'ready', self );
+ //if( typeof options.onload === 'function' ){
+ // options.onload();
+ //}
+
+ self._setUpListeners();
+
+ return self;
+};
+
+/** add an option from options if the key matches an option in defaultOptions */
+GalaxyApp.prototype._processOptions = function _processOptions( options ){
+ var self = this,
+ defaults = self.defaultOptions;
+ self.debug( '_processOptions: ', options );
+
+ self.options = {};
+ for( var k in defaults ){
+ if( defaults.hasOwnProperty( k ) ){
+ self.options[ k ] = ( options.hasOwnProperty( k ) )?( options[ k ] ):( defaults[ k ] );
+ }
+ }
+ return self;
+};
+
+/** add an option from options if the key matches an option in defaultOptions */
+GalaxyApp.prototype._patchGalaxy = function _processOptions( patchWith ){
+ var self = this;
+ // in case req or plain script tag order has created a prev. version of the Galaxy obj...
+ if( self.options.patchExisting && patchWith ){
+ self.debug( 'found existing Galaxy object:', patchWith );
+ // ...(for now) monkey patch any added attributes that the previous Galaxy may have had
+ //TODO: move those attributes to more formal assignment in GalaxyApp
+ for( var k in patchWith ){
+ if( patchWith.hasOwnProperty( k ) ){
+ self.debug( '\t patching in ' + k + ' to Galaxy' );
+ self[ k ] = patchWith[ k ];
+ }
+ }
+ }
+};
+
+/** set up the metrics logger (utils/metrics-logger) and pass loggerOptions */
+GalaxyApp.prototype._initLogger = function _initLogger( loggerOptions ){
+ var self = this;
+ self.debug( '_initLogger:', loggerOptions );
+ self.logger = new metricsLogger.MetricsLogger( loggerOptions );
+ return self;
+};
+
+/** add the localize fn to this object and the window namespace (as '_l') */
+GalaxyApp.prototype._initLocale = function _initLocale( options ){
+ var self = this;
+ self.debug( '_initLocale:', options );
+ self.localize = localize;
+ // add to window as global shortened alias
+ window._l = self.localize;
+ return self;
+};
+
+/** set up the current user as a Backbone model (mvc/user/user-model) */
+GalaxyApp.prototype._initUser = function _initUser( userJSON ){
+ var self = this;
+ self.debug( '_initUser:', userJSON );
+ self.user = new userModel.User( userJSON );
+ //TODO: temp - old alias
+ self.currUser = self.user;
+ return self;
+};
+
+/** Set up DOM/jQuery/Backbone event listeners enabled for all pages */
+GalaxyApp.prototype._setUpListeners = function _setUpListeners(){
+ var self = this;
+
+ // hook to jq beforeSend to record the most recent ajax call and cache some data about it
+ /** cached info about the last ajax call made through jQuery */
+ self.lastAjax = {};
+ $( document ).bind( 'ajaxSend', function( ev, xhr, options ){
+ var data = options.data;
+ try {
+ data = JSON.parse( data );
+ } catch( err ){}
+
+ self.lastAjax = {
+ url : location.href.slice( 0, -1 ) + options.url,
+ data : data
+ };
+ //TODO:?? we might somehow manage to *retry* ajax using either this hook or Backbone.sync
+ });
+
+};
+
+/** string rep */
+GalaxyApp.prototype.toString = function toString(){
+ var userEmail = this.user.get( 'email' ) || '(anonymous)';
+ return 'GalaxyApp(' + userEmail + ')';
+};
+
+
+// ============================================================================
+ return {
+ GalaxyApp : GalaxyApp
+ };
+});
diff -r f2a70e7bac29aa06b47a499a28af1bc7ee61c70f -r be1142c63cb38346b8c13d24367c931b6c75243a client/galaxy/scripts/galaxy.autocom_tagging.js
--- /dev/null
+++ b/client/galaxy/scripts/galaxy.autocom_tagging.js
@@ -0,0 +1,368 @@
+/**
+* JQuery extension for tagging with autocomplete.
+* @author: Jeremy Goecks
+* @require: jquery.autocomplete plugin
+*/
+//
+// Initialize "tag click functions" for tags.
+//
+function init_tag_click_function(tag_elt, click_func) {
+ $(tag_elt).find('.tag-name').each( function() {
+ $(this).click( function() {
+ var tag_str = $(this).text();
+ var tag_name_and_value = tag_str.split(":");
+ click_func(tag_name_and_value[0], tag_name_and_value[1]);
+ return true;
+ });
+ });
+}
+
+jQuery.fn.autocomplete_tagging = function(options) {
+
+ var defaults = {
+ get_toggle_link_text_fn: function(tags) {
+ var text = "";
+ var num_tags = obj_length(tags);
+ if (num_tags > 0) {
+ text = num_tags + (num_tags > 1 ? " Tags" : " Tag");
+ } else {
+ text = "Add tags";
+ }
+ return text;
+ },
+ tag_click_fn : function (name, value) {},
+ editable: true,
+ input_size: 20,
+ in_form: false,
+ tags : {},
+ use_toggle_link: true,
+ item_id: "",
+ add_tag_img: "",
+ add_tag_img_rollover: "",
+ delete_tag_img: "",
+ ajax_autocomplete_tag_url: "",
+ ajax_retag_url: "",
+ ajax_delete_tag_url: "",
+ ajax_add_tag_url: ""
+ };
+
+ var settings = jQuery.extend(defaults, options);
+
+ //
+ // Initalize object's elements.
+ //
+
+ // Get elements for this object. For this_obj, assume the last element with the id is the "this"; this is somewhat of a hack to address the problem
+ // that there may be two tagging elements for a single item if there are both community and individual tags for an element.
+ var this_obj = $(this);
+ var tag_area = this_obj.find('.tag-area');
+ var toggle_link = this_obj.find('.toggle-link');
+ var tag_input_field = this_obj.find('.tag-input');
+ var add_tag_button = this_obj.find('.add-tag-button');
+
+ // Initialize toggle link.
+ toggle_link.click( function() {
+ // Take special actions depending on whether toggle is showing or hiding link.
+ var after_toggle_fn;
+ if (tag_area.is(":hidden")) {
+ after_toggle_fn = function() {
+ // If there are no tags, go right to editing mode by generating a click on the area.
+ var num_tags = $(this).find('.tag-button').length;
+ if (num_tags === 0) {
+ tag_area.click();
+ }
+ };
+ } else {
+ after_toggle_fn = function() {
+ tag_area.blur();
+ };
+ }
+ tag_area.slideToggle("fast", after_toggle_fn);
+ return $(this);
+ });
+
+ // Initialize tag input field.
+ if (settings.editable) {
+ tag_input_field.hide();
+ }
+ tag_input_field.keyup( function(e) {
+ if ( e.keyCode === 27 ) {
+ // Escape key
+ $(this).trigger( "blur" );
+ } else if (
+ ( e.keyCode === 13 ) || // Return Key
+ ( e.keyCode === 188 ) || // Comma
+ ( e.keyCode === 32 ) // Space
+ ) {
+ //
+ // Check input.
+ //
+
+ var new_value = this.value;
+
+ // Suppress space after a ":"
+ if ( new_value.indexOf(": ", new_value.length - 2) !== -1) {
+ this.value = new_value.substring(0, new_value.length-1);
+ return false;
+ }
+
+ // Remove trigger keys from input.
+ if ( (e.keyCode === 188) || (e.keyCode === 32) ) {
+ new_value = new_value.substring( 0 , new_value.length - 1 );
+ }
+
+ // Trim whitespace.
+ new_value = $.trim(new_value);
+
+ // Too short?
+ if (new_value.length < 2) {
+ return false;
+ }
+
+ //
+ // New tag OK - apply it.
+ //
+
+ this.value = ""; // Reset text field now that tag is being added
+
+ // Add button for tag after all other tag buttons.
+ var new_tag_button = build_tag_button(new_value);
+ var tag_buttons = tag_area.children(".tag-button");
+ if (tag_buttons.length !== 0) {
+ var last_tag_button = tag_buttons.slice(tag_buttons.length-1);
+ last_tag_button.after(new_tag_button);
+ } else {
+ tag_area.prepend(new_tag_button);
+ }
+
+ // Add tag to internal list.
+ var tag_name_and_value = new_value.split(":");
+ settings.tags[tag_name_and_value[0]] = tag_name_and_value[1];
+
+ // Update toggle link text.
+ var new_text = settings.get_toggle_link_text_fn(settings.tags);
+ toggle_link.text(new_text);
+
+ // Commit tag to server.
+ var zz = $(this);
+ $.ajax({
+ url: settings.ajax_add_tag_url,
+ data: { new_tag: new_value },
+ error: function() {
+ // Failed. Roll back changes and show alert.
+ new_tag_button.remove();
+ delete settings.tags[tag_name_and_value[0]];
+ var new_text = settings.get_toggle_link_text_fn(settings.tags);
+ toggle_link.text(new_text);
+ alert( "Add tag failed" );
+ },
+ success: function() {
+ // Flush autocomplete cache because it's not out of date.
+ // TODO: in the future, we could remove the particular item
+ // that was chosen from the cache rather than flush it.
+ zz.data('autocompleter').cacheFlush();
+ }
+ });
+
+ return false;
+ }
+ });
+
+ // Add autocomplete to input.
+ var format_item_func = function(key, row_position, num_rows, value, search_term) {
+ var tag_name_and_value = value.split(":");
+ return (tag_name_and_value.length === 1 ? tag_name_and_value[0] : tag_name_and_value[1]);
+ };
+ var autocomplete_options = { selectFirst: false, formatItem: format_item_func,
+ autoFill: false, highlight: false };
+ tag_input_field.autocomplete(settings.ajax_autocomplete_tag_url, autocomplete_options);
+
+
+ // Initialize delete tag images for current tags.
+ this_obj.find('.delete-tag-img').each(function() {
+ init_delete_tag_image( $(this) );
+ });
+
+
+ // Initialize tag click function.
+ init_tag_click_function($(this), settings.tag_click_fn);
+
+ // Initialize "add tag" button.
+ add_tag_button.click( function() {
+ $(this).hide();
+
+ // Clicking on button is the same as clicking on the tag area.
+ tag_area.click();
+ return false;
+ });
+
+ //
+ // Set up tag area interactions; these are needed only if tags are editable.
+ //
+ if (settings.editable) {
+ // When the tag area blurs, go to "view tag" mode.
+ tag_area.bind("blur", function(e) {
+ if (obj_length(settings.tags) > 0) {
+ add_tag_button.show();
+ tag_input_field.hide();
+ tag_area.removeClass("active-tag-area");
+ // tag_area.addClass("tooltip");
+ } else {
+ // No tags, so do nothing to ensure that input is still visible.
+ }
+ });
+
+ // On click, enable user to add tags.
+ tag_area.click( function(e) {
+ var is_active = $(this).hasClass("active-tag-area");
+
+ // If a "delete image" object was pressed and area is inactive, do nothing.
+ if ($(e.target).hasClass("delete-tag-img") && !is_active) {
+ return false;
+ }
+
+ // If a "tag name" object was pressed and area is inactive, do nothing.
+ if ($(e.target).hasClass("tag-name") && !is_active) {
+ return false;
+ }
+
+ // Remove tooltip.
+ // $(this).removeClass("tooltip");
+
+ // Hide add tag button, show tag_input field. Change background to show
+ // area is active.
+ $(this).addClass("active-tag-area");
+ add_tag_button.hide();
+ tag_input_field.show();
+ tag_input_field.focus();
+
+ // Add handler to document that will call blur when the tag area is blurred;
+ // a tag area is blurred when a user clicks on an element outside the area.
+ var handle_document_click = function(e) {
+ var check_click = function(tag_area, target) {
+ var tag_area_id = tag_area.attr("id");
+ // Blur the tag area if the element clicked on is not in the tag area.
+ if (target !== tag_area) {
+ tag_area.blur();
+ $(window).unbind("click.tagging_blur");
+ $(this).addClass("tooltip");
+ }
+ };
+ check_click(tag_area, $(e.target));
+ };
+ // TODO: we should attach the click handler to all frames in order to capture
+ // clicks outside the frame that this element is in.
+ //window.parent.document.onclick = handle_document_click;
+ //var temp = $(window.parent.document.body).contents().find("iframe").html();
+ //alert(temp);
+ //$(document).parent().click(handle_document_click);
+ $(window).bind("click.tagging_blur", handle_document_click);
+
+ return false;
+ });
+ }
+
+ // If using toggle link, hide the tag area. Otherwise, show the tag area.
+ if (settings.use_toggle_link) {
+ tag_area.hide();
+ }
+
+ //
+ // Helper functions.
+ //
+
+ //
+ // Collapse tag name + value into a single string.
+ //
+ function build_tag_str(tag_name, tag_value) {
+ return tag_name + ( tag_value ? ":" + tag_value : "");
+ }
+
+
+ // Initialize a "delete tag image": when click, delete tag from UI and send delete request to server.
+ function init_delete_tag_image(delete_img) {
+ $(delete_img).mouseenter( function () {
+ $(this).attr("src", settings.delete_tag_img_rollover);
+ });
+ $(delete_img).mouseleave( function () {
+ $(this).attr("src", settings.delete_tag_img);
+ });
+ $(delete_img).click( function () {
+ // Tag button is image's parent.
+ var tag_button = $(this).parent();
+
+ // Get tag name, value.
+ var tag_name_elt = tag_button.find(".tag-name").eq(0);
+ var tag_str = tag_name_elt.text();
+ var tag_name_and_value = tag_str.split(":");
+ var tag_name = tag_name_and_value[0];
+ var tag_value = tag_name_and_value[1];
+
+ var prev_button = tag_button.prev();
+ tag_button.remove();
+
+ // Remove tag from local list for consistency.
+ delete settings.tags[tag_name];
+
+ // Update toggle link text.
+ var new_text = settings.get_toggle_link_text_fn(settings.tags);
+ toggle_link.text(new_text);
+
+ // Delete tag.
+ $.ajax({
+ url: settings.ajax_delete_tag_url,
+ data: { tag_name: tag_name },
+ error: function() {
+ // Failed. Roll back changes and show alert.
+ settings.tags[tag_name] = tag_value;
+ if (prev_button.hasClass("tag-button")) {
+ prev_button.after(tag_button);
+ } else {
+ tag_area.prepend(tag_button);
+ }
+ alert( "Remove tag failed" );
+
+ toggle_link.text(settings.get_toggle_link_text_fn(settings.tags));
+
+ // TODO: no idea why it's necessary to set this up again.
+ delete_img.mouseenter( function () {
+ $(this).attr("src", settings.delete_tag_img_rollover);
+ });
+ delete_img.mouseleave( function () {
+ $(this).attr("src", settings.delete_tag_img);
+ });
+ },
+ success: function() {}
+ });
+
+ return true;
+ });
+ }
+
+ //
+ // Function that builds a tag button.
+ //
+ function build_tag_button(tag_str) {
+ // Build "delete tag" image.
+ var delete_img = $("<img/>").attr("src", settings.delete_tag_img).addClass("delete-tag-img");
+ init_delete_tag_image(delete_img);
+
+ // Build tag button.
+ var tag_name_elt = $("<span>").text(tag_str).addClass("tag-name");
+ tag_name_elt.click( function() {
+ var tag_name_and_value = tag_str.split(":");
+ settings.tag_click_fn(tag_name_and_value[0], tag_name_and_value[1]);
+ return true;
+ });
+
+ var tag_button = $("<span></span>").addClass("tag-button");
+ tag_button.append(tag_name_elt);
+ // Allow delete only if element is editable.
+ if (settings.editable) {
+ tag_button.append(delete_img);
+ }
+
+ return tag_button;
+ }
+
+};
diff -r f2a70e7bac29aa06b47a499a28af1bc7ee61c70f -r be1142c63cb38346b8c13d24367c931b6c75243a client/galaxy/scripts/galaxy.base.js
--- /dev/null
+++ b/client/galaxy/scripts/galaxy.base.js
@@ -0,0 +1,657 @@
+// requestAnimationFrame polyfill
+(function() {
+ var lastTime = 0;
+ var vendors = ['ms', 'moz', 'webkit', 'o'];
+ for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
+ window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
+ window.cancelRequestAnimationFrame = window[vendors[x]+
+ 'CancelRequestAnimationFrame'];
+ }
+
+ if (!window.requestAnimationFrame)
+ window.requestAnimationFrame = function(callback, element) {
+ var currTime = new Date().getTime();
+ var timeToCall = Math.max(0, 16 - (currTime - lastTime));
+ var id = window.setTimeout(function() { callback(currTime + timeToCall); },
+ timeToCall);
+ lastTime = currTime + timeToCall;
+ return id;
+ };
+
+ if (!window.cancelAnimationFrame)
+ window.cancelAnimationFrame = function(id) {
+ clearTimeout(id);
+ };
+}());
+
+// IE doesn't implement Array.indexOf
+if (!Array.indexOf) {
+ Array.prototype.indexOf = function(obj) {
+ for (var i = 0, len = this.length; i < len; i++) {
+ if (this[i] == obj) {
+ return i;
+ }
+ }
+ return -1;
+ };
+}
+
+// Returns the number of keys (elements) in an array/dictionary.
+function obj_length(obj) {
+ if (obj.length !== undefined) {
+ return obj.length;
+ }
+
+ var count = 0;
+ for (var element in obj) {
+ count++;
+ }
+ return count;
+}
+
+$.fn.makeAbsolute = function(rebase) {
+ return this.each(function() {
+ var el = $(this);
+ var pos = el.position();
+ el.css({
+ position: "absolute",
+ marginLeft: 0, marginTop: 0,
+ top: pos.top, left: pos.left,
+ right: $(window).width() - ( pos.left + el.width() )
+ });
+ if (rebase) {
+ el.remove().appendTo("body");
+ }
+ });
+};
+
+/**
+ * Sets up popupmenu rendering and binds options functions to the appropriate links.
+ * initial_options is a dict with text describing the option pointing to either (a) a
+ * function to perform; or (b) another dict with two required keys, 'url' and 'action' (the
+ * function to perform. (b) is useful for exposing the underlying URL of the option.
+ */
+function make_popupmenu(button_element, initial_options) {
+ /* Use the $.data feature to store options with the link element.
+ This allows options to be changed at a later time
+ */
+ var element_menu_exists = (button_element.data("menu_options"));
+ button_element.data("menu_options", initial_options);
+
+ // If element already has menu, nothing else to do since HTML and actions are already set.
+ if (element_menu_exists) { return; }
+
+ button_element.bind("click.show_popup", function(e) {
+ // Close existing visible menus
+ $(".popmenu-wrapper").remove();
+
+ // Need setTimeouts so clicks don't interfere with each other
+ setTimeout( function() {
+ // Dynamically generate the wrapper holding all the selectable options of the menu.
+ var menu_element = $( "<ul class='dropdown-menu' id='" + button_element.attr('id') + "-menu'></ul>" );
+ var options = button_element.data("menu_options");
+ if (obj_length(options) <= 0) {
+ $("<li>No Options.</li>").appendTo(menu_element);
+ }
+ $.each( options, function( k, v ) {
+ if (v) {
+ // Action can be either an anonymous function and a mapped dict.
+ var action = v.action || v;
+ menu_element.append( $("<li></li>").append( $("<a>").attr("href", v.url).html(k).click(action) ) );
+ } else {
+ menu_element.append( $("<li></li>").addClass( "head" ).append( $("<a href='#'></a>").html(k) ) );
+ }
+ });
+ var wrapper = $( "<div class='popmenu-wrapper' style='position: absolute;left: 0; top: -1000;'></div>" )
+ .append( menu_element ).appendTo( "body" );
+
+ var x = e.pageX - wrapper.width() / 2 ;
+ x = Math.min( x, $(document).scrollLeft() + $(window).width() - $(wrapper).width() - 5 );
+ x = Math.max( x, $(document).scrollLeft() + 5 );
+
+ wrapper.css({
+ top: e.pageY,
+ left: x
+ });
+ }, 10);
+
+ setTimeout( function() {
+ // Bind click event to current window and all frames to remove any visible menus
+ // Bind to document object instead of window object for IE compat
+ var close_popup = function(el) {
+ $(el).bind("click.close_popup", function() {
+ $(".popmenu-wrapper").remove();
+ el.unbind("click.close_popup");
+ });
+ };
+ close_popup( $(window.document) ); // Current frame
+ close_popup( $(window.top.document) ); // Parent frame
+ for (var frame_id = window.top.frames.length; frame_id--;) { // Sibling frames
+ var frame = $(window.top.frames[frame_id].document);
+ close_popup(frame);
+ }
+ }, 50);
+
+ return false;
+ });
+
+}
+
+/**
+ * Convert two seperate (often adjacent) divs into galaxy popupmenu
+ * - div 1 contains a number of anchors which become the menu options
+ * - div 1 should have a 'popupmenu' attribute
+ * - this popupmenu attribute contains the id of div 2
+ * - div 2 becomes the 'face' of the popupmenu
+ *
+ * NOTE: make_popup_menus finds and operates on all divs with a popupmenu attr (no need to point it at something)
+ * but (since that selector searches the dom on the page), you can send a parent in
+ * NOTE: make_popup_menus, and make_popupmenu are horrible names
+ */
+function make_popup_menus( parent ) {
+ // find all popupmenu menu divs (divs that contains anchors to be converted to menu options)
+ // either in the parent or the document if no parent passed
+ parent = parent || document;
+ $( parent ).find( "div[popupmenu]" ).each( function() {
+ var options = {};
+ var menu = $(this);
+
+ // find each anchor in the menu, convert them into an options map: { a.text : click_function }
+ menu.find( "a" ).each( function() {
+ var link = $(this),
+ link_dom = link.get(0),
+ confirmtext = link_dom.getAttribute( "confirm" ),
+ href = link_dom.getAttribute( "href" ),
+ target = link_dom.getAttribute( "target" );
+
+ // no href - no function (gen. a label)
+ if (!href) {
+ options[ link.text() ] = null;
+
+ } else {
+ options[ link.text() ] = {
+ url: href,
+ action: function() {
+
+ // if theres confirm text, send the dialog
+ if ( !confirmtext || confirm( confirmtext ) ) {
+ // link.click() doesn't use target for some reason,
+ // so manually do it here.
+ if (target) {
+ window.open(href, target);
+ return false;
+ }
+ // For all other links, do the default action.
+ else {
+ link.click();
+ }
+ }
+ }
+ };
+ }
+ });
+ // locate the element with the id corresponding to the menu's popupmenu attr
+ var box = $( parent ).find( "#" + menu.attr( 'popupmenu' ) );
+
+ // For menus with clickable link text, make clicking on the link go through instead
+ // of activating the popup menu
+ box.find("a").bind("click", function(e) {
+ e.stopPropagation(); // Stop bubbling so clicking on the link goes through
+ return true;
+ });
+
+ // attach the click events and menu box building to the box element
+ make_popupmenu(box, options);
+ box.addClass("popup");
+ menu.remove();
+ });
+}
+
+// Alphanumeric/natural sort fn
+function naturalSort(a, b) {
+ // setup temp-scope variables for comparison evauluation
+ var re = /(-?[0-9\.]+)/g,
+ x = a.toString().toLowerCase() || '',
+ y = b.toString().toLowerCase() || '',
+ nC = String.fromCharCode(0),
+ xN = x.replace( re, nC + '$1' + nC ).split(nC),
+ yN = y.replace( re, nC + '$1' + nC ).split(nC),
+ xD = (new Date(x)).getTime(),
+ yD = xD ? (new Date(y)).getTime() : null;
+ // natural sorting of dates
+ if ( yD ) {
+ if ( xD < yD ) { return -1; }
+ else if ( xD > yD ) { return 1; }
+ }
+ // natural sorting through split numeric strings and default strings
+ var oFxNcL, oFyNcL;
+ for ( var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++ ) {
+ oFxNcL = parseFloat(xN[cLoc]) || xN[cLoc];
+ oFyNcL = parseFloat(yN[cLoc]) || yN[cLoc];
+ if (oFxNcL < oFyNcL) { return -1; }
+ else if (oFxNcL > oFyNcL) { return 1; }
+ }
+ return 0;
+}
+
+$.fn.refresh_select2 = function() {
+ var select_elt = $(this);
+ var options = { width: "resolve",
+ closeOnSelect: !select_elt.is("[MULTIPLE]"),
+ dropdownAutoWidth : true
+ };
+ return select_elt.select2( options );
+}
+
+// Replace select box with a text input box + autocomplete.
+function replace_big_select_inputs(min_length, max_length, select_elts) {
+ // To do replace, the select2 plugin must be loaded.
+
+ if (!jQuery.fn.select2) {
+ return;
+ }
+
+ // Set default for min_length and max_length
+ if (min_length === undefined) {
+ min_length = 20;
+ }
+ if (max_length === undefined) {
+ max_length = 3000;
+ }
+
+ select_elts = select_elts || $('select');
+
+ select_elts.each( function() {
+ var select_elt = $(this).not('[multiple]');
+ // Make sure that options is within range.
+ var num_options = select_elt.find('option').length;
+ if ( (num_options < min_length) || (num_options > max_length) ) {
+ return;
+ }
+
+ if (select_elt.hasClass("no-autocomplete")) {
+ return;
+ }
+
+ /* Replaced jQuery.autocomplete with select2, notes:
+ * - multiple selects are supported
+ * - the original element is updated with the value, convert_to_values should not be needed
+ * - events are fired when updating the original element, so refresh_on_change should just work
+ *
+ * - should we still sort dbkey fields here?
+ */
+ select_elt.refresh_select2();
+ });
+}
+
+/**
+ * Make an element with text editable: (a) when user clicks on text, a textbox/area
+ * is provided for editing; (b) when enter key pressed, element's text is set and on_finish
+ * is called.
+ */
+// TODO: use this function to implement async_save_text (implemented below).
+$.fn.make_text_editable = function(config_dict) {
+ // Get config options.
+ var num_cols = ("num_cols" in config_dict ? config_dict.num_cols : 30),
+ num_rows = ("num_rows" in config_dict ? config_dict.num_rows : 4),
+ use_textarea = ("use_textarea" in config_dict ? config_dict.use_textarea : false),
+ on_finish = ("on_finish" in config_dict ? config_dict.on_finish : null),
+ help_text = ("help_text" in config_dict ? config_dict.help_text : null);
+
+ // Add element behavior.
+ var container = $(this);
+ container.addClass("editable-text").click(function(e) {
+ // If there's already an input element, editing is active, so do nothing.
+ if ($(this).children(":input").length > 0) {
+ return;
+ }
+
+ container.removeClass("editable-text");
+
+ // Handler for setting element text.
+ var set_text = function(new_text) {
+ container.find(":input").remove();
+
+ if (new_text !== "") {
+ container.text(new_text);
+ }
+ else {
+ // No text; need a line so that there is a click target.
+ container.html("<br>");
+ }
+ container.addClass("editable-text");
+
+ if (on_finish) {
+ on_finish(new_text);
+ }
+ };
+
+ // Create input element(s) for editing.
+ var cur_text = ("cur_text" in config_dict ? config_dict.cur_text : container.text() ),
+ input_elt, button_elt;
+
+ if (use_textarea) {
+ input_elt = $("<textarea/>")
+ .attr({ rows: num_rows, cols: num_cols }).text($.trim(cur_text))
+ .keyup(function(e) {
+ if (e.keyCode === 27) {
+ // Escape key.
+ set_text(cur_text);
+ }
+ });
+ button_elt = $("<button/>").text("Done").click(function() {
+ set_text(input_elt.val());
+ // Return false so that click does not propogate to container.
+ return false;
+ });
+ }
+ else {
+ input_elt = $("<input type='text'/>").attr({ value: $.trim(cur_text), size: num_cols })
+ .blur(function() {
+ set_text(cur_text);
+ }).keyup(function(e) {
+ if (e.keyCode === 27) {
+ // Escape key.
+ $(this).trigger("blur");
+ } else if (e.keyCode === 13) {
+ // Enter key.
+ set_text($(this).val());
+ }
+
+ // Do not propogate event to avoid unwanted side effects.
+ e.stopPropagation();
+ });
+ }
+
+ // Replace text with input object(s) and focus & select.
+ container.text("");
+ container.append(input_elt);
+ if (button_elt) {
+ container.append(button_elt);
+ }
+ input_elt.focus();
+ input_elt.select();
+
+ // Do not propogate to elements below b/c that blurs input and prevents it from being used.
+ e.stopPropagation();
+ });
+
+ // Add help text if there some.
+ if (help_text) {
+ container.attr("title", help_text).tooltip();
+ }
+
+ return container;
+};
+
+/**
+ * Edit and save text asynchronously.
+ */
+function async_save_text( click_to_edit_elt, text_elt_id, save_url,
+ text_parm_name, num_cols, use_textarea, num_rows, on_start, on_finish ) {
+ // Set defaults if necessary.
+ if (num_cols === undefined) {
+ num_cols = 30;
+ }
+ if (num_rows === undefined) {
+ num_rows = 4;
+ }
+
+ // Set up input element.
+ $("#" + click_to_edit_elt).click(function() {
+ // Check if this is already active
+ if ( $("#renaming-active").length > 0) {
+ return;
+ }
+ var text_elt = $("#" + text_elt_id),
+ old_text = text_elt.text(),
+ t;
+
+ if (use_textarea) {
+ t = $("<textarea></textarea>").attr({ rows: num_rows, cols: num_cols }).text( $.trim(old_text) );
+ } else {
+ t = $("<input type='text'></input>").attr({ value: $.trim(old_text), size: num_cols });
+ }
+ t.attr("id", "renaming-active");
+ t.blur( function() {
+ $(this).remove();
+ text_elt.show();
+ if (on_finish) {
+ on_finish(t);
+ }
+ });
+ t.keyup( function( e ) {
+ if ( e.keyCode === 27 ) {
+ // Escape key
+ $(this).trigger( "blur" );
+ } else if ( e.keyCode === 13 ) {
+ // Enter key submits
+ var ajax_data = {};
+ ajax_data[text_parm_name] = $(this).val();
+ $(this).trigger( "blur" );
+ $.ajax({
+ url: save_url,
+ data: ajax_data,
+ error: function() {
+ alert( "Text editing for elt " + text_elt_id + " failed" );
+ // TODO: call finish or no? For now, let's not because error occurred.
+ },
+ success: function(processed_text) {
+ // Set new text and call finish method.
+ if (processed_text !== "") {
+ text_elt.text(processed_text);
+ } else {
+ text_elt.html("<em>None</em>");
+ }
+ if (on_finish) {
+ on_finish(t);
+ }
+ }
+ });
+ }
+ });
+
+ if (on_start) {
+ on_start(t);
+ }
+ // Replace text with input object and focus & select.
+ text_elt.hide();
+ t.insertAfter(text_elt);
+ t.focus();
+ t.select();
+
+ return;
+ });
+}
+
+function commatize( number ) {
+ number += ''; // Convert to string
+ var rgx = /(\d+)(\d{3})/;
+ while (rgx.test(number)) {
+ number = number.replace(rgx, '$1' + ',' + '$2');
+ }
+ return number;
+}
+
+// Reset tool search to start state.
+function reset_tool_search( initValue ) {
+ // Function may be called in top frame or in tool_menu_frame;
+ // in either case, get the tool menu frame.
+ var tool_menu_frame = $("#galaxy_tools").contents();
+ if (tool_menu_frame.length === 0) {
+ tool_menu_frame = $(document);
+ }
+
+ // Remove classes that indicate searching is active.
+ $(this).removeClass("search_active");
+ tool_menu_frame.find(".toolTitle").removeClass("search_match");
+
+ // Reset visibility of tools and labels.
+ tool_menu_frame.find(".toolSectionBody").hide();
+ tool_menu_frame.find(".toolTitle").show();
+ tool_menu_frame.find(".toolPanelLabel").show();
+ tool_menu_frame.find(".toolSectionWrapper").each( function() {
+ if ($(this).attr('id') !== 'recently_used_wrapper') {
+ // Default action.
+ $(this).show();
+ } else if ($(this).hasClass("user_pref_visible")) {
+ $(this).show();
+ }
+ });
+ tool_menu_frame.find("#search-no-results").hide();
+
+ // Reset search input.
+ tool_menu_frame.find("#search-spinner").hide();
+ if (initValue) {
+ var search_input = tool_menu_frame.find("#tool-search-query");
+ search_input.val("search tools");
+ }
+}
+
+// Create GalaxyAsync object.
+var GalaxyAsync = function(log_action) {
+ this.url_dict = {};
+ this.log_action = (log_action === undefined ? false : log_action);
+};
+
+GalaxyAsync.prototype.set_func_url = function( func_name, url ) {
+ this.url_dict[func_name] = url;
+};
+
+// Set user preference asynchronously.
+GalaxyAsync.prototype.set_user_pref = function( pref_name, pref_value ) {
+ // Get URL.
+ var url = this.url_dict[arguments.callee];
+ if (url === undefined) { return false; }
+ $.ajax({
+ url: url,
+ data: { "pref_name" : pref_name, "pref_value" : pref_value },
+ error: function() { return false; },
+ success: function() { return true; }
+ });
+};
+
+// Log user action asynchronously.
+GalaxyAsync.prototype.log_user_action = function( action, context, params ) {
+ if (!this.log_action) { return; }
+
+ // Get URL.
+ var url = this.url_dict[arguments.callee];
+ if (url === undefined) { return false; }
+ $.ajax({
+ url: url,
+ data: { "action" : action, "context" : context, "params" : params },
+ error: function() { return false; },
+ success: function() { return true; }
+ });
+};
+
+// Initialize refresh events.
+function init_refresh_on_change () {
+ $("select[refresh_on_change='true']")
+ .off('change')
+ .change(function() {
+ var select_field = $(this),
+ select_val = select_field.val(),
+ refresh = false,
+ ref_on_change_vals = select_field.attr("refresh_on_change_values");
+ if (ref_on_change_vals) {
+ ref_on_change_vals = ref_on_change_vals.split(',');
+ var last_selected_value = select_field.attr("last_selected_value");
+ if ($.inArray(select_val, ref_on_change_vals) === -1 && $.inArray(last_selected_value, ref_on_change_vals) === -1) {
+ return;
+ }
+ }
+ $(window).trigger("refresh_on_change");
+ $(document).trigger("convert_to_values"); // Convert autocomplete text to values
+ select_field.get(0).form.submit();
+ });
+
+ // checkboxes refresh on change
+ $(":checkbox[refresh_on_change='true']")
+ .off('click')
+ .click( function() {
+ var select_field = $(this),
+ select_val = select_field.val(),
+ refresh = false,
+ ref_on_change_vals = select_field.attr("refresh_on_change_values");
+ if (ref_on_change_vals) {
+ ref_on_change_vals = ref_on_change_vals.split(',');
+ var last_selected_value = select_field.attr("last_selected_value");
+ if ($.inArray(select_val, ref_on_change_vals) === -1 && $.inArray(last_selected_value, ref_on_change_vals) === -1) {
+ return;
+ }
+ }
+ $(window).trigger("refresh_on_change");
+ select_field.get(0).form.submit();
+ });
+
+ // Links with confirmation
+ $( "a[confirm]" )
+ .off('click')
+ .click( function() {
+ return confirm( $(this).attr("confirm") );
+ });
+};
+
+
+// jQuery plugin to prevent double submission of forms
+// Ref: http://stackoverflow.com/questions/2830542/prevent-double-submission-of-for…
+jQuery.fn.preventDoubleSubmission = function() {
+ $(this).on('submit',function(e){
+ var $form = $(this);
+
+ if ($form.data('submitted') === true) {
+ // Previously submitted - don't submit again
+ e.preventDefault();
+ } else {
+ // Mark it so that the next submit can be ignored
+ $form.data('submitted', true);
+ }
+ });
+
+ // Keep chainability
+ return this;
+};
+
+$(document).ready( function() {
+
+ // Refresh events for form fields.
+ init_refresh_on_change();
+
+ // Tooltips
+ if ( $.fn.tooltip ) {
+ // Put tooltips below items in panel header so that they do not overlap masthead.
+ $(".unified-panel-header [title]").tooltip( { placement: 'bottom' } );
+
+ // default tooltip initialization, it will follow the data-placement tag for tooltip location
+ // and fallback to 'top' if not present
+ $("[title]").tooltip();
+ }
+ // Make popup menus.
+ make_popup_menus();
+
+ // Replace big selects.
+ replace_big_select_inputs(20, 1500);
+
+ // If galaxy_main frame does not exist and link targets galaxy_main,
+ // add use_panels=True and set target to self.
+ $("a").click( function() {
+ var anchor = $(this);
+ var galaxy_main_exists = (parent.frames && parent.frames.galaxy_main);
+ if ( ( anchor.attr( "target" ) == "galaxy_main" ) && ( !galaxy_main_exists ) ) {
+ var href = anchor.attr("href");
+ if (href.indexOf("?") == -1) {
+ href += "?";
+ }
+ else {
+ href += "&";
+ }
+ href += "use_panels=True";
+ anchor.attr("href", href);
+ anchor.attr("target", "_self");
+ }
+ return anchor;
+ });
+
+});
diff -r f2a70e7bac29aa06b47a499a28af1bc7ee61c70f -r be1142c63cb38346b8c13d24367c931b6c75243a client/galaxy/scripts/galaxy.frame.js
--- /dev/null
+++ b/client/galaxy/scripts/galaxy.frame.js
@@ -0,0 +1,173 @@
+// dependencies
+define(["galaxy.masthead", "mvc/ui/ui-frames"], function(mod_masthead, Frames) {
+
+// frame manager
+var GalaxyFrame = Backbone.View.extend(
+{
+ // base element
+ el_main: 'body',
+
+ // frame active/disabled
+ active: false,
+
+ // button active
+ button_active: null,
+
+ // button load
+ button_load : null,
+
+ // initialize
+ initialize : function(options)
+ {
+ // add to masthead menu
+ var self = this;
+
+ // create frames
+ this.frames = new Frames.View({
+ visible: false,
+ });
+
+ // add activate icon
+ this.button_active = new mod_masthead.GalaxyMastheadIcon (
+ {
+ icon : 'fa-th',
+ tooltip : 'Enable/Disable Scratchbook',
+ onclick : function() { self._activate(); },
+ onunload : function() {
+ if (self.frames.length() > 0) {
+ return "You opened " + self.frames.length() + " frame(s) which will be lost.";
+ }
+ }
+ });
+
+ // add to masthead
+ Galaxy.masthead.append(this.button_active);
+
+ // add load icon
+ this.button_load = new mod_masthead.GalaxyMastheadIcon (
+ {
+ icon : 'fa-eye',
+ tooltip : 'Show/Hide Scratchbook',
+ onclick : function(e) {
+ if (self.frames.visible) {
+ self.frames.hide();
+ } else {
+ self.frames.show();
+ }
+ },
+ with_number : true
+ });
+
+ // add to masthead
+ Galaxy.masthead.append(this.button_load);
+
+ // create
+ this.setElement(this.frames.$el);
+
+ // append to main
+ $(this.el_main).append(this.$el);
+
+ // refresh menu
+ this.frames.setOnChange(function() {
+ self._refresh();
+ });
+ this._refresh();
+ },
+
+ // adds and displays a new frame/window
+ add: function(options)
+ {
+ // open new tab
+ if (options.target == '_blank')
+ {
+ window.open(options.content);
+ return;
+ }
+
+ // reload entire window
+ if (options.target == '_top' || options.target == '_parent' || options.target == '_self')
+ {
+ window.location = options.content;
+ return;
+ }
+
+ // validate
+ if (!this.active)
+ {
+ // fix url if main frame is unavailable
+ var $galaxy_main = $(window.parent.document).find('#galaxy_main');
+ if (options.target == 'galaxy_main' || options.target == 'center')
+ {
+ if ($galaxy_main.length === 0)
+ {
+ var href = options.content;
+ if (href.indexOf('?') == -1)
+ href += '?';
+ else
+ href += '&';
+ href += 'use_panels=True';
+ window.location = href;
+ } else {
+ $galaxy_main.attr('src', options.content);
+ }
+ } else
+ window.location = options.content;
+
+ // stop
+ return;
+ }
+
+ // add to frames view
+ this.frames.add(options);
+ },
+
+ // activate/disable panel
+ _activate: function ()
+ {
+ // check
+ if (this.active)
+ {
+ // disable
+ this.active = false;
+
+ // toggle
+ this.button_active.untoggle();
+
+ // hide panel
+ this.frames.hide();
+ } else {
+ // activate
+ this.active = true;
+
+ // untoggle
+ this.button_active.toggle();
+ }
+ },
+
+ // update frame counter
+ _refresh: function()
+ {
+ // update on screen counter
+ this.button_load.number(this.frames.length());
+
+ // check
+ if(this.frames.length() === 0)
+ this.button_load.hide();
+ else
+ this.button_load.show();
+
+ // check
+ if (this.frames.visible) {
+ this.button_load.toggle();
+ } else {
+ this.button_load.untoggle();
+ }
+ }
+});
+
+// return
+return {
+ GalaxyFrame: GalaxyFrame
+};
+
+});
diff -r f2a70e7bac29aa06b47a499a28af1bc7ee61c70f -r be1142c63cb38346b8c13d24367c931b6c75243a client/galaxy/scripts/galaxy.library.js
--- /dev/null
+++ b/client/galaxy/scripts/galaxy.library.js
@@ -0,0 +1,169 @@
+// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+// === MAIN GALAXY LIBRARY MODULE ====
+// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+
+define([
+ "galaxy.masthead",
+ "utils/utils",
+ "libs/toastr",
+ "mvc/base-mvc",
+ "mvc/library/library-model",
+ "mvc/library/library-folderlist-view",
+ "mvc/library/library-librarylist-view",
+ "mvc/library/library-librarytoolbar-view",
+ "mvc/library/library-foldertoolbar-view",
+ "mvc/library/library-dataset-view",
+ "mvc/library/library-library-view",
+ "mvc/library/library-folder-view"
+ ],
+function(mod_masthead,
+ mod_utils,
+ mod_toastr,
+ mod_baseMVC,
+ mod_library_model,
+ mod_folderlist_view,
+ mod_librarylist_view,
+ mod_librarytoolbar_view,
+ mod_foldertoolbar_view,
+ mod_library_dataset_view,
+ mod_library_library_view,
+ mod_library_folder_view
+ ) {
+
+// ============================================================================
+// ROUTER
+var LibraryRouter = Backbone.Router.extend({
+ initialize: function() {
+ this.routesHit = 0;
+ //keep count of number of routes handled by the application
+ Backbone.history.on('route', function() { this.routesHit++; }, this);
+ },
+
+ routes: {
+ "" : "libraries",
+ "library/:library_id/permissions" : "library_permissions",
+ "folders/:folder_id/permissions" : "folder_permissions",
+ "folders/:id" : "folder_content",
+ "folders/:folder_id/datasets/:dataset_id" : "dataset_detail",
+ "folders/:folder_id/datasets/:dataset_id/permissions" : "dataset_permissions",
+ "folders/:folder_id/datasets/:dataset_id/versions/:ldda_id" : "dataset_version",
+ "folders/:folder_id/download/:format" : "download",
+ "folders/:folder_id/import/:source" : "import_datasets"
+ },
+
+ back: function() {
+ if(this.routesHit > 1) {
+ //more than one route hit -> user did not land to current page directly
+ window.history.back();
+ } else {
+ //otherwise go to the home page. Use replaceState if available so
+ //the navigation doesn't create an extra history entry
+ this.navigate('#', {trigger:true, replace:true});
+ }
+ }
+});
+
+// ============================================================================
+/** session storage for library preferences */
+var LibraryPrefs = mod_baseMVC.SessionStorageModel.extend({
+ defaults : {
+ with_deleted : false,
+ sort_order : 'asc',
+ sort_by : 'name'
+ }
+});
+
+// ============================================================================
+// Main controller of Galaxy Library
+var GalaxyLibrary = Backbone.View.extend({
+
+ libraryToolbarView: null,
+ libraryListView: null,
+ library_router: null,
+ libraryView: null,
+ folderToolbarView: null,
+ folderListView: null,
+ datasetView: null,
+
+ initialize : function(){
+ Galaxy.libraries = this;
+
+ this.preferences = new LibraryPrefs( {id: 'global-lib-prefs'} );
+
+ this.library_router = new LibraryRouter();
+
+ this.library_router.on('route:libraries', function() {
+ Galaxy.libraries.libraryToolbarView = new mod_librarytoolbar_view.LibraryToolbarView();
+ Galaxy.libraries.libraryListView = new mod_librarylist_view.LibraryListView();
+ });
+
+ this.library_router.on('route:folder_content', function(id) {
+ if (Galaxy.libraries.folderToolbarView){
+ Galaxy.libraries.folderToolbarView.$el.unbind('click');
+ }
+ Galaxy.libraries.folderToolbarView = new mod_foldertoolbar_view.FolderToolbarView({id: id});
+ Galaxy.libraries.folderListView = new mod_folderlist_view.FolderListView({id: id});
+ });
+
+ this.library_router.on('route:download', function(folder_id, format) {
+ if ($('#folder_list_body').find(':checked').length === 0) {
+ mod_toastr.info( 'You must select at least one dataset to download' );
+ Galaxy.libraries.library_router.navigate('folders/' + folder_id, {trigger: true, replace: true});
+ } else {
+ Galaxy.libraries.folderToolbarView.download(folder_id, format);
+ Galaxy.libraries.library_router.navigate('folders/' + folder_id, {trigger: false, replace: true});
+ }
+ });
+
+ this.library_router.on('route:dataset_detail', function(folder_id, dataset_id){
+ if (Galaxy.libraries.datasetView){
+ Galaxy.libraries.datasetView.$el.unbind('click');
+ }
+ Galaxy.libraries.datasetView = new mod_library_dataset_view.LibraryDatasetView({id: dataset_id});
+ });
+ this.library_router.on('route:dataset_version', function(folder_id, dataset_id, ldda_id){
+ if (Galaxy.libraries.datasetView){
+ Galaxy.libraries.datasetView.$el.unbind('click');
+ }
+ Galaxy.libraries.datasetView = new mod_library_dataset_view.LibraryDatasetView({id: dataset_id, ldda_id: ldda_id, show_version: true});
+ });
+
+ this.library_router.on('route:dataset_permissions', function(folder_id, dataset_id){
+ if (Galaxy.libraries.datasetView){
+ Galaxy.libraries.datasetView.$el.unbind('click');
+ }
+ Galaxy.libraries.datasetView = new mod_library_dataset_view.LibraryDatasetView({id: dataset_id, show_permissions: true});
+ });
+
+ this.library_router.on('route:library_permissions', function(library_id){
+ if (Galaxy.libraries.libraryView){
+ Galaxy.libraries.libraryView.$el.unbind('click');
+ }
+ Galaxy.libraries.libraryView = new mod_library_library_view.LibraryView({id: library_id, show_permissions: true});
+ });
+
+ this.library_router.on('route:folder_permissions', function(folder_id){
+ if (Galaxy.libraries.folderView){
+ Galaxy.libraries.folderView.$el.unbind('click');
+ }
+ Galaxy.libraries.folderView = new mod_library_folder_view.FolderView({id: folder_id, show_permissions: true});
+ });
+ this.library_router.on('route:import_datasets', function(folder_id, source){
+ if (Galaxy.libraries.folderToolbarView && Galaxy.libraries.folderListView){
+ Galaxy.libraries.folderToolbarView.showImportModal({source:source});
+ } else {
+ Galaxy.libraries.folderToolbarView = new mod_foldertoolbar_view.FolderToolbarView({id: folder_id});
+ Galaxy.libraries.folderListView = new mod_folderlist_view.FolderListView({id: folder_id});
+ Galaxy.libraries.folderToolbarView.showImportModal({source: source});
+ }
+ });
+
+ Backbone.history.start({pushState: false});
+ }
+});
+
+return {
+ GalaxyApp: GalaxyLibrary
+};
+
+});
This diff is so big that we needed to truncate the remainder.
https://bitbucket.org/galaxy/galaxy-central/commits/c55530cfa7b1/
Changeset: c55530cfa7b1
Branch: next-stable
User: natefoo
Date: 2014-09-22 14:51:08+00:00
Summary: Merge stable.
Affected #: 1 file
diff -r be1142c63cb38346b8c13d24367c931b6c75243a -r c55530cfa7b1133bc6996d502ddaaf1d41e2ec42 .hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -18,4 +18,4 @@
81fbe25bd02edcd53065e8e4476dd1dfb5a72cf2 latest_2013.11.04
2a756ca2cb1826db7796018e77d12e2dd7b67603 latest_2014.02.10
ca45b78adb4152fc6e7395514d46eba6b7d0b838 release_2014.08.11
-21f2a42a06d7d2b8c408aed22c691f5e8b209311 latest_2014.08.11
+9f495158c5ba45fcf61fc37d82aa8545eaba0bd5 latest_2014.08.11
https://bitbucket.org/galaxy/galaxy-central/commits/fa3bb4ad3b09/
Changeset: fa3bb4ad3b09
Branch: next-stable
User: natefoo
Date: 2014-09-22 15:36:25+00:00
Summary: Merge last minute bug fixes from default.
Affected #: 3 files
diff -r c55530cfa7b1133bc6996d502ddaaf1d41e2ec42 -r fa3bb4ad3b09d41cddc20cf0158f228c97866c0e lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
@@ -1105,6 +1105,8 @@
# If set to a true value then MakeMaker's prompt function will always
# return the default without waiting for user input.
cmd = '''PERL_MM_USE_DEFAULT=1; export PERL_MM_USE_DEFAULT; '''
+ cmd += 'export PERL5LIB=$INSTALL_DIR/lib/perl5:$PERL5LIB;'
+ cmd += 'export PATH=$INSTALL_DIR/bin:$PATH;'
if perl_package.find( '://' ) != -1:
# We assume a URL to a gem file.
url = perl_package
diff -r c55530cfa7b1133bc6996d502ddaaf1d41e2ec42 -r fa3bb4ad3b09d41cddc20cf0158f228c97866c0e tools/data_source/ebi_sra.xml
--- a/tools/data_source/ebi_sra.xml
+++ b/tools/data_source/ebi_sra.xml
@@ -4,7 +4,7 @@
<!-- This paython script imports the file into Galaxy --><command interpreter="python">data_source.py $output $__app__.config.output_size_limit</command><!-- The URL where Galaxy will forwards the user when this tool is accessed from the Get Data menu -->
- <inputs action="http://www.ebi.ac.uk/ena/data/search" check_values="false" method="get">
+ <inputs action="https://www.ebi.ac.uk/ena/data/search" check_values="false" method="get"><display>go to EBI SRA server $GALAXY_URL</display></inputs><uihints minwidth="800"/>
diff -r c55530cfa7b1133bc6996d502ddaaf1d41e2ec42 -r fa3bb4ad3b09d41cddc20cf0158f228c97866c0e tools/data_source/ucsc_tablebrowser.xml
--- a/tools/data_source/ucsc_tablebrowser.xml
+++ b/tools/data_source/ucsc_tablebrowser.xml
@@ -7,7 +7,7 @@
<tool name="UCSC Main" id="ucsc_table_direct1" tool_type="data_source"><description>table browser</description><command interpreter="python">data_source.py $output $__app__.config.output_size_limit</command>
- <inputs action="http://genome.ucsc.edu/cgi-bin/hgTables" check_values="false" method="get">
+ <inputs action="https://genome.ucsc.edu/cgi-bin/hgTables" check_values="false" method="get"><display>go to UCSC Table Browser $GALAXY_URL</display><param name="GALAXY_URL" type="baseurl" value="/tool_runner" /><param name="tool_id" type="hidden" value="ucsc_table_direct1" />
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: natefoo: Always access UCSC Main via HTTPS.
by commits-noreply@bitbucket.org 22 Sep '14
by commits-noreply@bitbucket.org 22 Sep '14
22 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/579d211c2b0f/
Changeset: 579d211c2b0f
User: natefoo
Date: 2014-09-22 15:31:56+00:00
Summary: Always access UCSC Main via HTTPS.
Affected #: 1 file
diff -r 7867dda60542072921153e30195fffde741e5333 -r 579d211c2b0fa8ef4195930cb999edbb9a0cf8eb tools/data_source/ucsc_tablebrowser.xml
--- a/tools/data_source/ucsc_tablebrowser.xml
+++ b/tools/data_source/ucsc_tablebrowser.xml
@@ -7,7 +7,7 @@
<tool name="UCSC Main" id="ucsc_table_direct1" tool_type="data_source"><description>table browser</description><command interpreter="python">data_source.py $output $__app__.config.output_size_limit</command>
- <inputs action="http://genome.ucsc.edu/cgi-bin/hgTables" check_values="false" method="get">
+ <inputs action="https://genome.ucsc.edu/cgi-bin/hgTables" check_values="false" method="get"><display>go to UCSC Table Browser $GALAXY_URL</display><param name="GALAXY_URL" type="baseurl" value="/tool_runner" /><param name="tool_id" type="hidden" value="ucsc_table_direct1" />
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jmchilton: Always access EBI SRA via HTTPS.
by commits-noreply@bitbucket.org 22 Sep '14
by commits-noreply@bitbucket.org 22 Sep '14
22 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/7867dda60542/
Changeset: 7867dda60542
User: jmchilton
Date: 2014-09-22 15:23:02+00:00
Summary: Always access EBI SRA via HTTPS.
Thanks to Ilya for opening pull request to make it conditionally use HTTPS - https://bitbucket.org/galaxy/galaxy-central/pull-request/491/remove-http-fr… - but this goes one step further and always uses HTTPS as suggested by Nate in the pull request comments.
Affected #: 1 file
diff -r e3b16462112b2ab8150564e183213048e7c027da -r 7867dda60542072921153e30195fffde741e5333 tools/data_source/ebi_sra.xml
--- a/tools/data_source/ebi_sra.xml
+++ b/tools/data_source/ebi_sra.xml
@@ -4,7 +4,7 @@
<!-- This paython script imports the file into Galaxy --><command interpreter="python">data_source.py $output $__app__.config.output_size_limit</command><!-- The URL where Galaxy will forwards the user when this tool is accessed from the Get Data menu -->
- <inputs action="http://www.ebi.ac.uk/ena/data/search" check_values="false" method="get">
+ <inputs action="https://www.ebi.ac.uk/ena/data/search" check_values="false" method="get"><display>go to EBI SRA server $GALAXY_URL</display></inputs><uihints minwidth="800"/>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/6d5e465c5b8b/
Changeset: 6d5e465c5b8b
Branch: BjoernGruening/add-install_dir-to-perl5lib-and-path-bef-1410949639333
User: dannon
Date: 2014-09-22 15:15:58+00:00
Summary: Branch prune.
Affected #: 0 files
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dannon: Merged in BjoernGruening/galaxy-central-5/BjoernGruening/add-install_dir-to-perl5lib-and-path-bef-1410949639333 (pull request #499)
by commits-noreply@bitbucket.org 22 Sep '14
by commits-noreply@bitbucket.org 22 Sep '14
22 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e3b16462112b/
Changeset: e3b16462112b
User: dannon
Date: 2014-09-22 15:09:07+00:00
Summary: Merged in BjoernGruening/galaxy-central-5/BjoernGruening/add-install_dir-to-perl5lib-and-path-bef-1410949639333 (pull request #499)
Add $INSTALL_DIR to PERL5LIB and PATH before starting to install libraries. A few packages need this in order to recognise previous installed packages.
Affected #: 1 file
diff -r df92b55d194a4d67a1b863c85044eb91c138c74b -r e3b16462112b2ab8150564e183213048e7c027da lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
@@ -1105,6 +1105,8 @@
# If set to a true value then MakeMaker's prompt function will always
# return the default without waiting for user input.
cmd = '''PERL_MM_USE_DEFAULT=1; export PERL_MM_USE_DEFAULT; '''
+ cmd += 'export PERL5LIB=$INSTALL_DIR/lib/perl5:$PERL5LIB;'
+ cmd += 'export PATH=$INSTALL_DIR/bin:$PATH;'
if perl_package.find( '://' ) != -1:
# We assume a URL to a gem file.
url = perl_package
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/4969f6502d42/
Changeset: 4969f6502d42
Branch: BjoernGruening/add-install_dir-to-perl5lib-and-path-bef-1410949639333
User: BjoernGruening
Date: 2014-09-17 10:27:56+00:00
Summary: Add $INSTALL_DIR to PERL5LIB and PATH before starting to install libraries. A few packages need this in order to recognise previous installed packages.
Affected #: 1 file
diff -r 02738142b8cf5e0372ac5c2b46eeff5f0ab8e87a -r 4969f6502d423feb580946d6b4812a477cff77b4 lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
@@ -1105,6 +1105,8 @@
# If set to a true value then MakeMaker's prompt function will always
# return the default without waiting for user input.
cmd = '''PERL_MM_USE_DEFAULT=1; export PERL_MM_USE_DEFAULT; '''
+ cmd += 'export PERL5LIB=$INSTALL_DIR/lib/perl5:$PERL5LIB;'
+ cmd += 'export PATH=$INSTALL_DIR/bin:$PATH;'
if perl_package.find( '://' ) != -1:
# We assume a URL to a gem file.
url = perl_package
https://bitbucket.org/galaxy/galaxy-central/commits/e3b16462112b/
Changeset: e3b16462112b
User: dannon
Date: 2014-09-22 15:09:07+00:00
Summary: Merged in BjoernGruening/galaxy-central-5/BjoernGruening/add-install_dir-to-perl5lib-and-path-bef-1410949639333 (pull request #499)
Add $INSTALL_DIR to PERL5LIB and PATH before starting to install libraries. A few packages need this in order to recognise previous installed packages.
Affected #: 1 file
diff -r df92b55d194a4d67a1b863c85044eb91c138c74b -r e3b16462112b2ab8150564e183213048e7c027da lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/recipe/step_handler.py
@@ -1105,6 +1105,8 @@
# If set to a true value then MakeMaker's prompt function will always
# return the default without waiting for user input.
cmd = '''PERL_MM_USE_DEFAULT=1; export PERL_MM_USE_DEFAULT; '''
+ cmd += 'export PERL5LIB=$INSTALL_DIR/lib/perl5:$PERL5LIB;'
+ cmd += 'export PATH=$INSTALL_DIR/bin:$PATH;'
if perl_package.find( '://' ) != -1:
# We assume a URL to a gem file.
url = perl_package
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jmchilton: Merged in jmchilton/galaxy-central-fork-1 (pull request #496)
by commits-noreply@bitbucket.org 22 Sep '14
by commits-noreply@bitbucket.org 22 Sep '14
22 Sep '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/df92b55d194a/
Changeset: df92b55d194a
User: jmchilton
Date: 2014-09-22 14:24:39+00:00
Summary: Merged in jmchilton/galaxy-central-fork-1 (pull request #496)
More consistent tool API for map/reduce operations.
Affected #: 4 files
diff -r 42f677bab2e4880b62758614fcb2c7dc27013788 -r df92b55d194a4d67a1b863c85044eb91c138c74b lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -1887,6 +1887,11 @@
elif isinstance( value, dict ) and 'src' in value and 'id' in value:
if value['src'] == 'hda':
rval = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( trans.app.security.decode_id(value['id']) )
+ elif value['src'] == 'hdca':
+ decoded_id = trans.app.security.decode_id( value[ 'id' ] )
+ rval = trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( decoded_id )
+ else:
+ raise ValueError("Unknown input source %s passed to job submission API." % value['src'])
elif str( value ).startswith( "__collection_reduce__|" ):
encoded_id = str( value )[ len( "__collection_reduce__|" ): ]
decoded_id = trans.app.security.decode_id( encoded_id )
@@ -1903,6 +1908,10 @@
raise ValueError( "The previously selected dataset has been previously deleted" )
if hasattr( v, "dataset" ) and v.dataset.state in [ galaxy.model.Dataset.states.ERROR, galaxy.model.Dataset.states.DISCARDED ]:
raise ValueError( "The previously selected dataset has entered an unusable state" )
+ if not self.multiple:
+ if len( values ) > 1:
+ raise ValueError( "More than one dataset supplied to single input dataset parameter.")
+ rval = values[ 0 ]
return rval
def to_string( self, value, app ):
diff -r 42f677bab2e4880b62758614fcb2c7dc27013788 -r df92b55d194a4d67a1b863c85044eb91c138c74b lib/galaxy/tools/parameters/meta.py
--- a/lib/galaxy/tools/parameters/meta.py
+++ b/lib/galaxy/tools/parameters/meta.py
@@ -14,7 +14,33 @@
execution).
"""
+ def classify_unmodified_parameter( input_key ):
+ value = incoming[ input_key ]
+ if isinstance( value, dict ) and 'values' in value:
+ # Explicit meta wrapper for inputs...
+ is_batch = value.get( 'batch', False )
+ is_linked = value.get( 'linked', True )
+ if is_batch and is_linked:
+ classification = permutations.input_classification.MATCHED
+ elif is_batch:
+ classification = permutations.input_classification.MULTIPLIED
+ else:
+ classification = permutations.input_classification.SINGLE
+ if __collection_multirun_parameter( value ):
+ collection_value = value[ 'values' ][ 0 ]
+ values = __expand_collection_parameter( trans, input_key, collection_value, collections_to_match )
+ else:
+ values = value[ 'values' ]
+ else:
+ classification = permutations.input_classification.SINGLE
+ values = value
+ return classification, values
+
+ from galaxy.dataset_collections import matching
+ collections_to_match = matching.CollectionsToMatch()
+
def classifier( input_key ):
+ collection_multirun_key = "%s|__collection_multirun__" % input_key
multirun_key = "%s|__multirun__" % input_key
if multirun_key in incoming:
multi_value = util.listify( incoming[ multirun_key ] )
@@ -24,41 +50,12 @@
if len( multi_value ) == 0:
multi_value = None
return permutations.input_classification.SINGLE, multi_value[ 0 ]
+ elif collection_multirun_key in incoming:
+ incoming_val = incoming[ collection_multirun_key ]
+ values = __expand_collection_parameter( trans, input_key, incoming_val, collections_to_match )
+ return permutations.input_classification.MATCHED, values
else:
- return permutations.input_classification.SINGLE, incoming[ input_key ]
-
- from galaxy.dataset_collections import matching
- collections_to_match = matching.CollectionsToMatch()
-
- def collection_classifier( input_key ):
- multirun_key = "%s|__collection_multirun__" % input_key
- if multirun_key in incoming:
- incoming_val = incoming[ multirun_key ]
- # If subcollectin multirun of data_collection param - value will
- # be "hdca_id|subcollection_type" else it will just be hdca_id
- if "|" in incoming_val:
- encoded_hdc_id, subcollection_type = incoming_val.split( "|", 1 )
- else:
- try:
- src = incoming_val[ "src" ]
- if src != "hdca":
- raise exceptions.ToolMetaParameterException( "Invalid dataset collection source type %s" % src )
- encoded_hdc_id = incoming_val[ "id" ]
- except TypeError:
- encoded_hdc_id = incoming_val
- subcollection_type = None
- hdc_id = trans.app.security.decode_id( encoded_hdc_id )
- hdc = trans.sa_session.query( model.HistoryDatasetCollectionAssociation ).get( hdc_id )
- collections_to_match.add( input_key, hdc, subcollection_type=subcollection_type )
- if subcollection_type is not None:
- from galaxy.dataset_collections import subcollections
- subcollection_elements = subcollections.split_dataset_collection_instance( hdc, subcollection_type )
- return permutations.input_classification.MATCHED, subcollection_elements
- else:
- hdas = hdc.collection.dataset_instances
- return permutations.input_classification.MATCHED, hdas
- else:
- return permutations.input_classification.SINGLE, incoming[ input_key ]
+ return classify_unmodified_parameter( input_key )
# Stick an unexpanded version of multirun keys so they can be replaced,
# by expand_mult_inputs.
@@ -76,20 +73,59 @@
multirun_found = False
collection_multirun_found = False
for key, value in incoming.iteritems():
- multirun_found = try_replace_key( key, "|__multirun__" ) or multirun_found
- collection_multirun_found = try_replace_key( key, "|__collection_multirun__" ) or collection_multirun_found
+ if isinstance( value, dict ) and 'values' in value:
+ batch = value.get( 'batch', False )
+ if batch:
+ if __collection_multirun_parameter( value ):
+ collection_multirun_found = True
+ else:
+ multirun_found = True
+ else:
+ continue
+ else:
+ # Old-style batching (remove someday? - pretty hacky and didn't live in API long)
+ try_replace_key( key, "|__multirun__" ) or multirun_found
+ try_replace_key( key, "|__collection_multirun__" ) or collection_multirun_found
- if sum( [ 1 if f else 0 for f in [ multirun_found, collection_multirun_found ] ] ) > 1:
- # In theory doable, but to complicated for a first pass.
- message = "Cannot specify parallel execution across both multiple datasets and dataset collections."
- raise exceptions.ToolMetaParameterException( message )
+ expanded_incomings = permutations.expand_multi_inputs( incoming_template, classifier )
+ if collections_to_match.has_collections():
+ collection_info = trans.app.dataset_collections_service.match_collections( collections_to_match )
+ else:
+ collection_info = None
+ return expanded_incomings, collection_info
- if multirun_found:
- return permutations.expand_multi_inputs( incoming_template, classifier ), None
+
+def __expand_collection_parameter( trans, input_key, incoming_val, collections_to_match ):
+ # If subcollectin multirun of data_collection param - value will
+ # be "hdca_id|subcollection_type" else it will just be hdca_id
+ if "|" in incoming_val:
+ encoded_hdc_id, subcollection_type = incoming_val.split( "|", 1 )
else:
- expanded_incomings = permutations.expand_multi_inputs( incoming_template, collection_classifier )
- if collections_to_match.has_collections():
- collection_info = trans.app.dataset_collections_service.match_collections( collections_to_match )
- else:
- collection_info = None
- return expanded_incomings, collection_info
+ try:
+ src = incoming_val[ "src" ]
+ if src != "hdca":
+ raise exceptions.ToolMetaParameterException( "Invalid dataset collection source type %s" % src )
+ encoded_hdc_id = incoming_val[ "id" ]
+ subcollection_type = incoming_val.get( 'map_over_type', None )
+ except TypeError:
+ encoded_hdc_id = incoming_val
+ subcollection_type = None
+ hdc_id = trans.app.security.decode_id( encoded_hdc_id )
+ hdc = trans.sa_session.query( model.HistoryDatasetCollectionAssociation ).get( hdc_id )
+ collections_to_match.add( input_key, hdc, subcollection_type=subcollection_type )
+ if subcollection_type is not None:
+ from galaxy.dataset_collections import subcollections
+ subcollection_elements = subcollections.split_dataset_collection_instance( hdc, subcollection_type )
+ return subcollection_elements
+ else:
+ hdas = hdc.collection.dataset_instances
+ return hdas
+
+
+def __collection_multirun_parameter( value ):
+ batch_values = util.listify( value[ 'values' ] )
+ if len( batch_values ) == 1:
+ batch_over = batch_values[ 0 ]
+ if isinstance( batch_over, dict ) and ('src' in batch_over) and (batch_over[ 'src' ] == 'hdca'):
+ return True
+ return False
diff -r 42f677bab2e4880b62758614fcb2c7dc27013788 -r df92b55d194a4d67a1b863c85044eb91c138c74b test/api/test_tools.py
--- a/test/api/test_tools.py
+++ b/test/api/test_tools.py
@@ -109,6 +109,35 @@
output1_content = self.dataset_populator.get_history_dataset_content( history_id, dataset=output1 )
self.assertEqual( output1_content.strip(), "Cat1Test" )
+ @skip_without_tool( "cat1" )
+ def test_run_cat1_listified_param( self ):
+ # Run simple non-upload tool with an input data parameter.
+ history_id = self.dataset_populator.new_history()
+ new_dataset = self.dataset_populator.new_dataset( history_id, content='Cat1Testlistified' )
+ inputs = dict(
+ input1=[dataset_to_param( new_dataset )],
+ )
+ outputs = self._cat1_outputs( history_id, inputs=inputs )
+ self.assertEquals( len( outputs ), 1 )
+ output1 = outputs[ 0 ]
+ output1_content = self.dataset_populator.get_history_dataset_content( history_id, dataset=output1 )
+ self.assertEqual( output1_content.strip(), "Cat1Testlistified" )
+
+ @skip_without_tool( "cat1" )
+ def test_run_cat1_single_meta_wrapper( self ):
+ # Wrap input in a no-op meta parameter wrapper like Sam is planning to
+ # use for all UI API submissions.
+ history_id = self.dataset_populator.new_history()
+ new_dataset = self.dataset_populator.new_dataset( history_id, content='123' )
+ inputs = dict(
+ input1={ 'batch': False, 'values': [ dataset_to_param( new_dataset ) ] },
+ )
+ outputs = self._cat1_outputs( history_id, inputs=inputs )
+ self.assertEquals( len( outputs ), 1 )
+ output1 = outputs[ 0 ]
+ output1_content = self.dataset_populator.get_history_dataset_content( history_id, dataset=output1 )
+ self.assertEqual( output1_content.strip(), "123" )
+
@skip_without_tool( "validation_default" )
def test_validation( self ):
history_id = self.dataset_populator.new_history()
@@ -118,6 +147,20 @@
response = self._run( "validation_default", history_id, inputs )
self._assert_status_code_is( response, 400 )
+ @skip_without_tool( "collection_paired_test" )
+ def test_collection_parameter( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca_id = self.__build_pair( history_id, [ "123", "456" ] )
+ inputs = {
+ "f1": { "src": "hdca", "id": hdca_id },
+ }
+ output = self._run( "collection_paired_test", history_id, inputs, assert_ok=True )
+ assert len( output[ 'jobs' ] ) == 1
+ assert len( output[ 'implicit_collections' ] ) == 0
+ assert len( output[ 'outputs' ] ) == 1
+ contents = self.dataset_populator.get_history_dataset_content( history_id, hid=4 )
+ assert contents.strip() == "123\n456", contents
+
@skip_without_tool( "cat1" )
def test_run_cat1_with_two_inputs( self ):
# Run tool with an multiple data parameter and grouping (repeat)
@@ -135,16 +178,31 @@
self.assertEqual( output1_content.strip(), "Cat1Test\nCat2Test" )
@skip_without_tool( "cat1" )
+ def test_multirun_cat1_legacy( self ):
+ history_id, datasets = self._prepare_cat1_multirun()
+ inputs = {
+ "input1|__multirun__": datasets,
+ }
+ self._check_cat1_multirun( history_id, inputs )
+
+ @skip_without_tool( "cat1" )
def test_multirun_cat1( self ):
+ history_id, datasets = self._prepare_cat1_multirun()
+ inputs = {
+ "input1": {
+ 'batch': True,
+ 'values': datasets,
+ },
+ }
+ self._check_cat1_multirun( history_id, inputs )
+
+ def _prepare_cat1_multirun( self ):
history_id = self.dataset_populator.new_history()
new_dataset1 = self.dataset_populator.new_dataset( history_id, content='123' )
new_dataset2 = self.dataset_populator.new_dataset( history_id, content='456' )
- inputs = {
- "input1|__multirun__": [
- dataset_to_param( new_dataset1 ),
- dataset_to_param( new_dataset2 ),
- ],
- }
+ return history_id, [ dataset_to_param( new_dataset1 ), dataset_to_param( new_dataset2 ) ]
+
+ def _check_cat1_multirun( self, history_id, inputs ):
outputs = self._cat1_outputs( history_id, inputs=inputs )
self.assertEquals( len( outputs ), 2 )
output1 = outputs[ 0 ]
@@ -154,6 +212,20 @@
self.assertEquals( output1_content.strip(), "123" )
self.assertEquals( output2_content.strip(), "456" )
+ @skip_without_tool( "random_lines1" )
+ def test_multirun_non_data_parameter( self ):
+ history_id = self.dataset_populator.new_history()
+ new_dataset1 = self.dataset_populator.new_dataset( history_id, content='123\n456\n789' )
+ inputs = {
+ 'input': dataset_to_param( new_dataset1 ),
+ 'num_lines': { 'batch': True, 'values': [ 1, 2, 3 ] }
+ }
+ outputs = self._run_and_get_outputs( 'random_lines1', history_id, inputs )
+ # Assert we have three outputs with 1, 2, and 3 lines respectively.
+ assert len( outputs ) == 3
+ outputs_contents = [ self.dataset_populator.get_history_dataset_content( history_id, dataset=o ).strip() for o in outputs ]
+ assert sorted( map( lambda c: len( c.split( "\n" ) ), outputs_contents ) ) == [ 1, 2, 3 ]
+
@skip_without_tool( "cat1" )
def test_multirun_in_repeat( self ):
history_id = self.dataset_populator.new_history()
@@ -177,35 +249,60 @@
self.assertEquals( output2_content.strip(), "Common\n456" )
@skip_without_tool( "cat1" )
- def test_multirun_on_multiple_inputs( self ):
- history_id = self.dataset_populator.new_history()
- new_dataset1 = self.dataset_populator.new_dataset( history_id, content='123' )
- new_dataset2 = self.dataset_populator.new_dataset( history_id, content='456' )
- new_dataset3 = self.dataset_populator.new_dataset( history_id, content='789' )
- new_dataset4 = self.dataset_populator.new_dataset( history_id, content='0ab' )
+ def test_multirun_on_multiple_inputs_legacy( self ):
+ history_id, first_two, second_two = self._setup_two_multiruns()
inputs = {
- "input1|__multirun__": [
- dataset_to_param( new_dataset1 ),
- dataset_to_param( new_dataset2 ),
- ],
- 'queries_0|input2|__multirun__': [
- dataset_to_param( new_dataset3 ),
- dataset_to_param( new_dataset4 ),
- ],
+ "input1|__multirun__": first_two,
+ 'queries_0|input2|__multirun__': second_two,
}
outputs = self._cat1_outputs( history_id, inputs=inputs )
self.assertEquals( len( outputs ), 2 )
outputs_contents = [ self.dataset_populator.get_history_dataset_content( history_id, dataset=o ).strip() for o in outputs ]
assert "123\n789" in outputs_contents
assert "456\n0ab" in outputs_contents
- # TODO: Once cross production (instead of linking inputs) is an option
- # again redo test with these checks...
- # self.assertEquals( len( outputs ), 4 )
- # assert "123\n0ab" in outputs_contents
- # assert "456\n789" in outputs_contents
@skip_without_tool( "cat1" )
- def test_map_over_collection( self ):
+ def test_multirun_on_multiple_inputs( self ):
+ history_id, first_two, second_two = self._setup_two_multiruns()
+ inputs = {
+ "input1": { 'batch': True, 'values': first_two },
+ 'queries_0|input2': { 'batch': True, 'values': second_two },
+ }
+ outputs = self._cat1_outputs( history_id, inputs=inputs )
+ self.assertEquals( len( outputs ), 2 )
+ outputs_contents = [ self.dataset_populator.get_history_dataset_content( history_id, dataset=o ).strip() for o in outputs ]
+ assert "123\n789" in outputs_contents
+ assert "456\n0ab" in outputs_contents
+
+ @skip_without_tool( "cat1" )
+ def test_multirun_on_multiple_inputs_unlinked( self ):
+ history_id, first_two, second_two = self._setup_two_multiruns()
+ inputs = {
+ "input1": { 'batch': True, 'linked': False, 'values': first_two },
+ 'queries_0|input2': { 'batch': True, 'linked': False, 'values': second_two },
+ }
+ outputs = self._cat1_outputs( history_id, inputs=inputs )
+ outputs_contents = [ self.dataset_populator.get_history_dataset_content( history_id, dataset=o ).strip() for o in outputs ]
+ self.assertEquals( len( outputs ), 4 )
+ assert "123\n789" in outputs_contents
+ assert "456\n0ab" in outputs_contents
+ assert "123\n0ab" in outputs_contents
+ assert "456\n789" in outputs_contents
+
+ def _setup_two_multiruns( self ):
+ history_id = self.dataset_populator.new_history()
+ new_dataset1 = self.dataset_populator.new_dataset( history_id, content='123' )
+ new_dataset2 = self.dataset_populator.new_dataset( history_id, content='456' )
+ new_dataset3 = self.dataset_populator.new_dataset( history_id, content='789' )
+ new_dataset4 = self.dataset_populator.new_dataset( history_id, content='0ab' )
+ return (
+ history_id,
+ [ dataset_to_param( new_dataset1 ), dataset_to_param( new_dataset2 ) ],
+ [ dataset_to_param( new_dataset3 ), dataset_to_param( new_dataset4 ) ]
+ )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_collection_legacy( self ):
history_id = self.dataset_populator.new_history()
hdca_id = self.__build_pair( history_id, [ "123", "456" ] )
inputs = {
@@ -214,6 +311,18 @@
# first, next test method tests other.
"input1|__collection_multirun__": hdca_id,
}
+ self._run_and_check_simple_collection_mapping( history_id, inputs )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_collection( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca_id = self.__build_pair( history_id, [ "123", "456" ] )
+ inputs = {
+ "input1": { 'batch': True, 'values': [ { 'src': 'hdca', 'id': hdca_id } ] },
+ }
+ self._run_and_check_simple_collection_mapping( history_id, inputs )
+
+ def _run_and_check_simple_collection_mapping( self, history_id, inputs ):
create = self._run_cat1( history_id, inputs=inputs, assert_ok=True )
outputs = create[ 'outputs' ]
jobs = create[ 'jobs' ]
@@ -229,12 +338,24 @@
self.assertEquals( output2_content.strip(), "456" )
@skip_without_tool( "cat1" )
- def test_map_over_nested_collections( self ):
+ def test_map_over_nested_collections_legacy( self ):
history_id = self.dataset_populator.new_history()
hdca_id = self.__build_nested_list( history_id )
inputs = {
"input1|__collection_multirun__": dict( src="hdca", id=hdca_id ),
}
+ self._check_simple_cat1_over_nested_collections( history_id, inputs )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_nested_collections( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca_id = self.__build_nested_list( history_id )
+ inputs = {
+ "input1": { 'batch': True, 'values': [ dict( src="hdca", id=hdca_id ) ] },
+ }
+ self._check_simple_cat1_over_nested_collections( history_id, inputs )
+
+ def _check_simple_cat1_over_nested_collections( self, history_id, inputs ):
create = self._run_cat1( history_id, inputs=inputs, assert_ok=True )
outputs = create[ 'outputs' ]
jobs = create[ 'jobs' ]
@@ -257,7 +378,7 @@
self.assertEquals( outputs[ 0 ][ "id" ], first_object_forward_element[ "object" ][ "id" ] )
@skip_without_tool( "cat1" )
- def test_map_over_two_collections( self ):
+ def test_map_over_two_collections_legacy( self ):
history_id = self.dataset_populator.new_history()
hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
hdca2_id = self.__build_pair( history_id, [ "789", "0ab" ] )
@@ -265,7 +386,24 @@
"input1|__collection_multirun__": hdca1_id,
"queries_0|input2|__collection_multirun__": hdca2_id,
}
- outputs = self._cat1_outputs( history_id, inputs=inputs )
+ self._check_map_cat1_over_two_collections( history_id, inputs )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_two_collections( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
+ hdca2_id = self.__build_pair( history_id, [ "789", "0ab" ] )
+ inputs = {
+ "input1": { 'batch': True, 'values': [ {'src': 'hdca', 'id': hdca1_id } ] },
+ "queries_0|input2": { 'batch': True, 'values': [ { 'src': 'hdca', 'id': hdca2_id } ] },
+ }
+ self._check_map_cat1_over_two_collections( history_id, inputs )
+
+ def _check_map_cat1_over_two_collections( self, history_id, inputs ):
+ response = self._run_cat1( history_id, inputs )
+ self._assert_status_code_is( response, 200 )
+ response_object = response.json()
+ outputs = response_object[ 'outputs' ]
self.assertEquals( len( outputs ), 2 )
output1 = outputs[ 0 ]
output2 = outputs[ 1 ]
@@ -274,6 +412,49 @@
self.assertEquals( output1_content.strip(), "123\n789" )
self.assertEquals( output2_content.strip(), "456\n0ab" )
+ self.assertEquals( len( response_object[ 'jobs' ] ), 2 )
+ self.assertEquals( len( response_object[ 'implicit_collections' ] ), 1 )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_two_collections_unlinked( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
+ hdca2_id = self.__build_pair( history_id, [ "789", "0ab" ] )
+ inputs = {
+ "input1": { 'batch': True, 'linked': False, 'values': [ {'src': 'hdca', 'id': hdca1_id } ] },
+ "queries_0|input2": { 'batch': True, 'linked': False, 'values': [ { 'src': 'hdca', 'id': hdca2_id } ] },
+ }
+ response = self._run_cat1( history_id, inputs )
+ self._assert_status_code_is( response, 200 )
+ response_object = response.json()
+ outputs = response_object[ 'outputs' ]
+ self.assertEquals( len( outputs ), 4 )
+
+ self.assertEquals( len( response_object[ 'jobs' ] ), 4 )
+ # Implicit collections not created with unlinked inputs yet - this may
+ # be problematic.
+ self.assertEquals( len( response_object[ 'implicit_collections' ] ), 0 )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_collected_and_individual_datasets( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
+ new_dataset1 = self.dataset_populator.new_dataset( history_id, content='789' )
+ new_dataset2 = self.dataset_populator.new_dataset( history_id, content='0ab' )
+
+ inputs = {
+ "input1": { 'batch': True, 'values': [ {'src': 'hdca', 'id': hdca1_id } ] },
+ "queries_0|input2": { 'batch': True, 'values': [ dataset_to_param( new_dataset1 ), dataset_to_param( new_dataset2 ) ] },
+ }
+ response = self._run_cat1( history_id, inputs )
+ self._assert_status_code_is( response, 200 )
+ response_object = response.json()
+ outputs = response_object[ 'outputs' ]
+ self.assertEquals( len( outputs ), 2 )
+
+ self.assertEquals( len( response_object[ 'jobs' ] ), 2 )
+ self.assertEquals( len( response_object[ 'implicit_collections' ] ), 1 )
+
@skip_without_tool( "cat1" )
def test_cannot_map_over_incompatible_collections( self ):
history_id = self.dataset_populator.new_history()
@@ -289,7 +470,7 @@
assert run_response.status_code >= 400
@skip_without_tool( "multi_data_param" )
- def test_reduce_collections( self ):
+ def test_reduce_collections_legacy( self ):
history_id = self.dataset_populator.new_history()
hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
hdca2_id = self.dataset_collection_populator.create_list_in_history( history_id ).json()[ "id" ]
@@ -297,6 +478,20 @@
"f1": "__collection_reduce__|%s" % hdca1_id,
"f2": "__collection_reduce__|%s" % hdca2_id,
}
+ self._check_simple_reduce_job( history_id, inputs )
+
+ @skip_without_tool( "multi_data_param" )
+ def test_reduce_collections( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
+ hdca2_id = self.dataset_collection_populator.create_list_in_history( history_id ).json()[ "id" ]
+ inputs = {
+ "f1": { 'src': 'hdca', 'id': hdca1_id },
+ "f2": { 'src': 'hdca', 'id': hdca2_id },
+ }
+ self._check_simple_reduce_job( history_id, inputs )
+
+ def _check_simple_reduce_job( self, history_id, inputs ):
create = self._run( "multi_data_param", history_id, inputs, assert_ok=True )
outputs = create[ 'outputs' ]
jobs = create[ 'jobs' ]
@@ -310,12 +505,27 @@
assert len( output2_content.strip().split("\n") ) == 3, output2_content
@skip_without_tool( "collection_paired_test" )
- def test_subcollection_mapping( self ):
+ def test_subcollection_mapping_legacy( self ):
history_id = self.dataset_populator.new_history()
hdca_list_id = self.__build_nested_list( history_id )
inputs = {
"f1|__collection_multirun__": "%s|paired" % hdca_list_id
}
+ self._check_simple_subcollection_mapping( history_id, inputs )
+
+ @skip_without_tool( "collection_paired_test" )
+ def test_subcollection_mapping( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca_list_id = self.__build_nested_list( history_id )
+ inputs = {
+ "f1": {
+ 'batch': True,
+ 'values': [ { 'src': 'hdca', 'map_over_type': 'paired', 'id': hdca_list_id }],
+ }
+ }
+ self._check_simple_subcollection_mapping( history_id, inputs )
+
+ def _check_simple_subcollection_mapping( self, history_id, inputs ):
# Following wait not really needed - just getting so many database
# locked errors with sqlite.
self.dataset_populator.wait_for_history( history_id, assert_ok=True )
@@ -329,7 +539,7 @@
assert output2_content.strip() == "789\n0ab", output2_content
@skip_without_tool( "collection_mixed_param" )
- def test_combined_mapping_and_subcollection_mapping( self ):
+ def test_combined_mapping_and_subcollection_mapping_legacy( self ):
history_id = self.dataset_populator.new_history()
nested_list_id = self.__build_nested_list( history_id )
create_response = self.dataset_collection_populator.create_list_in_history( history_id, contents=["xxx", "yyy"] )
@@ -338,6 +548,27 @@
"f1|__collection_multirun__": "%s|paired" % nested_list_id,
"f2|__collection_multirun__": list_id,
}
+ self._check_combined_mapping_and_subcollection_mapping( history_id, inputs )
+
+ @skip_without_tool( "collection_mixed_param" )
+ def test_combined_mapping_and_subcollection_mapping( self ):
+ history_id = self.dataset_populator.new_history()
+ nested_list_id = self.__build_nested_list( history_id )
+ create_response = self.dataset_collection_populator.create_list_in_history( history_id, contents=["xxx", "yyy"] )
+ list_id = create_response.json()[ "id" ]
+ inputs = {
+ "f1": {
+ 'batch': True,
+ 'values': [ { 'src': 'hdca', 'map_over_type': 'paired', 'id': nested_list_id }],
+ },
+ "f2": {
+ 'batch': True,
+ 'values': [ { 'src': 'hdca', 'id': list_id }],
+ },
+ }
+ self._check_combined_mapping_and_subcollection_mapping( history_id, inputs )
+
+ def _check_combined_mapping_and_subcollection_mapping( self, history_id, inputs ):
self.dataset_populator.wait_for_history( history_id, assert_ok=True )
outputs = self._run_and_get_outputs( "collection_mixed_param", history_id, inputs )
assert len( outputs ), 2
diff -r 42f677bab2e4880b62758614fcb2c7dc27013788 -r df92b55d194a4d67a1b863c85044eb91c138c74b test/api/test_workflows.py
--- a/test/api/test_workflows.py
+++ b/test/api/test_workflows.py
@@ -361,13 +361,13 @@
hdca = self.dataset_collection_populator.create_pair_in_history( history_id, contents=["1 2 3\n4 5 6", "7 8 9\n10 11 10"] ).json()
hdca_id = hdca[ "id" ]
inputs1 = {
- "input|__collection_multirun__": hdca_id,
+ "input": { "batch": True, "values": [ { "src": "hdca", "id": hdca_id } ] },
"num_lines": 2
}
implicit_hdca1, job_id1 = self._run_tool_get_collection_and_job_id( history_id, "random_lines1", inputs1 )
inputs2 = {
- "f1": "__collection_reduce__|%s" % ( implicit_hdca1[ "id" ] ),
- "f2": "__collection_reduce__|%s" % ( implicit_hdca1[ "id" ] )
+ "f1": { "src": "hdca", "id": implicit_hdca1[ "id" ] },
+ "f2": { "src": "hdca", "id": implicit_hdca1[ "id" ] },
}
reduction_run_output = self.dataset_populator.run_tool(
tool_id="multi_data_param",
@@ -413,12 +413,12 @@
hdca = self.dataset_collection_populator.create_pair_in_history( history_id, contents=["1 2 3\n4 5 6", "7 8 9\n10 11 10"] ).json()
hdca_id = hdca[ "id" ]
inputs1 = {
- "input|__collection_multirun__": hdca_id,
+ "input": { "batch": True, "values": [ { "src": "hdca", "id": hdca_id } ] },
"num_lines": 2
}
implicit_hdca1, job_id1 = self._run_tool_get_collection_and_job_id( history_id, "random_lines1", inputs1 )
inputs2 = {
- "input|__collection_multirun__": implicit_hdca1[ "id" ],
+ "input": { "batch": True, "values": [ { "src": "hdca", "id": implicit_hdca1[ "id" ] } ] },
"num_lines": 1
}
_, job_id2 = self._run_tool_get_collection_and_job_id( history_id, "random_lines1", inputs2 )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
10 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/d5218767204d/
Changeset: d5218767204d
User: jmchilton
Date: 2014-09-16 15:57:48+00:00
Summary: Allow sending singleton lists of datasets to single dataset parameters via API tool submission.
Request from Sam.
Affected #: 2 files
diff -r 80d68ea889c01357b520ecefc56f86b0a44549fc -r d5218767204d12af6275b320409e507ae3dfe95b lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -1903,6 +1903,10 @@
raise ValueError( "The previously selected dataset has been previously deleted" )
if hasattr( v, "dataset" ) and v.dataset.state in [ galaxy.model.Dataset.states.ERROR, galaxy.model.Dataset.states.DISCARDED ]:
raise ValueError( "The previously selected dataset has entered an unusable state" )
+ if not self.multiple:
+ if len( values ) > 1:
+ raise ValueError( "More than one dataset supplied to single input dataset parameter.")
+ rval = values[ 0 ]
return rval
def to_string( self, value, app ):
diff -r 80d68ea889c01357b520ecefc56f86b0a44549fc -r d5218767204d12af6275b320409e507ae3dfe95b test/api/test_tools.py
--- a/test/api/test_tools.py
+++ b/test/api/test_tools.py
@@ -109,6 +109,20 @@
output1_content = self.dataset_populator.get_history_dataset_content( history_id, dataset=output1 )
self.assertEqual( output1_content.strip(), "Cat1Test" )
+ @skip_without_tool( "cat1" )
+ def test_run_cat1_listified_param( self ):
+ # Run simple non-upload tool with an input data parameter.
+ history_id = self.dataset_populator.new_history()
+ new_dataset = self.dataset_populator.new_dataset( history_id, content='Cat1Testlistified' )
+ inputs = dict(
+ input1=[dataset_to_param( new_dataset )],
+ )
+ outputs = self._cat1_outputs( history_id, inputs=inputs )
+ self.assertEquals( len( outputs ), 1 )
+ output1 = outputs[ 0 ]
+ output1_content = self.dataset_populator.get_history_dataset_content( history_id, dataset=output1 )
+ self.assertEqual( output1_content.strip(), "Cat1Testlistified" )
+
@skip_without_tool( "validation_default" )
def test_validation( self ):
history_id = self.dataset_populator.new_history()
https://bitbucket.org/galaxy/galaxy-central/commits/d9c75786e6b4/
Changeset: d9c75786e6b4
User: jmchilton
Date: 2014-09-16 15:57:48+00:00
Summary: Overhaul multi-run and collection multi-run tool API jobs.
Adding consistency allowing each parameter to be wrapped in a object describing the meta-properties of the submitting value - this was requested by Sam to make the new tool form easier to manage, it makes multi-running properties work for non-data parameters, and allows linked/unlinked specification of parameters.
Affected #: 2 files
diff -r d5218767204d12af6275b320409e507ae3dfe95b -r d9c75786e6b43f18f9c1eaded635d5d6b236e2a7 lib/galaxy/tools/parameters/meta.py
--- a/lib/galaxy/tools/parameters/meta.py
+++ b/lib/galaxy/tools/parameters/meta.py
@@ -14,6 +14,28 @@
execution).
"""
+ def classifiy_unmodified_parameter( input_key ):
+ value = incoming[ input_key ]
+ if isinstance( value, dict ) and 'values' in value:
+ # Explicit meta wrapper for inputs...
+ is_batch = value.get( 'batch', False )
+ is_linked = value.get( 'linked', True )
+ if is_batch and is_linked:
+ classification = permutations.input_classification.MATCHED
+ elif is_batch:
+ classification = permutations.input_classification.MULTIPLIED
+ else:
+ classification = permutations.input_classification.SINGLE
+ if __collection_multirun_parameter( value ):
+ collection_value = value[ 'values' ][ 0 ]
+ values = __expand_collection_parameter( trans, input_key, collection_value, collections_to_match )
+ else:
+ values = value[ 'values' ]
+ else:
+ classification = permutations.input_classification.SINGLE
+ values = value
+ return classification, values
+
def classifier( input_key ):
multirun_key = "%s|__multirun__" % input_key
if multirun_key in incoming:
@@ -25,7 +47,7 @@
multi_value = None
return permutations.input_classification.SINGLE, multi_value[ 0 ]
else:
- return permutations.input_classification.SINGLE, incoming[ input_key ]
+ return classifiy_unmodified_parameter( input_key )
from galaxy.dataset_collections import matching
collections_to_match = matching.CollectionsToMatch()
@@ -34,31 +56,10 @@
multirun_key = "%s|__collection_multirun__" % input_key
if multirun_key in incoming:
incoming_val = incoming[ multirun_key ]
- # If subcollectin multirun of data_collection param - value will
- # be "hdca_id|subcollection_type" else it will just be hdca_id
- if "|" in incoming_val:
- encoded_hdc_id, subcollection_type = incoming_val.split( "|", 1 )
- else:
- try:
- src = incoming_val[ "src" ]
- if src != "hdca":
- raise exceptions.ToolMetaParameterException( "Invalid dataset collection source type %s" % src )
- encoded_hdc_id = incoming_val[ "id" ]
- except TypeError:
- encoded_hdc_id = incoming_val
- subcollection_type = None
- hdc_id = trans.app.security.decode_id( encoded_hdc_id )
- hdc = trans.sa_session.query( model.HistoryDatasetCollectionAssociation ).get( hdc_id )
- collections_to_match.add( input_key, hdc, subcollection_type=subcollection_type )
- if subcollection_type is not None:
- from galaxy.dataset_collections import subcollections
- subcollection_elements = subcollections.split_dataset_collection_instance( hdc, subcollection_type )
- return permutations.input_classification.MATCHED, subcollection_elements
- else:
- hdas = hdc.collection.dataset_instances
- return permutations.input_classification.MATCHED, hdas
+ values = __expand_collection_parameter( trans, input_key, incoming_val, collections_to_match )
+ return permutations.input_classification.MATCHED, values
else:
- return permutations.input_classification.SINGLE, incoming[ input_key ]
+ return classifiy_unmodified_parameter( input_key )
# Stick an unexpanded version of multirun keys so they can be replaced,
# by expand_mult_inputs.
@@ -76,8 +77,19 @@
multirun_found = False
collection_multirun_found = False
for key, value in incoming.iteritems():
- multirun_found = try_replace_key( key, "|__multirun__" ) or multirun_found
- collection_multirun_found = try_replace_key( key, "|__collection_multirun__" ) or collection_multirun_found
+ if isinstance( value, dict ) and 'values' in value:
+ batch = value.get( 'batch', False )
+ if batch:
+ if __collection_multirun_parameter( value ):
+ collection_multirun_found = True
+ else:
+ multirun_found = True
+ else:
+ continue
+ else:
+ # Old-style batching (remove someday - didn't live in API long?)
+ multirun_found = try_replace_key( key, "|__multirun__" ) or multirun_found
+ collection_multirun_found = try_replace_key( key, "|__collection_multirun__" ) or collection_multirun_found
if sum( [ 1 if f else 0 for f in [ multirun_found, collection_multirun_found ] ] ) > 1:
# In theory doable, but to complicated for a first pass.
@@ -93,3 +105,38 @@
else:
collection_info = None
return expanded_incomings, collection_info
+
+
+def __expand_collection_parameter( trans, input_key, incoming_val, collections_to_match ):
+ # If subcollectin multirun of data_collection param - value will
+ # be "hdca_id|subcollection_type" else it will just be hdca_id
+ if "|" in incoming_val:
+ encoded_hdc_id, subcollection_type = incoming_val.split( "|", 1 )
+ else:
+ try:
+ src = incoming_val[ "src" ]
+ if src != "hdca":
+ raise exceptions.ToolMetaParameterException( "Invalid dataset collection source type %s" % src )
+ encoded_hdc_id = incoming_val[ "id" ]
+ except TypeError:
+ encoded_hdc_id = incoming_val
+ subcollection_type = None
+ hdc_id = trans.app.security.decode_id( encoded_hdc_id )
+ hdc = trans.sa_session.query( model.HistoryDatasetCollectionAssociation ).get( hdc_id )
+ collections_to_match.add( input_key, hdc, subcollection_type=subcollection_type )
+ if subcollection_type is not None:
+ from galaxy.dataset_collections import subcollections
+ subcollection_elements = subcollections.split_dataset_collection_instance( hdc, subcollection_type )
+ return subcollection_elements
+ else:
+ hdas = hdc.collection.dataset_instances
+ return hdas
+
+
+def __collection_multirun_parameter( value ):
+ batch_values = util.listify( value[ 'values' ] )
+ if len( batch_values ) == 1:
+ batch_over = batch_values[ 0 ]
+ if isinstance( batch_over, dict ) and ('src' in batch_over) and (batch_over[ 'src' ] == 'hdca'):
+ return True
+ return False
diff -r d5218767204d12af6275b320409e507ae3dfe95b -r d9c75786e6b43f18f9c1eaded635d5d6b236e2a7 test/api/test_tools.py
--- a/test/api/test_tools.py
+++ b/test/api/test_tools.py
@@ -123,6 +123,22 @@
output1_content = self.dataset_populator.get_history_dataset_content( history_id, dataset=output1 )
self.assertEqual( output1_content.strip(), "Cat1Testlistified" )
+ @skip_without_tool( "cat1" )
+ def test_run_cat1_single_meta_wrapper( self ):
+ # Wrap input in a no-op meta parameter wrapper like Sam is planning to
+ # use for all UI API submissions.
+ history_id = self.dataset_populator.new_history()
+ new_dataset = self.dataset_populator.new_dataset( history_id, content='123' )
+ inputs = dict(
+ input1={ 'batch': False, 'values': [ dataset_to_param( new_dataset ) ] },
+ )
+ outputs = self._cat1_outputs( history_id, inputs=inputs )
+ self.assertEquals( len( outputs ), 1 )
+ output1 = outputs[ 0 ]
+ output1_content = self.dataset_populator.get_history_dataset_content( history_id, dataset=output1 )
+ self.assertEqual( output1_content.strip(), "123" )
+
+
@skip_without_tool( "validation_default" )
def test_validation( self ):
history_id = self.dataset_populator.new_history()
@@ -149,16 +165,31 @@
self.assertEqual( output1_content.strip(), "Cat1Test\nCat2Test" )
@skip_without_tool( "cat1" )
+ def test_multirun_cat1_legacy( self ):
+ history_id, datasets = self._prepare_cat1_multirun()
+ inputs = {
+ "input1|__multirun__": datasets,
+ }
+ self._check_cat1_multirun( history_id, inputs )
+
+ @skip_without_tool( "cat1" )
def test_multirun_cat1( self ):
+ history_id, datasets = self._prepare_cat1_multirun()
+ inputs = {
+ "input1": {
+ 'batch': True,
+ 'values': datasets,
+ },
+ }
+ self._check_cat1_multirun( history_id, inputs )
+
+ def _prepare_cat1_multirun( self ):
history_id = self.dataset_populator.new_history()
new_dataset1 = self.dataset_populator.new_dataset( history_id, content='123' )
new_dataset2 = self.dataset_populator.new_dataset( history_id, content='456' )
- inputs = {
- "input1|__multirun__": [
- dataset_to_param( new_dataset1 ),
- dataset_to_param( new_dataset2 ),
- ],
- }
+ return history_id, [ dataset_to_param( new_dataset1 ), dataset_to_param( new_dataset2 ) ]
+
+ def _check_cat1_multirun( self, history_id, inputs ):
outputs = self._cat1_outputs( history_id, inputs=inputs )
self.assertEquals( len( outputs ), 2 )
output1 = outputs[ 0 ]
@@ -168,6 +199,20 @@
self.assertEquals( output1_content.strip(), "123" )
self.assertEquals( output2_content.strip(), "456" )
+ @skip_without_tool( "random_lines1" )
+ def test_multirun_non_data_parameter( self ):
+ history_id = self.dataset_populator.new_history()
+ new_dataset1 = self.dataset_populator.new_dataset( history_id, content='123\n456\n789' )
+ inputs = {
+ 'input': dataset_to_param( new_dataset1 ),
+ 'num_lines': { 'batch': True, 'values': [ 1, 2, 3 ] }
+ }
+ outputs = self._run_and_get_outputs( 'random_lines1', history_id, inputs )
+ # Assert we have three outputs with 1, 2, and 3 lines respectively.
+ assert len( outputs ) == 3
+ outputs_contents = [ self.dataset_populator.get_history_dataset_content( history_id, dataset=o ).strip() for o in outputs ]
+ assert sorted( map( lambda c: len( c.split( "\n" ) ), outputs_contents ) ) == [ 1, 2, 3 ]
+
@skip_without_tool( "cat1" )
def test_multirun_in_repeat( self ):
history_id = self.dataset_populator.new_history()
@@ -191,35 +236,60 @@
self.assertEquals( output2_content.strip(), "Common\n456" )
@skip_without_tool( "cat1" )
- def test_multirun_on_multiple_inputs( self ):
- history_id = self.dataset_populator.new_history()
- new_dataset1 = self.dataset_populator.new_dataset( history_id, content='123' )
- new_dataset2 = self.dataset_populator.new_dataset( history_id, content='456' )
- new_dataset3 = self.dataset_populator.new_dataset( history_id, content='789' )
- new_dataset4 = self.dataset_populator.new_dataset( history_id, content='0ab' )
+ def test_multirun_on_multiple_inputs_legacy( self ):
+ history_id, first_two, second_two = self._setup_two_multiruns()
inputs = {
- "input1|__multirun__": [
- dataset_to_param( new_dataset1 ),
- dataset_to_param( new_dataset2 ),
- ],
- 'queries_0|input2|__multirun__': [
- dataset_to_param( new_dataset3 ),
- dataset_to_param( new_dataset4 ),
- ],
+ "input1|__multirun__": first_two,
+ 'queries_0|input2|__multirun__': second_two,
}
outputs = self._cat1_outputs( history_id, inputs=inputs )
self.assertEquals( len( outputs ), 2 )
outputs_contents = [ self.dataset_populator.get_history_dataset_content( history_id, dataset=o ).strip() for o in outputs ]
assert "123\n789" in outputs_contents
assert "456\n0ab" in outputs_contents
- # TODO: Once cross production (instead of linking inputs) is an option
- # again redo test with these checks...
- # self.assertEquals( len( outputs ), 4 )
- # assert "123\n0ab" in outputs_contents
- # assert "456\n789" in outputs_contents
@skip_without_tool( "cat1" )
- def test_map_over_collection( self ):
+ def test_multirun_on_multiple_inputs( self ):
+ history_id, first_two, second_two = self._setup_two_multiruns()
+ inputs = {
+ "input1": { 'batch': True, 'values': first_two },
+ 'queries_0|input2': { 'batch': True, 'values': second_two },
+ }
+ outputs = self._cat1_outputs( history_id, inputs=inputs )
+ self.assertEquals( len( outputs ), 2 )
+ outputs_contents = [ self.dataset_populator.get_history_dataset_content( history_id, dataset=o ).strip() for o in outputs ]
+ assert "123\n789" in outputs_contents
+ assert "456\n0ab" in outputs_contents
+
+ @skip_without_tool( "cat1" )
+ def test_multirun_on_multiple_inputs_unlinked( self ):
+ history_id, first_two, second_two = self._setup_two_multiruns()
+ inputs = {
+ "input1": { 'batch': True, 'linked': False, 'values': first_two },
+ 'queries_0|input2': { 'batch': True, 'linked': False, 'values': second_two },
+ }
+ outputs = self._cat1_outputs( history_id, inputs=inputs )
+ outputs_contents = [ self.dataset_populator.get_history_dataset_content( history_id, dataset=o ).strip() for o in outputs ]
+ self.assertEquals( len( outputs ), 4 )
+ assert "123\n789" in outputs_contents
+ assert "456\n0ab" in outputs_contents
+ assert "123\n0ab" in outputs_contents
+ assert "456\n789" in outputs_contents
+
+ def _setup_two_multiruns( self ):
+ history_id = self.dataset_populator.new_history()
+ new_dataset1 = self.dataset_populator.new_dataset( history_id, content='123' )
+ new_dataset2 = self.dataset_populator.new_dataset( history_id, content='456' )
+ new_dataset3 = self.dataset_populator.new_dataset( history_id, content='789' )
+ new_dataset4 = self.dataset_populator.new_dataset( history_id, content='0ab' )
+ return (
+ history_id,
+ [ dataset_to_param( new_dataset1 ), dataset_to_param( new_dataset2 ) ],
+ [ dataset_to_param( new_dataset3 ), dataset_to_param( new_dataset4 ) ]
+ )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_collection_legacy( self ):
history_id = self.dataset_populator.new_history()
hdca_id = self.__build_pair( history_id, [ "123", "456" ] )
inputs = {
@@ -228,6 +298,18 @@
# first, next test method tests other.
"input1|__collection_multirun__": hdca_id,
}
+ self._run_and_check_simple_collection_mapping( history_id, inputs )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_collection( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca_id = self.__build_pair( history_id, [ "123", "456" ] )
+ inputs = {
+ "input1": { 'batch': True, 'values': [ { 'src': 'hdca', 'id': hdca_id } ] },
+ }
+ self._run_and_check_simple_collection_mapping( history_id, inputs )
+
+ def _run_and_check_simple_collection_mapping( self, history_id, inputs ):
create = self._run_cat1( history_id, inputs=inputs, assert_ok=True )
outputs = create[ 'outputs' ]
jobs = create[ 'jobs' ]
@@ -243,12 +325,24 @@
self.assertEquals( output2_content.strip(), "456" )
@skip_without_tool( "cat1" )
- def test_map_over_nested_collections( self ):
+ def test_map_over_nested_collections_legacy( self ):
history_id = self.dataset_populator.new_history()
hdca_id = self.__build_nested_list( history_id )
inputs = {
"input1|__collection_multirun__": dict( src="hdca", id=hdca_id ),
}
+ self._check_simple_cat1_over_nested_collections( history_id, inputs )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_nested_collections( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca_id = self.__build_nested_list( history_id )
+ inputs = {
+ "input1": { 'batch': True, 'values': [ dict( src="hdca", id=hdca_id ) ] },
+ }
+ self._check_simple_cat1_over_nested_collections( history_id, inputs )
+
+ def _check_simple_cat1_over_nested_collections( self, history_id, inputs ):
create = self._run_cat1( history_id, inputs=inputs, assert_ok=True )
outputs = create[ 'outputs' ]
jobs = create[ 'jobs' ]
@@ -271,7 +365,7 @@
self.assertEquals( outputs[ 0 ][ "id" ], first_object_forward_element[ "object" ][ "id" ] )
@skip_without_tool( "cat1" )
- def test_map_over_two_collections( self ):
+ def test_map_over_two_collections_legacy( self ):
history_id = self.dataset_populator.new_history()
hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
hdca2_id = self.__build_pair( history_id, [ "789", "0ab" ] )
@@ -279,7 +373,24 @@
"input1|__collection_multirun__": hdca1_id,
"queries_0|input2|__collection_multirun__": hdca2_id,
}
- outputs = self._cat1_outputs( history_id, inputs=inputs )
+ self._check_map_cat1_over_two_collections( history_id, inputs )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_two_collections( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
+ hdca2_id = self.__build_pair( history_id, [ "789", "0ab" ] )
+ inputs = {
+ "input1": { 'batch': True, 'values': [ {'src': 'hdca', 'id': hdca1_id } ] },
+ "queries_0|input2": { 'batch': True, 'values': [ { 'src': 'hdca', 'id': hdca2_id } ] },
+ }
+ self._check_map_cat1_over_two_collections( history_id, inputs )
+
+ def _check_map_cat1_over_two_collections( self, history_id, inputs ):
+ response = self._run_cat1( history_id, inputs )
+ self._assert_status_code_is( response, 200 )
+ response_object = response.json()
+ outputs = response_object[ 'outputs' ]
self.assertEquals( len( outputs ), 2 )
output1 = outputs[ 0 ]
output2 = outputs[ 1 ]
@@ -288,6 +399,29 @@
self.assertEquals( output1_content.strip(), "123\n789" )
self.assertEquals( output2_content.strip(), "456\n0ab" )
+ self.assertEquals( len( response_object[ 'jobs' ] ), 2 )
+ self.assertEquals( len( response_object[ 'implicit_collections' ] ), 1 )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_two_collections_unlinked( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
+ hdca2_id = self.__build_pair( history_id, [ "789", "0ab" ] )
+ inputs = {
+ "input1": { 'batch': True, 'linked': False, 'values': [ {'src': 'hdca', 'id': hdca1_id } ] },
+ "queries_0|input2": { 'batch': True, 'linked': False, 'values': [ { 'src': 'hdca', 'id': hdca2_id } ] },
+ }
+ response = self._run_cat1( history_id, inputs )
+ self._assert_status_code_is( response, 200 )
+ response_object = response.json()
+ outputs = response_object[ 'outputs' ]
+ self.assertEquals( len( outputs ), 4 )
+
+ self.assertEquals( len( response_object[ 'jobs' ] ), 4 )
+ # Implicit collections not created with unlinked inputs yet - this may
+ # be problematic.
+ self.assertEquals( len( response_object[ 'implicit_collections' ] ), 0 )
+
@skip_without_tool( "cat1" )
def test_cannot_map_over_incompatible_collections( self ):
history_id = self.dataset_populator.new_history()
https://bitbucket.org/galaxy/galaxy-central/commits/e5e67860cbde/
Changeset: e5e67860cbde
User: jmchilton
Date: 2014-09-16 15:57:48+00:00
Summary: Allow mixing batch multi-running of collections and individual datasets.
I wouldn't really recommend doing this per se - but probably don't want to prevent it either.
Affected #: 2 files
diff -r d9c75786e6b43f18f9c1eaded635d5d6b236e2a7 -r e5e67860cbde0edb272e1dbd225f4195e8b4785f lib/galaxy/tools/parameters/meta.py
--- a/lib/galaxy/tools/parameters/meta.py
+++ b/lib/galaxy/tools/parameters/meta.py
@@ -36,7 +36,11 @@
values = value
return classification, values
+ from galaxy.dataset_collections import matching
+ collections_to_match = matching.CollectionsToMatch()
+
def classifier( input_key ):
+ collection_multirun_key = "%s|__collection_multirun__" % input_key
multirun_key = "%s|__multirun__" % input_key
if multirun_key in incoming:
multi_value = util.listify( incoming[ multirun_key ] )
@@ -46,16 +50,8 @@
if len( multi_value ) == 0:
multi_value = None
return permutations.input_classification.SINGLE, multi_value[ 0 ]
- else:
- return classifiy_unmodified_parameter( input_key )
-
- from galaxy.dataset_collections import matching
- collections_to_match = matching.CollectionsToMatch()
-
- def collection_classifier( input_key ):
- multirun_key = "%s|__collection_multirun__" % input_key
- if multirun_key in incoming:
- incoming_val = incoming[ multirun_key ]
+ elif collection_multirun_key in incoming:
+ incoming_val = incoming[ collection_multirun_key ]
values = __expand_collection_parameter( trans, input_key, incoming_val, collections_to_match )
return permutations.input_classification.MATCHED, values
else:
@@ -87,24 +83,16 @@
else:
continue
else:
- # Old-style batching (remove someday - didn't live in API long?)
- multirun_found = try_replace_key( key, "|__multirun__" ) or multirun_found
- collection_multirun_found = try_replace_key( key, "|__collection_multirun__" ) or collection_multirun_found
+ # Old-style batching (remove someday? - pretty hacky and didn't live in API long)
+ try_replace_key( key, "|__multirun__" ) or multirun_found
+ try_replace_key( key, "|__collection_multirun__" ) or collection_multirun_found
- if sum( [ 1 if f else 0 for f in [ multirun_found, collection_multirun_found ] ] ) > 1:
- # In theory doable, but to complicated for a first pass.
- message = "Cannot specify parallel execution across both multiple datasets and dataset collections."
- raise exceptions.ToolMetaParameterException( message )
-
- if multirun_found:
- return permutations.expand_multi_inputs( incoming_template, classifier ), None
+ expanded_incomings = permutations.expand_multi_inputs( incoming_template, classifier )
+ if collections_to_match.has_collections():
+ collection_info = trans.app.dataset_collections_service.match_collections( collections_to_match )
else:
- expanded_incomings = permutations.expand_multi_inputs( incoming_template, collection_classifier )
- if collections_to_match.has_collections():
- collection_info = trans.app.dataset_collections_service.match_collections( collections_to_match )
- else:
- collection_info = None
- return expanded_incomings, collection_info
+ collection_info = None
+ return expanded_incomings, collection_info
def __expand_collection_parameter( trans, input_key, incoming_val, collections_to_match ):
diff -r d9c75786e6b43f18f9c1eaded635d5d6b236e2a7 -r e5e67860cbde0edb272e1dbd225f4195e8b4785f test/api/test_tools.py
--- a/test/api/test_tools.py
+++ b/test/api/test_tools.py
@@ -423,6 +423,26 @@
self.assertEquals( len( response_object[ 'implicit_collections' ] ), 0 )
@skip_without_tool( "cat1" )
+ def test_map_over_collected_and_individual_datasets( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
+ new_dataset1 = self.dataset_populator.new_dataset( history_id, content='789' )
+ new_dataset2 = self.dataset_populator.new_dataset( history_id, content='0ab' )
+
+ inputs = {
+ "input1": { 'batch': True, 'values': [ {'src': 'hdca', 'id': hdca1_id } ] },
+ "queries_0|input2": { 'batch': True, 'values': [ dataset_to_param( new_dataset1 ), dataset_to_param( new_dataset2 ) ] },
+ }
+ response = self._run_cat1( history_id, inputs )
+ self._assert_status_code_is( response, 200 )
+ response_object = response.json()
+ outputs = response_object[ 'outputs' ]
+ self.assertEquals( len( outputs ), 2 )
+
+ self.assertEquals( len( response_object[ 'jobs' ] ), 2 )
+ self.assertEquals( len( response_object[ 'implicit_collections' ] ), 1 )
+
+ @skip_without_tool( "cat1" )
def test_cannot_map_over_incompatible_collections( self ):
history_id = self.dataset_populator.new_history()
hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
https://bitbucket.org/galaxy/galaxy-central/commits/a7f6b4b1468c/
Changeset: a7f6b4b1468c
User: jmchilton
Date: 2014-09-16 15:57:48+00:00
Summary: Simplified dataset collection reductions via API.
Old tool form needed to encode every value as a string so I had done "__collection_reduction__|<hdca_id>" to distinguish that value from an "<hda_id>" - since hdca and hdas can have the same encoded ids. The new tool form API is going to use the API which allows for richer object representations - so {"src": "hda", "id": "<hda_id>"} versus {"src": "hdca", "id": "<hdca_id>"} should be enough to distinguish between passing an HDA and an HDCA to a multiple input data parameter.
Affected #: 2 files
diff -r e5e67860cbde0edb272e1dbd225f4195e8b4785f -r a7f6b4b1468cc52237981a7e7c1645f4720f8b1e lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -1887,6 +1887,11 @@
elif isinstance( value, dict ) and 'src' in value and 'id' in value:
if value['src'] == 'hda':
rval = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( trans.app.security.decode_id(value['id']) )
+ elif value['src'] == 'hdca':
+ decoded_id = trans.app.security.decode_id( value[ 'id' ] )
+ rval = trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( decoded_id )
+ else:
+ raise ValueError("Unknown input source %s passed to job submission API." % value['src'])
elif str( value ).startswith( "__collection_reduce__|" ):
encoded_id = str( value )[ len( "__collection_reduce__|" ): ]
decoded_id = trans.app.security.decode_id( encoded_id )
diff -r e5e67860cbde0edb272e1dbd225f4195e8b4785f -r a7f6b4b1468cc52237981a7e7c1645f4720f8b1e test/api/test_tools.py
--- a/test/api/test_tools.py
+++ b/test/api/test_tools.py
@@ -457,7 +457,7 @@
assert run_response.status_code >= 400
@skip_without_tool( "multi_data_param" )
- def test_reduce_collections( self ):
+ def test_reduce_collections_legacy( self ):
history_id = self.dataset_populator.new_history()
hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
hdca2_id = self.dataset_collection_populator.create_list_in_history( history_id ).json()[ "id" ]
@@ -465,6 +465,20 @@
"f1": "__collection_reduce__|%s" % hdca1_id,
"f2": "__collection_reduce__|%s" % hdca2_id,
}
+ self._check_simple_reduce_job( history_id, inputs )
+
+ @skip_without_tool( "multi_data_param" )
+ def test_reduce_collections( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
+ hdca2_id = self.dataset_collection_populator.create_list_in_history( history_id ).json()[ "id" ]
+ inputs = {
+ "f1": { 'src': 'hdca', 'id': hdca1_id },
+ "f2": { 'src': 'hdca', 'id': hdca2_id },
+ }
+ self._check_simple_reduce_job( history_id, inputs )
+
+ def _check_simple_reduce_job( self, history_id, inputs ):
create = self._run( "multi_data_param", history_id, inputs, assert_ok=True )
outputs = create[ 'outputs' ]
jobs = create[ 'jobs' ]
https://bitbucket.org/galaxy/galaxy-central/commits/6185cea44918/
Changeset: 6185cea44918
User: jmchilton
Date: 2014-09-16 15:57:48+00:00
Summary: Redo API for subcollection mapping steps in tools.
Like the reductions - was previously constrained by sequeezing these values into simple strings - now the tool form will target the API I think this expanded version is a little more straight-forward (though verbose). Adds consistency with rest of the tool form API changes.
Affected #: 2 files
diff -r a7f6b4b1468cc52237981a7e7c1645f4720f8b1e -r 6185cea4491868aea6207879e88118402f4344d3 lib/galaxy/tools/parameters/meta.py
--- a/lib/galaxy/tools/parameters/meta.py
+++ b/lib/galaxy/tools/parameters/meta.py
@@ -106,9 +106,10 @@
if src != "hdca":
raise exceptions.ToolMetaParameterException( "Invalid dataset collection source type %s" % src )
encoded_hdc_id = incoming_val[ "id" ]
+ subcollection_type = incoming_val.get( 'map_over_type', None )
except TypeError:
encoded_hdc_id = incoming_val
- subcollection_type = None
+ subcollection_type = None
hdc_id = trans.app.security.decode_id( encoded_hdc_id )
hdc = trans.sa_session.query( model.HistoryDatasetCollectionAssociation ).get( hdc_id )
collections_to_match.add( input_key, hdc, subcollection_type=subcollection_type )
diff -r a7f6b4b1468cc52237981a7e7c1645f4720f8b1e -r 6185cea4491868aea6207879e88118402f4344d3 test/api/test_tools.py
--- a/test/api/test_tools.py
+++ b/test/api/test_tools.py
@@ -492,12 +492,27 @@
assert len( output2_content.strip().split("\n") ) == 3, output2_content
@skip_without_tool( "collection_paired_test" )
- def test_subcollection_mapping( self ):
+ def test_subcollection_mapping_legacy( self ):
history_id = self.dataset_populator.new_history()
hdca_list_id = self.__build_nested_list( history_id )
inputs = {
"f1|__collection_multirun__": "%s|paired" % hdca_list_id
}
+ self._check_simple_subcollection_mapping( history_id, inputs )
+
+ @skip_without_tool( "collection_paired_test" )
+ def test_subcollection_mapping( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca_list_id = self.__build_nested_list( history_id )
+ inputs = {
+ "f1": {
+ 'batch': True,
+ 'values': [ { 'src': 'hdca', 'map_over_type': 'paired', 'id': hdca_list_id }],
+ }
+ }
+ self._check_simple_subcollection_mapping( history_id, inputs )
+
+ def _check_simple_subcollection_mapping( self, history_id, inputs ):
# Following wait not really needed - just getting so many database
# locked errors with sqlite.
self.dataset_populator.wait_for_history( history_id, assert_ok=True )
@@ -511,7 +526,7 @@
assert output2_content.strip() == "789\n0ab", output2_content
@skip_without_tool( "collection_mixed_param" )
- def test_combined_mapping_and_subcollection_mapping( self ):
+ def test_combined_mapping_and_subcollection_mapping_legacy( self ):
history_id = self.dataset_populator.new_history()
nested_list_id = self.__build_nested_list( history_id )
create_response = self.dataset_collection_populator.create_list_in_history( history_id, contents=["xxx", "yyy"] )
@@ -520,6 +535,27 @@
"f1|__collection_multirun__": "%s|paired" % nested_list_id,
"f2|__collection_multirun__": list_id,
}
+ self._check_combined_mapping_and_subcollection_mapping( history_id, inputs )
+
+ @skip_without_tool( "collection_mixed_param" )
+ def test_combined_mapping_and_subcollection_mapping( self ):
+ history_id = self.dataset_populator.new_history()
+ nested_list_id = self.__build_nested_list( history_id )
+ create_response = self.dataset_collection_populator.create_list_in_history( history_id, contents=["xxx", "yyy"] )
+ list_id = create_response.json()[ "id" ]
+ inputs = {
+ "f1": {
+ 'batch': True,
+ 'values': [ { 'src': 'hdca', 'map_over_type': 'paired', 'id': nested_list_id }],
+ },
+ "f2": {
+ 'batch': True,
+ 'values': [ { 'src': 'hdca', 'id': list_id }],
+ },
+ }
+ self._check_combined_mapping_and_subcollection_mapping( history_id, inputs )
+
+ def _check_combined_mapping_and_subcollection_mapping( self, history_id, inputs ):
self.dataset_populator.wait_for_history( history_id, assert_ok=True )
outputs = self._run_and_get_outputs( "collection_mixed_param", history_id, inputs )
assert len( outputs ), 2
https://bitbucket.org/galaxy/galaxy-central/commits/b8bc9b8b9806/
Changeset: b8bc9b8b9806
User: jmchilton
Date: 2014-09-16 15:57:48+00:00
Summary: Add tools test for data_collection input parameter specification.
Affected #: 1 file
diff -r 6185cea4491868aea6207879e88118402f4344d3 -r b8bc9b8b980689cbd32ad999675a31203574afb9 test/api/test_tools.py
--- a/test/api/test_tools.py
+++ b/test/api/test_tools.py
@@ -148,6 +148,20 @@
response = self._run( "validation_default", history_id, inputs )
self._assert_status_code_is( response, 400 )
+ @skip_without_tool( "collection_paired_test" )
+ def test_collection_parameter( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca_id = self.__build_pair( history_id, [ "123", "456" ] )
+ inputs = {
+ "f1": { "src": "hdca", "id": hdca_id },
+ }
+ output = self._run( "collection_paired_test", history_id, inputs, assert_ok=True )
+ assert len( output[ 'jobs' ] ) == 1
+ assert len( output[ 'implicit_collections' ] ) == 0
+ assert len( output[ 'outputs' ] ) == 1
+ contents = self.dataset_populator.get_history_dataset_content( history_id, hid=4 )
+ assert contents.strip() == "123\n456", contents
+
@skip_without_tool( "cat1" )
def test_run_cat1_with_two_inputs( self ):
# Run tool with an multiple data parameter and grouping (repeat)
https://bitbucket.org/galaxy/galaxy-central/commits/f5ea6456c64e/
Changeset: f5ea6456c64e
User: jmchilton
Date: 2014-09-16 15:57:48+00:00
Summary: PEP-8 fix.
Affected #: 1 file
diff -r b8bc9b8b980689cbd32ad999675a31203574afb9 -r f5ea6456c64ece76db8528eee5c88eb839cbaa34 test/api/test_tools.py
--- a/test/api/test_tools.py
+++ b/test/api/test_tools.py
@@ -138,7 +138,6 @@
output1_content = self.dataset_populator.get_history_dataset_content( history_id, dataset=output1 )
self.assertEqual( output1_content.strip(), "123" )
-
@skip_without_tool( "validation_default" )
def test_validation( self ):
history_id = self.dataset_populator.new_history()
https://bitbucket.org/galaxy/galaxy-central/commits/e66166960524/
Changeset: e66166960524
User: jmchilton
Date: 2014-09-16 15:57:48+00:00
Summary: Update map/reduce workflow tests for newer API constructs.
Old ones still work - but I wanted to verify the new changes didn't cause any unintended consequences with workflows.
Affected #: 1 file
diff -r f5ea6456c64ece76db8528eee5c88eb839cbaa34 -r e6616696052491bf563b690865f307f2de96d57c test/api/test_workflows.py
--- a/test/api/test_workflows.py
+++ b/test/api/test_workflows.py
@@ -350,13 +350,13 @@
hdca = self.dataset_collection_populator.create_pair_in_history( history_id, contents=["1 2 3\n4 5 6", "7 8 9\n10 11 10"] ).json()
hdca_id = hdca[ "id" ]
inputs1 = {
- "input|__collection_multirun__": hdca_id,
+ "input": { "batch": True, "values": [ { "src": "hdca", "id": hdca_id } ] },
"num_lines": 2
}
implicit_hdca1, job_id1 = self._run_tool_get_collection_and_job_id( history_id, "random_lines1", inputs1 )
inputs2 = {
- "f1": "__collection_reduce__|%s" % ( implicit_hdca1[ "id" ] ),
- "f2": "__collection_reduce__|%s" % ( implicit_hdca1[ "id" ] )
+ "f1": { "src": "hdca", "id": implicit_hdca1[ "id" ] },
+ "f2": { "src": "hdca", "id": implicit_hdca1[ "id" ] },
}
reduction_run_output = self.dataset_populator.run_tool(
tool_id="multi_data_param",
@@ -402,12 +402,12 @@
hdca = self.dataset_collection_populator.create_pair_in_history( history_id, contents=["1 2 3\n4 5 6", "7 8 9\n10 11 10"] ).json()
hdca_id = hdca[ "id" ]
inputs1 = {
- "input|__collection_multirun__": hdca_id,
+ "input": { "batch": True, "values": [ { "src": "hdca", "id": hdca_id } ] },
"num_lines": 2
}
implicit_hdca1, job_id1 = self._run_tool_get_collection_and_job_id( history_id, "random_lines1", inputs1 )
inputs2 = {
- "input|__collection_multirun__": implicit_hdca1[ "id" ],
+ "input": { "batch": True, "values": [ { "src": "hdca", "id": implicit_hdca1[ "id" ] } ] },
"num_lines": 1
}
_, job_id2 = self._run_tool_get_collection_and_job_id( history_id, "random_lines1", inputs2 )
https://bitbucket.org/galaxy/galaxy-central/commits/708d988d3e7b/
Changeset: 708d988d3e7b
User: jmchilton
Date: 2014-09-16 18:51:31+00:00
Summary: Fix spelling error in method name (thanks Nicola!).
Affected #: 1 file
diff -r e6616696052491bf563b690865f307f2de96d57c -r 708d988d3e7bf0ea9c91e0c2b2cbdc53037d3544 lib/galaxy/tools/parameters/meta.py
--- a/lib/galaxy/tools/parameters/meta.py
+++ b/lib/galaxy/tools/parameters/meta.py
@@ -14,7 +14,7 @@
execution).
"""
- def classifiy_unmodified_parameter( input_key ):
+ def classify_unmodified_parameter( input_key ):
value = incoming[ input_key ]
if isinstance( value, dict ) and 'values' in value:
# Explicit meta wrapper for inputs...
@@ -55,7 +55,7 @@
values = __expand_collection_parameter( trans, input_key, incoming_val, collections_to_match )
return permutations.input_classification.MATCHED, values
else:
- return classifiy_unmodified_parameter( input_key )
+ return classify_unmodified_parameter( input_key )
# Stick an unexpanded version of multirun keys so they can be replaced,
# by expand_mult_inputs.
https://bitbucket.org/galaxy/galaxy-central/commits/df92b55d194a/
Changeset: df92b55d194a
User: jmchilton
Date: 2014-09-22 14:24:39+00:00
Summary: Merged in jmchilton/galaxy-central-fork-1 (pull request #496)
More consistent tool API for map/reduce operations.
Affected #: 4 files
diff -r 42f677bab2e4880b62758614fcb2c7dc27013788 -r df92b55d194a4d67a1b863c85044eb91c138c74b lib/galaxy/tools/parameters/basic.py
--- a/lib/galaxy/tools/parameters/basic.py
+++ b/lib/galaxy/tools/parameters/basic.py
@@ -1887,6 +1887,11 @@
elif isinstance( value, dict ) and 'src' in value and 'id' in value:
if value['src'] == 'hda':
rval = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( trans.app.security.decode_id(value['id']) )
+ elif value['src'] == 'hdca':
+ decoded_id = trans.app.security.decode_id( value[ 'id' ] )
+ rval = trans.sa_session.query( trans.app.model.HistoryDatasetCollectionAssociation ).get( decoded_id )
+ else:
+ raise ValueError("Unknown input source %s passed to job submission API." % value['src'])
elif str( value ).startswith( "__collection_reduce__|" ):
encoded_id = str( value )[ len( "__collection_reduce__|" ): ]
decoded_id = trans.app.security.decode_id( encoded_id )
@@ -1903,6 +1908,10 @@
raise ValueError( "The previously selected dataset has been previously deleted" )
if hasattr( v, "dataset" ) and v.dataset.state in [ galaxy.model.Dataset.states.ERROR, galaxy.model.Dataset.states.DISCARDED ]:
raise ValueError( "The previously selected dataset has entered an unusable state" )
+ if not self.multiple:
+ if len( values ) > 1:
+ raise ValueError( "More than one dataset supplied to single input dataset parameter.")
+ rval = values[ 0 ]
return rval
def to_string( self, value, app ):
diff -r 42f677bab2e4880b62758614fcb2c7dc27013788 -r df92b55d194a4d67a1b863c85044eb91c138c74b lib/galaxy/tools/parameters/meta.py
--- a/lib/galaxy/tools/parameters/meta.py
+++ b/lib/galaxy/tools/parameters/meta.py
@@ -14,7 +14,33 @@
execution).
"""
+ def classify_unmodified_parameter( input_key ):
+ value = incoming[ input_key ]
+ if isinstance( value, dict ) and 'values' in value:
+ # Explicit meta wrapper for inputs...
+ is_batch = value.get( 'batch', False )
+ is_linked = value.get( 'linked', True )
+ if is_batch and is_linked:
+ classification = permutations.input_classification.MATCHED
+ elif is_batch:
+ classification = permutations.input_classification.MULTIPLIED
+ else:
+ classification = permutations.input_classification.SINGLE
+ if __collection_multirun_parameter( value ):
+ collection_value = value[ 'values' ][ 0 ]
+ values = __expand_collection_parameter( trans, input_key, collection_value, collections_to_match )
+ else:
+ values = value[ 'values' ]
+ else:
+ classification = permutations.input_classification.SINGLE
+ values = value
+ return classification, values
+
+ from galaxy.dataset_collections import matching
+ collections_to_match = matching.CollectionsToMatch()
+
def classifier( input_key ):
+ collection_multirun_key = "%s|__collection_multirun__" % input_key
multirun_key = "%s|__multirun__" % input_key
if multirun_key in incoming:
multi_value = util.listify( incoming[ multirun_key ] )
@@ -24,41 +50,12 @@
if len( multi_value ) == 0:
multi_value = None
return permutations.input_classification.SINGLE, multi_value[ 0 ]
+ elif collection_multirun_key in incoming:
+ incoming_val = incoming[ collection_multirun_key ]
+ values = __expand_collection_parameter( trans, input_key, incoming_val, collections_to_match )
+ return permutations.input_classification.MATCHED, values
else:
- return permutations.input_classification.SINGLE, incoming[ input_key ]
-
- from galaxy.dataset_collections import matching
- collections_to_match = matching.CollectionsToMatch()
-
- def collection_classifier( input_key ):
- multirun_key = "%s|__collection_multirun__" % input_key
- if multirun_key in incoming:
- incoming_val = incoming[ multirun_key ]
- # If subcollectin multirun of data_collection param - value will
- # be "hdca_id|subcollection_type" else it will just be hdca_id
- if "|" in incoming_val:
- encoded_hdc_id, subcollection_type = incoming_val.split( "|", 1 )
- else:
- try:
- src = incoming_val[ "src" ]
- if src != "hdca":
- raise exceptions.ToolMetaParameterException( "Invalid dataset collection source type %s" % src )
- encoded_hdc_id = incoming_val[ "id" ]
- except TypeError:
- encoded_hdc_id = incoming_val
- subcollection_type = None
- hdc_id = trans.app.security.decode_id( encoded_hdc_id )
- hdc = trans.sa_session.query( model.HistoryDatasetCollectionAssociation ).get( hdc_id )
- collections_to_match.add( input_key, hdc, subcollection_type=subcollection_type )
- if subcollection_type is not None:
- from galaxy.dataset_collections import subcollections
- subcollection_elements = subcollections.split_dataset_collection_instance( hdc, subcollection_type )
- return permutations.input_classification.MATCHED, subcollection_elements
- else:
- hdas = hdc.collection.dataset_instances
- return permutations.input_classification.MATCHED, hdas
- else:
- return permutations.input_classification.SINGLE, incoming[ input_key ]
+ return classify_unmodified_parameter( input_key )
# Stick an unexpanded version of multirun keys so they can be replaced,
# by expand_mult_inputs.
@@ -76,20 +73,59 @@
multirun_found = False
collection_multirun_found = False
for key, value in incoming.iteritems():
- multirun_found = try_replace_key( key, "|__multirun__" ) or multirun_found
- collection_multirun_found = try_replace_key( key, "|__collection_multirun__" ) or collection_multirun_found
+ if isinstance( value, dict ) and 'values' in value:
+ batch = value.get( 'batch', False )
+ if batch:
+ if __collection_multirun_parameter( value ):
+ collection_multirun_found = True
+ else:
+ multirun_found = True
+ else:
+ continue
+ else:
+ # Old-style batching (remove someday? - pretty hacky and didn't live in API long)
+ try_replace_key( key, "|__multirun__" ) or multirun_found
+ try_replace_key( key, "|__collection_multirun__" ) or collection_multirun_found
- if sum( [ 1 if f else 0 for f in [ multirun_found, collection_multirun_found ] ] ) > 1:
- # In theory doable, but to complicated for a first pass.
- message = "Cannot specify parallel execution across both multiple datasets and dataset collections."
- raise exceptions.ToolMetaParameterException( message )
+ expanded_incomings = permutations.expand_multi_inputs( incoming_template, classifier )
+ if collections_to_match.has_collections():
+ collection_info = trans.app.dataset_collections_service.match_collections( collections_to_match )
+ else:
+ collection_info = None
+ return expanded_incomings, collection_info
- if multirun_found:
- return permutations.expand_multi_inputs( incoming_template, classifier ), None
+
+def __expand_collection_parameter( trans, input_key, incoming_val, collections_to_match ):
+ # If subcollectin multirun of data_collection param - value will
+ # be "hdca_id|subcollection_type" else it will just be hdca_id
+ if "|" in incoming_val:
+ encoded_hdc_id, subcollection_type = incoming_val.split( "|", 1 )
else:
- expanded_incomings = permutations.expand_multi_inputs( incoming_template, collection_classifier )
- if collections_to_match.has_collections():
- collection_info = trans.app.dataset_collections_service.match_collections( collections_to_match )
- else:
- collection_info = None
- return expanded_incomings, collection_info
+ try:
+ src = incoming_val[ "src" ]
+ if src != "hdca":
+ raise exceptions.ToolMetaParameterException( "Invalid dataset collection source type %s" % src )
+ encoded_hdc_id = incoming_val[ "id" ]
+ subcollection_type = incoming_val.get( 'map_over_type', None )
+ except TypeError:
+ encoded_hdc_id = incoming_val
+ subcollection_type = None
+ hdc_id = trans.app.security.decode_id( encoded_hdc_id )
+ hdc = trans.sa_session.query( model.HistoryDatasetCollectionAssociation ).get( hdc_id )
+ collections_to_match.add( input_key, hdc, subcollection_type=subcollection_type )
+ if subcollection_type is not None:
+ from galaxy.dataset_collections import subcollections
+ subcollection_elements = subcollections.split_dataset_collection_instance( hdc, subcollection_type )
+ return subcollection_elements
+ else:
+ hdas = hdc.collection.dataset_instances
+ return hdas
+
+
+def __collection_multirun_parameter( value ):
+ batch_values = util.listify( value[ 'values' ] )
+ if len( batch_values ) == 1:
+ batch_over = batch_values[ 0 ]
+ if isinstance( batch_over, dict ) and ('src' in batch_over) and (batch_over[ 'src' ] == 'hdca'):
+ return True
+ return False
diff -r 42f677bab2e4880b62758614fcb2c7dc27013788 -r df92b55d194a4d67a1b863c85044eb91c138c74b test/api/test_tools.py
--- a/test/api/test_tools.py
+++ b/test/api/test_tools.py
@@ -109,6 +109,35 @@
output1_content = self.dataset_populator.get_history_dataset_content( history_id, dataset=output1 )
self.assertEqual( output1_content.strip(), "Cat1Test" )
+ @skip_without_tool( "cat1" )
+ def test_run_cat1_listified_param( self ):
+ # Run simple non-upload tool with an input data parameter.
+ history_id = self.dataset_populator.new_history()
+ new_dataset = self.dataset_populator.new_dataset( history_id, content='Cat1Testlistified' )
+ inputs = dict(
+ input1=[dataset_to_param( new_dataset )],
+ )
+ outputs = self._cat1_outputs( history_id, inputs=inputs )
+ self.assertEquals( len( outputs ), 1 )
+ output1 = outputs[ 0 ]
+ output1_content = self.dataset_populator.get_history_dataset_content( history_id, dataset=output1 )
+ self.assertEqual( output1_content.strip(), "Cat1Testlistified" )
+
+ @skip_without_tool( "cat1" )
+ def test_run_cat1_single_meta_wrapper( self ):
+ # Wrap input in a no-op meta parameter wrapper like Sam is planning to
+ # use for all UI API submissions.
+ history_id = self.dataset_populator.new_history()
+ new_dataset = self.dataset_populator.new_dataset( history_id, content='123' )
+ inputs = dict(
+ input1={ 'batch': False, 'values': [ dataset_to_param( new_dataset ) ] },
+ )
+ outputs = self._cat1_outputs( history_id, inputs=inputs )
+ self.assertEquals( len( outputs ), 1 )
+ output1 = outputs[ 0 ]
+ output1_content = self.dataset_populator.get_history_dataset_content( history_id, dataset=output1 )
+ self.assertEqual( output1_content.strip(), "123" )
+
@skip_without_tool( "validation_default" )
def test_validation( self ):
history_id = self.dataset_populator.new_history()
@@ -118,6 +147,20 @@
response = self._run( "validation_default", history_id, inputs )
self._assert_status_code_is( response, 400 )
+ @skip_without_tool( "collection_paired_test" )
+ def test_collection_parameter( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca_id = self.__build_pair( history_id, [ "123", "456" ] )
+ inputs = {
+ "f1": { "src": "hdca", "id": hdca_id },
+ }
+ output = self._run( "collection_paired_test", history_id, inputs, assert_ok=True )
+ assert len( output[ 'jobs' ] ) == 1
+ assert len( output[ 'implicit_collections' ] ) == 0
+ assert len( output[ 'outputs' ] ) == 1
+ contents = self.dataset_populator.get_history_dataset_content( history_id, hid=4 )
+ assert contents.strip() == "123\n456", contents
+
@skip_without_tool( "cat1" )
def test_run_cat1_with_two_inputs( self ):
# Run tool with an multiple data parameter and grouping (repeat)
@@ -135,16 +178,31 @@
self.assertEqual( output1_content.strip(), "Cat1Test\nCat2Test" )
@skip_without_tool( "cat1" )
+ def test_multirun_cat1_legacy( self ):
+ history_id, datasets = self._prepare_cat1_multirun()
+ inputs = {
+ "input1|__multirun__": datasets,
+ }
+ self._check_cat1_multirun( history_id, inputs )
+
+ @skip_without_tool( "cat1" )
def test_multirun_cat1( self ):
+ history_id, datasets = self._prepare_cat1_multirun()
+ inputs = {
+ "input1": {
+ 'batch': True,
+ 'values': datasets,
+ },
+ }
+ self._check_cat1_multirun( history_id, inputs )
+
+ def _prepare_cat1_multirun( self ):
history_id = self.dataset_populator.new_history()
new_dataset1 = self.dataset_populator.new_dataset( history_id, content='123' )
new_dataset2 = self.dataset_populator.new_dataset( history_id, content='456' )
- inputs = {
- "input1|__multirun__": [
- dataset_to_param( new_dataset1 ),
- dataset_to_param( new_dataset2 ),
- ],
- }
+ return history_id, [ dataset_to_param( new_dataset1 ), dataset_to_param( new_dataset2 ) ]
+
+ def _check_cat1_multirun( self, history_id, inputs ):
outputs = self._cat1_outputs( history_id, inputs=inputs )
self.assertEquals( len( outputs ), 2 )
output1 = outputs[ 0 ]
@@ -154,6 +212,20 @@
self.assertEquals( output1_content.strip(), "123" )
self.assertEquals( output2_content.strip(), "456" )
+ @skip_without_tool( "random_lines1" )
+ def test_multirun_non_data_parameter( self ):
+ history_id = self.dataset_populator.new_history()
+ new_dataset1 = self.dataset_populator.new_dataset( history_id, content='123\n456\n789' )
+ inputs = {
+ 'input': dataset_to_param( new_dataset1 ),
+ 'num_lines': { 'batch': True, 'values': [ 1, 2, 3 ] }
+ }
+ outputs = self._run_and_get_outputs( 'random_lines1', history_id, inputs )
+ # Assert we have three outputs with 1, 2, and 3 lines respectively.
+ assert len( outputs ) == 3
+ outputs_contents = [ self.dataset_populator.get_history_dataset_content( history_id, dataset=o ).strip() for o in outputs ]
+ assert sorted( map( lambda c: len( c.split( "\n" ) ), outputs_contents ) ) == [ 1, 2, 3 ]
+
@skip_without_tool( "cat1" )
def test_multirun_in_repeat( self ):
history_id = self.dataset_populator.new_history()
@@ -177,35 +249,60 @@
self.assertEquals( output2_content.strip(), "Common\n456" )
@skip_without_tool( "cat1" )
- def test_multirun_on_multiple_inputs( self ):
- history_id = self.dataset_populator.new_history()
- new_dataset1 = self.dataset_populator.new_dataset( history_id, content='123' )
- new_dataset2 = self.dataset_populator.new_dataset( history_id, content='456' )
- new_dataset3 = self.dataset_populator.new_dataset( history_id, content='789' )
- new_dataset4 = self.dataset_populator.new_dataset( history_id, content='0ab' )
+ def test_multirun_on_multiple_inputs_legacy( self ):
+ history_id, first_two, second_two = self._setup_two_multiruns()
inputs = {
- "input1|__multirun__": [
- dataset_to_param( new_dataset1 ),
- dataset_to_param( new_dataset2 ),
- ],
- 'queries_0|input2|__multirun__': [
- dataset_to_param( new_dataset3 ),
- dataset_to_param( new_dataset4 ),
- ],
+ "input1|__multirun__": first_two,
+ 'queries_0|input2|__multirun__': second_two,
}
outputs = self._cat1_outputs( history_id, inputs=inputs )
self.assertEquals( len( outputs ), 2 )
outputs_contents = [ self.dataset_populator.get_history_dataset_content( history_id, dataset=o ).strip() for o in outputs ]
assert "123\n789" in outputs_contents
assert "456\n0ab" in outputs_contents
- # TODO: Once cross production (instead of linking inputs) is an option
- # again redo test with these checks...
- # self.assertEquals( len( outputs ), 4 )
- # assert "123\n0ab" in outputs_contents
- # assert "456\n789" in outputs_contents
@skip_without_tool( "cat1" )
- def test_map_over_collection( self ):
+ def test_multirun_on_multiple_inputs( self ):
+ history_id, first_two, second_two = self._setup_two_multiruns()
+ inputs = {
+ "input1": { 'batch': True, 'values': first_two },
+ 'queries_0|input2': { 'batch': True, 'values': second_two },
+ }
+ outputs = self._cat1_outputs( history_id, inputs=inputs )
+ self.assertEquals( len( outputs ), 2 )
+ outputs_contents = [ self.dataset_populator.get_history_dataset_content( history_id, dataset=o ).strip() for o in outputs ]
+ assert "123\n789" in outputs_contents
+ assert "456\n0ab" in outputs_contents
+
+ @skip_without_tool( "cat1" )
+ def test_multirun_on_multiple_inputs_unlinked( self ):
+ history_id, first_two, second_two = self._setup_two_multiruns()
+ inputs = {
+ "input1": { 'batch': True, 'linked': False, 'values': first_two },
+ 'queries_0|input2': { 'batch': True, 'linked': False, 'values': second_two },
+ }
+ outputs = self._cat1_outputs( history_id, inputs=inputs )
+ outputs_contents = [ self.dataset_populator.get_history_dataset_content( history_id, dataset=o ).strip() for o in outputs ]
+ self.assertEquals( len( outputs ), 4 )
+ assert "123\n789" in outputs_contents
+ assert "456\n0ab" in outputs_contents
+ assert "123\n0ab" in outputs_contents
+ assert "456\n789" in outputs_contents
+
+ def _setup_two_multiruns( self ):
+ history_id = self.dataset_populator.new_history()
+ new_dataset1 = self.dataset_populator.new_dataset( history_id, content='123' )
+ new_dataset2 = self.dataset_populator.new_dataset( history_id, content='456' )
+ new_dataset3 = self.dataset_populator.new_dataset( history_id, content='789' )
+ new_dataset4 = self.dataset_populator.new_dataset( history_id, content='0ab' )
+ return (
+ history_id,
+ [ dataset_to_param( new_dataset1 ), dataset_to_param( new_dataset2 ) ],
+ [ dataset_to_param( new_dataset3 ), dataset_to_param( new_dataset4 ) ]
+ )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_collection_legacy( self ):
history_id = self.dataset_populator.new_history()
hdca_id = self.__build_pair( history_id, [ "123", "456" ] )
inputs = {
@@ -214,6 +311,18 @@
# first, next test method tests other.
"input1|__collection_multirun__": hdca_id,
}
+ self._run_and_check_simple_collection_mapping( history_id, inputs )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_collection( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca_id = self.__build_pair( history_id, [ "123", "456" ] )
+ inputs = {
+ "input1": { 'batch': True, 'values': [ { 'src': 'hdca', 'id': hdca_id } ] },
+ }
+ self._run_and_check_simple_collection_mapping( history_id, inputs )
+
+ def _run_and_check_simple_collection_mapping( self, history_id, inputs ):
create = self._run_cat1( history_id, inputs=inputs, assert_ok=True )
outputs = create[ 'outputs' ]
jobs = create[ 'jobs' ]
@@ -229,12 +338,24 @@
self.assertEquals( output2_content.strip(), "456" )
@skip_without_tool( "cat1" )
- def test_map_over_nested_collections( self ):
+ def test_map_over_nested_collections_legacy( self ):
history_id = self.dataset_populator.new_history()
hdca_id = self.__build_nested_list( history_id )
inputs = {
"input1|__collection_multirun__": dict( src="hdca", id=hdca_id ),
}
+ self._check_simple_cat1_over_nested_collections( history_id, inputs )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_nested_collections( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca_id = self.__build_nested_list( history_id )
+ inputs = {
+ "input1": { 'batch': True, 'values': [ dict( src="hdca", id=hdca_id ) ] },
+ }
+ self._check_simple_cat1_over_nested_collections( history_id, inputs )
+
+ def _check_simple_cat1_over_nested_collections( self, history_id, inputs ):
create = self._run_cat1( history_id, inputs=inputs, assert_ok=True )
outputs = create[ 'outputs' ]
jobs = create[ 'jobs' ]
@@ -257,7 +378,7 @@
self.assertEquals( outputs[ 0 ][ "id" ], first_object_forward_element[ "object" ][ "id" ] )
@skip_without_tool( "cat1" )
- def test_map_over_two_collections( self ):
+ def test_map_over_two_collections_legacy( self ):
history_id = self.dataset_populator.new_history()
hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
hdca2_id = self.__build_pair( history_id, [ "789", "0ab" ] )
@@ -265,7 +386,24 @@
"input1|__collection_multirun__": hdca1_id,
"queries_0|input2|__collection_multirun__": hdca2_id,
}
- outputs = self._cat1_outputs( history_id, inputs=inputs )
+ self._check_map_cat1_over_two_collections( history_id, inputs )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_two_collections( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
+ hdca2_id = self.__build_pair( history_id, [ "789", "0ab" ] )
+ inputs = {
+ "input1": { 'batch': True, 'values': [ {'src': 'hdca', 'id': hdca1_id } ] },
+ "queries_0|input2": { 'batch': True, 'values': [ { 'src': 'hdca', 'id': hdca2_id } ] },
+ }
+ self._check_map_cat1_over_two_collections( history_id, inputs )
+
+ def _check_map_cat1_over_two_collections( self, history_id, inputs ):
+ response = self._run_cat1( history_id, inputs )
+ self._assert_status_code_is( response, 200 )
+ response_object = response.json()
+ outputs = response_object[ 'outputs' ]
self.assertEquals( len( outputs ), 2 )
output1 = outputs[ 0 ]
output2 = outputs[ 1 ]
@@ -274,6 +412,49 @@
self.assertEquals( output1_content.strip(), "123\n789" )
self.assertEquals( output2_content.strip(), "456\n0ab" )
+ self.assertEquals( len( response_object[ 'jobs' ] ), 2 )
+ self.assertEquals( len( response_object[ 'implicit_collections' ] ), 1 )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_two_collections_unlinked( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
+ hdca2_id = self.__build_pair( history_id, [ "789", "0ab" ] )
+ inputs = {
+ "input1": { 'batch': True, 'linked': False, 'values': [ {'src': 'hdca', 'id': hdca1_id } ] },
+ "queries_0|input2": { 'batch': True, 'linked': False, 'values': [ { 'src': 'hdca', 'id': hdca2_id } ] },
+ }
+ response = self._run_cat1( history_id, inputs )
+ self._assert_status_code_is( response, 200 )
+ response_object = response.json()
+ outputs = response_object[ 'outputs' ]
+ self.assertEquals( len( outputs ), 4 )
+
+ self.assertEquals( len( response_object[ 'jobs' ] ), 4 )
+ # Implicit collections not created with unlinked inputs yet - this may
+ # be problematic.
+ self.assertEquals( len( response_object[ 'implicit_collections' ] ), 0 )
+
+ @skip_without_tool( "cat1" )
+ def test_map_over_collected_and_individual_datasets( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
+ new_dataset1 = self.dataset_populator.new_dataset( history_id, content='789' )
+ new_dataset2 = self.dataset_populator.new_dataset( history_id, content='0ab' )
+
+ inputs = {
+ "input1": { 'batch': True, 'values': [ {'src': 'hdca', 'id': hdca1_id } ] },
+ "queries_0|input2": { 'batch': True, 'values': [ dataset_to_param( new_dataset1 ), dataset_to_param( new_dataset2 ) ] },
+ }
+ response = self._run_cat1( history_id, inputs )
+ self._assert_status_code_is( response, 200 )
+ response_object = response.json()
+ outputs = response_object[ 'outputs' ]
+ self.assertEquals( len( outputs ), 2 )
+
+ self.assertEquals( len( response_object[ 'jobs' ] ), 2 )
+ self.assertEquals( len( response_object[ 'implicit_collections' ] ), 1 )
+
@skip_without_tool( "cat1" )
def test_cannot_map_over_incompatible_collections( self ):
history_id = self.dataset_populator.new_history()
@@ -289,7 +470,7 @@
assert run_response.status_code >= 400
@skip_without_tool( "multi_data_param" )
- def test_reduce_collections( self ):
+ def test_reduce_collections_legacy( self ):
history_id = self.dataset_populator.new_history()
hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
hdca2_id = self.dataset_collection_populator.create_list_in_history( history_id ).json()[ "id" ]
@@ -297,6 +478,20 @@
"f1": "__collection_reduce__|%s" % hdca1_id,
"f2": "__collection_reduce__|%s" % hdca2_id,
}
+ self._check_simple_reduce_job( history_id, inputs )
+
+ @skip_without_tool( "multi_data_param" )
+ def test_reduce_collections( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca1_id = self.__build_pair( history_id, [ "123", "456" ] )
+ hdca2_id = self.dataset_collection_populator.create_list_in_history( history_id ).json()[ "id" ]
+ inputs = {
+ "f1": { 'src': 'hdca', 'id': hdca1_id },
+ "f2": { 'src': 'hdca', 'id': hdca2_id },
+ }
+ self._check_simple_reduce_job( history_id, inputs )
+
+ def _check_simple_reduce_job( self, history_id, inputs ):
create = self._run( "multi_data_param", history_id, inputs, assert_ok=True )
outputs = create[ 'outputs' ]
jobs = create[ 'jobs' ]
@@ -310,12 +505,27 @@
assert len( output2_content.strip().split("\n") ) == 3, output2_content
@skip_without_tool( "collection_paired_test" )
- def test_subcollection_mapping( self ):
+ def test_subcollection_mapping_legacy( self ):
history_id = self.dataset_populator.new_history()
hdca_list_id = self.__build_nested_list( history_id )
inputs = {
"f1|__collection_multirun__": "%s|paired" % hdca_list_id
}
+ self._check_simple_subcollection_mapping( history_id, inputs )
+
+ @skip_without_tool( "collection_paired_test" )
+ def test_subcollection_mapping( self ):
+ history_id = self.dataset_populator.new_history()
+ hdca_list_id = self.__build_nested_list( history_id )
+ inputs = {
+ "f1": {
+ 'batch': True,
+ 'values': [ { 'src': 'hdca', 'map_over_type': 'paired', 'id': hdca_list_id }],
+ }
+ }
+ self._check_simple_subcollection_mapping( history_id, inputs )
+
+ def _check_simple_subcollection_mapping( self, history_id, inputs ):
# Following wait not really needed - just getting so many database
# locked errors with sqlite.
self.dataset_populator.wait_for_history( history_id, assert_ok=True )
@@ -329,7 +539,7 @@
assert output2_content.strip() == "789\n0ab", output2_content
@skip_without_tool( "collection_mixed_param" )
- def test_combined_mapping_and_subcollection_mapping( self ):
+ def test_combined_mapping_and_subcollection_mapping_legacy( self ):
history_id = self.dataset_populator.new_history()
nested_list_id = self.__build_nested_list( history_id )
create_response = self.dataset_collection_populator.create_list_in_history( history_id, contents=["xxx", "yyy"] )
@@ -338,6 +548,27 @@
"f1|__collection_multirun__": "%s|paired" % nested_list_id,
"f2|__collection_multirun__": list_id,
}
+ self._check_combined_mapping_and_subcollection_mapping( history_id, inputs )
+
+ @skip_without_tool( "collection_mixed_param" )
+ def test_combined_mapping_and_subcollection_mapping( self ):
+ history_id = self.dataset_populator.new_history()
+ nested_list_id = self.__build_nested_list( history_id )
+ create_response = self.dataset_collection_populator.create_list_in_history( history_id, contents=["xxx", "yyy"] )
+ list_id = create_response.json()[ "id" ]
+ inputs = {
+ "f1": {
+ 'batch': True,
+ 'values': [ { 'src': 'hdca', 'map_over_type': 'paired', 'id': nested_list_id }],
+ },
+ "f2": {
+ 'batch': True,
+ 'values': [ { 'src': 'hdca', 'id': list_id }],
+ },
+ }
+ self._check_combined_mapping_and_subcollection_mapping( history_id, inputs )
+
+ def _check_combined_mapping_and_subcollection_mapping( self, history_id, inputs ):
self.dataset_populator.wait_for_history( history_id, assert_ok=True )
outputs = self._run_and_get_outputs( "collection_mixed_param", history_id, inputs )
assert len( outputs ), 2
diff -r 42f677bab2e4880b62758614fcb2c7dc27013788 -r df92b55d194a4d67a1b863c85044eb91c138c74b test/api/test_workflows.py
--- a/test/api/test_workflows.py
+++ b/test/api/test_workflows.py
@@ -361,13 +361,13 @@
hdca = self.dataset_collection_populator.create_pair_in_history( history_id, contents=["1 2 3\n4 5 6", "7 8 9\n10 11 10"] ).json()
hdca_id = hdca[ "id" ]
inputs1 = {
- "input|__collection_multirun__": hdca_id,
+ "input": { "batch": True, "values": [ { "src": "hdca", "id": hdca_id } ] },
"num_lines": 2
}
implicit_hdca1, job_id1 = self._run_tool_get_collection_and_job_id( history_id, "random_lines1", inputs1 )
inputs2 = {
- "f1": "__collection_reduce__|%s" % ( implicit_hdca1[ "id" ] ),
- "f2": "__collection_reduce__|%s" % ( implicit_hdca1[ "id" ] )
+ "f1": { "src": "hdca", "id": implicit_hdca1[ "id" ] },
+ "f2": { "src": "hdca", "id": implicit_hdca1[ "id" ] },
}
reduction_run_output = self.dataset_populator.run_tool(
tool_id="multi_data_param",
@@ -413,12 +413,12 @@
hdca = self.dataset_collection_populator.create_pair_in_history( history_id, contents=["1 2 3\n4 5 6", "7 8 9\n10 11 10"] ).json()
hdca_id = hdca[ "id" ]
inputs1 = {
- "input|__collection_multirun__": hdca_id,
+ "input": { "batch": True, "values": [ { "src": "hdca", "id": hdca_id } ] },
"num_lines": 2
}
implicit_hdca1, job_id1 = self._run_tool_get_collection_and_job_id( history_id, "random_lines1", inputs1 )
inputs2 = {
- "input|__collection_multirun__": implicit_hdca1[ "id" ],
+ "input": { "batch": True, "values": [ { "src": "hdca", "id": implicit_hdca1[ "id" ] } ] },
"num_lines": 1
}
_, job_id2 = self._run_tool_get_collection_and_job_id( history_id, "random_lines1", inputs2 )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0